Skip to content

fix(#178): make the hosted gate presentable — and the docs true - #179

Open
TheBlackBit wants to merge 2 commits into
mainfrom
docs/178-reader-identity-trust
Open

fix(#178): make the hosted gate presentable — and the docs true#179
TheBlackBit wants to merge 2 commits into
mainfrom
docs/178-reader-identity-trust

Conversation

@TheBlackBit

@TheBlackBit TheBlackBit commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Closes #178.

What this fixes

Presenting a credential to the demo shows a red wallet warning: "The website requesting
this data is unknown."
The gate never identified itself, and two docs said that couldn't
be fixed yet. It can.

Changes

  • examples/quickstart/server.mjs — the app deployed at credentagent-demo.vercel.app
    now presents a reader identity when one is configured. Unset, behaviour is unchanged,
    so merging and deploying before the setup below is safe.
  • Docs — the guide and the demo-PKI README described the readerIdentity option as
    unbuilt. Corrected.
  • run-gate.mjs — says why no identity was found instead of just "none".

No changes under packages/. No version bump: the pinned 0.3.1 already has the option.

Reviewer setup — needed for the warning to actually clear

1. Vercelcredentagent-demo project → Environment Variables, each holding the full
file contents. Then redeploy.

Variable File
CREDENTAGENT_READER_CERT reader-cert.pem
CREDENTAGENT_READER_KEY reader-key.pem

2. Download site — the utopia.rical at https://credentagent.vercel.app names a reader
whose private key was never published, so importing it does nothing. Replace it with
this one:
drop it into tools/demo-pki/out/ and re-run build_site.py. The credentials and the
VICAL on that page are fine — leave those.

All three files are from one PKI generation and only work together. The certificate covers
localhost and credentagent-demo.vercel.app. Drive is interim; these belong on the site.

Verified

Ran the deployed app configured as the deployment. Its payment request carried the demo
reader certificate in x5c, and that certificate is named on the trust list, under both
origins:

client_id : x509_san_dns:credentagent-demo.vercel.app
client_id : x509_san_dns:localhost

@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
credentagent-demo Ready Ready Preview Sep 1, 2026 3:12pm UTC

Presenting a credential to the demo draws a red wallet warning: "The website
requesting this data is unknown." Two things caused it.

The app deployed at credentagent-demo.vercel.app (examples/quickstart) self-signed
a throwaway reader certificate on every request, so no trust list a tester
imported could ever match. It now presents a reader identity when one is
configured via CREDENTAGENT_READER_KEY / CREDENTAGENT_READER_CERT; unset,
behaviour is unchanged, so deploying before configuring is safe. No version bump
needed — the pinned 0.3.1 already carries readerIdentity.

And two documents still described that capability as unbuilt: the RICAL row in
the trusted-demo-credentials guide, and the "Pending code hook" callout in the
demo-pki README, which called it "documented intent, not a working knob". Both
now state what actually clears the warning — the wallet importing the reader
trust list AND the gate signing with the matching reader key — with the config
snippet and the origin-binding constraint. testing-on-device.md already had this
right; the other two now agree with it.

Also documented: the committed reader certificate has no committed private key
(keys/ is gitignored), so a fresh clone always self-signs and the shipped trust
list matches a reader nobody can present. run-gate.mjs now names that half-state
instead of printing only "reader identity : none".

Verified by running the deployed app configured as the deployment: its payment
request carried the demo reader certificate in x5c under both origins the
certificate covers, and that certificate is named on the trust list.

No changes under packages/.

Signed-off-by: Ever Morales <solisever777@gmail.com>
Signed-off-by: Ever Morales <ever.morales@koombea.com>
@TheBlackBit
TheBlackBit force-pushed the docs/178-reader-identity-trust branch from 13c2c52 to b340770 Compare August 28, 2026 04:37
@TheBlackBit TheBlackBit changed the title docs(demo-pki,#178): the gate can present a trusted reader identity — and the shipped RICAL can't prove it fix(#178): make the hosted gate presentable — and the docs true Aug 28, 2026
@TheBlackBit
TheBlackBit requested a review from dzuluaga August 28, 2026 04:38

@dzuluaga dzuluaga left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve — with two minor doc nits (non-blocking).

Verified the load-bearing claim independently: the quickstart pins @openmobilehub/credentagent-gate@^0.3.1, which resolves to exactly 0.3.1, and I unpacked the published 0.3.1 tarballreaderIdentity is fully implemented there (dist/client.js reads it, SAN-checks it, and threads it through mountCeremonybuildDcPaymentRequest to present a stable reader cert in x5c). So this works on the deployed version, not just the un-published 0.4.0 source. The change is backward-compatible (env unset → readerIdentity undefined → byte-identical to before), and the trust boundary is right: only the reader key/cert land on the gate, so a popped gate can impersonate this one demo reader and nothing else.

Nit 1 (worth fixing) — the new "check it without a phone" line fails on a fresh clone. tools/demo-pki/README.md advertises node tools/demo-pki/verify-reader-trust.mjs, but that script (a) imports packages/credentagent-gate/dist/..., and dist/ is not committed → needs npm run build first; and (b) reads keys/reader-key.pem, which is gitignored. On a fresh clone it hits exactly the "you don't have the private key" failure the rest of this PR explains. Suggest stating the prereqs inline, e.g. "(after ./gen-pki.sh and building the gate package)".

Nit 2 (optional) — SAN caveat. The deployed walletOrigin comes from VERCEL_PROJECT_PRODUCTION_URL; the cert SAN covers credentagent-demo.vercel.app + localhost. warnOnReaderSanMismatch only console.warns (doesn't throw), so if the gate is ever served from a custom production domain or a preview hostname, the warning silently won't clear. A one-line note in the Vercel setup section would save a debugging session.

Neither blocks merge.

Addresses two review nits on the reader-identity docs (both doc-only).

- "Check it without a phone": verify-reader-trust.mjs needs the reader
  private key (from ./gen-pki.sh; gitignored) AND the built gate dist/
  (not committed), so a bare clone can't run it. Lead with both prereqs
  instead of implying the command runs anywhere.

- Step-5 SAN paragraph: on Vercel the gate's walletOrigin is
  VERCEL_PROJECT_PRODUCTION_URL, and the shipped cert's SAN covers only
  credentagent-demo.vercel.app + localhost. A custom production domain is
  off-SAN and only console.warns (never fails), so the "unknown verifier"
  warning silently won't clear; a preview URL keeps the production
  walletOrigin, so it mismatches with no log at all. Call out both traps.

No code or version change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EYBmPdD3LXNo3aJcScTxH
Signed-off-by: Diego Zuluaga <dfzuluaga@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docs say the gate can't present a trusted reader identity — it can, and the shipped demo PKI can't prove it

2 participants