Skip to content

Looking Glass

Looking Glass is the primary interface for executing protocol flows. It shows every step of a flow as it happens, with full payload visibility via WebSocket event streaming.

  1. Select a protocol and flow from the sidebar.
  2. Configure the flow (varies by protocol – client ID, subject, callback URL, credential format, or HAIP).
  3. Execute the flow.
  4. Watch each step render in real time as the backend emits events.
  5. Click any step to inspect full request/response payloads, tokens, and validation results.

Each flow execution produces a timeline of events:

Event Type What It Shows
flow.step Major protocol steps (authorization request sent, token exchanged, assertion delivered)
token.issued Token creation with decoded claims
token.validated Token validation results with pass/fail details
request.sent Outbound HTTP requests with headers and body
response.received HTTP responses with status, headers, and body
http.exchange Complete request/response pairs
security.warning Validation failures, missing parameters, spec violations
security.info Successful security checks and confirmations
crypto.operation Key generation, signing, hash verification

Every event includes an annotation with RFC references (for example “RFC 6749 Section 4.1”) and security context explaining what the step does and why.

OID4VCI and OID4VP runs use the hosted Wallet Harness. Looking Glass creates issuer and verifier traffic; the wallet performs the holder-side hops (offer import, proof, presentation). Open the wallet directly to import offers, inspect stored credentials, and complete QR or deeplink presentations.

Looking Glass supports shareable deep-links in the format /looking-glass?protocol=X&flow=Y. These links are generated by the palette search (cmd+K), the Share button in the flow toolbar, and flow detail pages (“Try in Looking Glass”). Optional selector parameters reproduce the same independent choices the UI exposes:

Parameter Flows Values
client_auth Client Credentials client_secret_basic, private_key_jwt
token_mode Client Credentials bearer, dpop
credential_format OID4VCI, OID4VP mso_mdoc, dc+sd-jwt
haip OID4VCI, OID4VP 1 (omit for the general profile)

On OID4VCI, haip=1 selects key-attested issuance. On OID4VP, haip=1 selects that issuance configuration plus HAIP presentation (x509_hash, DCQL, encrypted direct_post.jwt).

URL query parameters follow a consume-and-clear lifecycle:

  • When a deep-link is opened, the protocol, flow, and any recognized selector params are read and applied, then removed from the address bar.
  • Changing protocol or flow via the UI dropdowns updates the URL to reflect the new selection.
  • Resetting or clearing the flow strips query params entirely.
  • Navigating away from Looking Glass always results in a clean URL on return.

When a flow is selected, three icon buttons appear next to the protocol/flow dropdowns:

Control What It Does
Reset Resets the current flow execution to its initial state and clears the URL
Share Copies a shareable deep-link for the current protocol and flow to the clipboard
Clear Clears all selections (protocol, flow, tokens, configuration), resets every input field, and strips query params from the URL

The flow header also provides a low-emphasis reference breadcrumb: Protocol Reference › protocol › flow. Each reference opens in a new tab so the live execution remains intact. On narrow screens, the breadcrumb collapses to the matching flow guide.

Looking Glass blocks or warns before combinations that the live protocol will reject, and it explains failures without replacing the real error / error_description text.

  • HAIP selector (general / HAIP) is independent of credential format (mso_mdoc / dc+sd-jwt), matching the Client Credentials private_key_jwt / DPoP selectors. On OID4VCI, HAIP issues MobileDrivingLicenceMsoMdocHAIP or UniversityDegreeCredentialSDJWTHAIP with client and key attestation (HAIP 1.0 Sections 4.4.1 and 4.5.1). The hosted wallet is configured for that path, so Execute is expected to succeed when WALLET_KEY_ATTESTATION_* meets any key_attestations_required levels (mdoc HAIP requires iso_18045_moderate). A self-hosted wallet without WALLET_CLIENT_ATTESTATION_ATTESTER_JWK_JSON and WALLET_CLIENT_ATTESTATION_KEY_ATTESTATION_JWK_JSON returns HTTP 400 on import. On OID4VP, HAIP issues those same configurations, then presents with x509_hash, DCQL, and encrypted direct_post.jwt (HAIP 1.0 Section 5). Missing attestation or key_storage that does not satisfy key_attestations_required is HTTP 400, not a fallback to general. Verifier trust profiles other than x509_hash, custom DCQL, scope alias, request_uri POST, and the redirect_uri / client_id override live under Advanced. When verifier trust is redirect_uri, that field is the redirect URI: client_id MUST equal response_uri (OpenID4VP 1.0 Section 5.9.3).
  • Issuer-initiated offer delivery is optional and lives under Advanced. When blank, Execute produces an openid-credential-offer:// QR. Paste an HTTPS credential_offer_endpoint only to have the issuer deliver the live offer (OID4VCI 1.0 §4.1.2).
  • Invalid DCQL or an empty scope alias disables Execute until the request contract is valid.
  • OID4VP format mismatch blocks wallet submit when the selected credential format is not in the DCQL query (paste a matching credential_jwt to override with a warning). Changing format restores the matching DCQL preset.
  • x509_hash is the HAIP signed-request prefix: DCQL and encrypted direct_post.jwt are required. On the unencrypted direct_post flow, Looking Glass coerces the request to direct_post.jwt. The hosted wallet already trusts the showcase verifier CA; self-hosted wallets validate x5c against WALLET_VERIFIER_X509_TRUST_ANCHOR_PEM. Certificate roots in x5c are never self-trusted. Looking Glass HAIP still issues the key-attested configuration (Sections 4.4.1 / 4.5.1) before that presentation.
  • After a failure, the timeline and wallet modal keep the protocol error and add the matching next step (attestation env, verifier CA, tx_code, rate limit, or wallet proxy).

Each flow execution creates a Looking Glass session. Sessions are linked to backend processing via:

  • The X-Looking-Glass-Session HTTP header
  • The lg_session query parameter (used for redirects where headers cannot be set)

The start-demo response also returns a 256-bit session_token owner capability exactly once. The backend stores only its SHA-256 hash. Keep the token in memory and do not put it in URLs, logs, or shared links.

  • GET /api/lookingglass/sessions returns metadata only; it never exposes captured events.
  • GET /api/lookingglass/sessions/{id} returns the complete owner-visible session only when X-Looking-Glass-Session-Token contains the capability.
  • WebSocket subscriptions offer protocolsoup-lookingglass-v1 and protocolsoup-lookingglass-owner.<session_token> as dedicated Sec-WebSocket-Protocol values. Query-parameter ownership is not supported.
  • Owner-only action headers are redacted from captured traffic before session persistence.

The OAuth Client Credentials interface exposes client authentication and access-token protection as independent selectors. Choose client_secret_basic or private_key_jwt, then choose Bearer or DPoP. Looking Glass captures the real operations for the selected combination, including public JWK registration and client assertions for private_key_jwt, and key generation, proof JWTs, nonce retries, and cnf.jkt binding for DPoP.

The private_key_jwt option requires the owner capability to register its public JWK Set. Registration is accepted only while the matching client_credentials session is active and can succeed only once.

The built-in token decoder is available at POST /api/lookingglass/decode. It handles:

  • JWT access tokens and ID tokens
  • SAML assertions
  • Security Event Tokens (SETs)
  • X.509 certificates

SSF is a protocol in Looking Glass (/looking-glass?protocol=ssf), not a separate sandbox. Catalog flow IDs (caep-session-revoked, ssf-push-delivery, …) are presets into one durable session: they fill the subject/event/delivery chrome. They are not a second execute path.

  • Fire event sends a CAEP/RISC SET for the chrome subject and event to every eligible Transmitter stream (push and poll). That is what changes RP posture on the State tab (and, for session-revoked, the federation revoke-subject hop). Other Looking Glass sessions are not notified.
  • Verify stream only does GET /.well-known/ssf-configuration, stream configuration (GET list, POST create if the list is empty), JWKS, and POST /verify. It does not revoke sessions or disable accounts.
  • Transmitter and Receiver timeline plus unstripped SET/JWKS wire capture (Flow tab is Looking Glass bus only)
  • After CAEP session-revoked, a real HTTP hop to federation POST /oauth2/demo/caep/revoke-subject so OAuth sessions die
  • SET metadata overlay on the Tokens tab (decoded from the signed compact JWT)

/ssf-sandbox redirects to Looking Glass. SSF remains its own image (protocolsoup-ssf) behind the gateway, the same way SCIM does.