Demo
Run Plumbus locally and observe the difference between a classic bearer model and a sender-constrained boundary.
The same application is exposed on two ports:
- :8080 — Via Plumbus (sender-constrained boundary)
- :9090 — Direct service (JWT in cookie, no binding)
Same authentication endpoint.
Same API routes.
Only the service boundary changes.
Requirements
- Docker (Docker Desktop or Docker Engine)
or any compatible OCI runtime such as Podman - A modern browser with Service Worker support
No external services are required.
No database.
No configuration.
Run
docker run -p 8080:8080 -p 9090:9090 ghcr.io/mighty-nerd/plumbus-demo:latest
Open in browser:
Default credentials:
alice / alice
bob / bob
What to Try
1. Authenticate on :9090 (Direct Service)
- Click Authenticate
- Call the API
Result: 200 OK
Now switch to :8080 and call the same API.
Result: 401 Unauthorized
Authentication material issued directly is rejected by the Plumbus boundary.
2. Authenticate on :8080 (Via Plumbus)
- Click Authenticate
- Call the API
Result: 200 OK
Now switch to :9090 and call the same API.
Result: 200 OK
Plumbus does not modify authentication material.
It enforces sender-constraint externally.
What This Demonstrates
- Direct service → bearer semantics (portable)
- Plumbus boundary → sender-constrained usage
- Application code remains unchanged
- Authentication mechanism remains unchanged
Only the right to use authentication material is constrained.
Advanced
The live demo page includes:
- Raw curl examples
- A standalone Python client that generates DPoP proofs
- A multi-instance cluster setup demonstrating cross-instance validation
All request behavior is observable.
No internal logic is hidden.
Optional Challenge
Expose only the boundary:
docker run -p 8080:8080 ghcr.io/mighty-nerd/plumbus-demo:latest
Obtain 200 OK from /api/echo on :8080
from a different client context
without possessing the original client private key
within the freshness window.
Same application.
Same authentication.
Different boundary.