Skip to content

credential-handler/chapi-demo-stack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

chapi-demo-stack

One-command, phone-reachable CHAPI demo environment.

docker compose up starts the three CHAPI demo sites (chapi-demo-wallet, chapi-demo-issuer, chapi-demo-verifier) in containers, exposes each through a Cloudflare quick tunnel (*.trycloudflare.com), and auto-points all of them at a credential mediator (authn.io) running on your host — also tunneled, so real phones can complete the full register → issue/store → present flow against your local mediator build.

Why

Testing local authn.io changes on a real phone normally requires: /etc/hosts entries, self-signed-certificate acceptance on every origin, hand-editing each demo's config.js, and a tunnel that doesn't break CHAPI. The manual version of this takes an afternoon; this stack makes it docker compose up.

Quick tunnels are used deliberately instead of ngrok's free tier: ngrok's browser interstitial requires a cookie that iOS refuses to send in cross-site iframe contexts, which silently breaks the hidden CHAPI mediator/wallet iframes on iPhones. Cloudflare quick tunnels serve no interstitial.

Prerequisites

  • Docker (with Compose v2).
  • A credential mediator running on the host at https://localhost:33443 — e.g. an authn.io checkout running node authn.localhost.js. The mediator stays on the host (not containerized) so webpack watch / live development keeps working; self-signed certificates are fine (the tunnel skips TLS verification for the host hop).

Usage

docker compose up -d && ./urls.sh

urls.sh blocks until every tunnel is up, then prints the three phone-ready URLs as the last thing in your terminal. (Plain docker compose up works too, but the attached logs scroll the URL block away — re-print it any time with ./urls.sh.) Then on the phone, in order:

  1. wallet — tap LOGIN to register the wallet with the mediator.
  2. issuer — Issue and Store a credential.
  3. verifier — Present the credential.

Re-print the URLs of a running stack any time:

./urls.sh

Stopping

The stack runs in the background and stays publicly reachable until stopped — don't forget it:

docker compose down

(urls.sh prints this reminder too.)

Full reset

All state is ephemeral (repos are re-cloned and tunnel URLs re-minted on every up), so down + up is already a fresh start. To also re-pull the images, exactly like a first run on a new machine:

docker compose down --rmi all --volumes --remove-orphans
docker compose up -d && ./urls.sh

How it works

phone ──► *.trycloudflare.com ──► cloudflared sidecar ──► demo container
                                          │
host mediator (authn.io :33443) ◄── mediator-tunnel (no-tls-verify)
  • The cloudflared image is distroless (no shell), so each tunnel runs the stock binary and exposes its assigned quick-tunnel hostname via cloudflared's metrics endpoint (http://<tunnel>:2000/quicktunnel).
  • Each demo container polls the mediator tunnel's endpoint for that URL, clones its repo at start, generates config.js with MEDIATOR pointed at it (the config.js override hook exists in every chapi-demo repo for exactly this purpose), and serves over plain HTTP with caching disabled (http-server -c-1). TLS terminates at the Cloudflare edge, so browsers still get a secure context.
  • Each demo gets its own quick tunnel; the urls one-shot service collects and prints all of them.

Polyfill pin

The demos float on credential-handler-polyfill@3, which currently resolves to a version that throws on iOS WebKit (every iOS browser) — see credential-handler-polyfill#51. The entrypoint pins 3.0.2 (controlled by POLYFILL_PIN in docker-compose.yml); drop the pin once #51 is fixed upstream.

Caveats

  • Ephemeral URLs. Quick-tunnel hostnames change on every compose up; the phone wallet must re-register each session. For stable hostnames, swap quick tunnels for named Cloudflare tunnels (free account + domain required) — the compose layout supports swapping the tunnel entrypoint without touching the demo services.
  • Best-effort transport. trycloudflare.com has no SLA and may be rate-limited. Fine for development/testing; do not demo to an audience on it.
  • Public exposure. While the stack runs, the demos and your local mediator are reachable from the public internet at unguessable URLs. They serve only static demo content and your mediator UI, but shut the stack down when not in use.
  • The demos are cloned at container start (main branch). To test local demo checkouts instead, bind-mount one over /app in docker-compose.yml.
  • The mediator is intentionally not containerized. The primary use case is testing local authn.io changes, so the mediator runs on the host where webpack watch keeps your edits live; containerizing it would freeze a snapshot instead. A fully self-contained mode (an optional mediator service building authn.io from GitHub, or bind-mounting a local checkout) is a possible future enhancement.

About

One-command, phone-reachable CHAPI demo environment: dockerized demo sites + Cloudflare quick tunnels pointed at a local credential mediator

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages