Unreleased documentation. These pages follow the main branch and can change before the next release. For supported guidance, use v0.15.2.
Control who can request Evidence Gateway
For the assertion provider
Complete Return a governed value before starting this tutorial. You will give two applications different access to that Evidence Gateway service, add one while the service is running, and prove that a valid access token does not let its client ask every configured question.
Understand what you are controlling
Section titled “Understand what you are controlling”This tutorial manages access for machine applications, not accounts for people.
Registry Mint authenticates each application from its own key and issues a short-lived access token. Evidence Gateway then checks whether the application’s access policy includes the configured question. These are separate decisions:
| Decision | Example | Owner |
|---|---|---|
| Which application is calling? | age-checker | Registry Mint client registration |
| What may it ask? | The age-checks policy includes adult-status | Evidence Gateway access policy |
| May Evidence Gateway read its source? | GET /people/{person_id} | Evidence Gateway source configuration |
| May a consumer trust the result? | Expected issuer, audience, and signing key | Consumer verification policy |
The first two rows are the access-management boundary you will configure. Source credentials and consumer trust remain independent.
Access policies are part of Evidence Gateway’s immutable governed configuration. Client membership is part of Registry Mint’s reloadable registry:
| Change | Runtime effect |
|---|---|
| Add or revoke a client | Registry Mint receives a reload request; Evidence Gateway does not restart |
| Add a question or change an access policy | Start a new Evidence Gateway generation |
A client change affects tokens issued after Registry Mint reloads. A token issued before a client is revoked remains valid for up to 300 seconds.
Restart the registry
Section titled “Restart the registry”In one terminal, return to the working directory from the first tutorial and start the synthetic registry:
python3 registry.pyLeave the registry running. In another terminal, enter the project containing both questions:
cd adult-statusThe project has these two governed questions:
| Question | Declared purpose | Answer |
|---|---|---|
adult-status | age-check | Boolean adult status |
age-bracket | service-path-selection | One reviewed age bracket |
An access policy names one or more questions. Each question already fixes its purpose, subject shape, source, and possible answers, so you do not repeat those fields in the policy.
Define two access policies
Section titled “Define two access policies”Define a policy for each service task:
evidencectl access policy add age-checks --question adult-statusevidencectl access policy add service-routing --question age-bracketAdded access policy age-checks for adult-status.Added access policy service-routing for age-bracket.Review the governed policies before starting Evidence Gateway:
evidencectl access policy listPOLICY QUESTIONSage-checks adult-statusservice-routing age-bracketThe commands write the reviewable policy documents to access/policies/age-checks.yaml and
access/policies/service-routing.yaml.
Many clients can share one policy. A client can also belong to several policies when their question
sets do not overlap. evidencectl rejects overlapping policy assignments because they would make
the access decision ambiguous. Adding a question to either policy later changes the governed
authorization boundary and requires a new Evidence Gateway generation.
Register the first local application
Section titled “Register the first local application”Register age-checker under the age-checks policy:
evidencectl access client add age-checker \ --policy age-checks \ --generate-local-keyAdded client age-checker with policy age-checks.--generate-local-key keeps this tutorial self-contained. The private key represents the
application’s identity and remains owner-only at
.evidence/clients/age-checker/private.jwk. The reviewable registration at
access/clients/age-checker.yaml contains the policy membership and public key, never the private
key.
Start the protected service
Section titled “Start the protected service”Compile the questions and both access policies, then start Evidence Gateway and Registry Mint:
evidencectl dev --detachEvidence ready at http://127.0.0.1:8080Mint ready at http://127.0.0.1:8081Registry Mint recognizes age-checker. Evidence Gateway has both access policies available, even though
no client belongs to service-routing yet.
Make an allowed request
Section titled “Make an allowed request”Prepare an adult-status request as age-checker:
evidencectl request prepare adult-status \ --purpose age-check \ --subject person_id=person-123 \ --client age-checker \ --name age-checker-allowedThe Evidence client prepares the request and closes its pinned verification expectations locally.
evidencectl separately signs a one-time client assertion with the local application key and
exchanges it with Registry Mint for a short-lived access token. Preparation sends no HTTP request
to Evidence Gateway and performs no source access.
Send the request across the Evidence Gateway HTTP boundary:
curl --silent --show-error --fail-with-body \ --config .evidence/requests/age-checker-allowed/authorization.curl \ --request POST \ --url http://127.0.0.1:8080/v1/evidence \ --header 'Content-Type: application/json' \ --header 'Accept: application/jose+json' \ --data-binary @.evidence/requests/age-checker-allowed/request.json \ --output age-checker-allowed.jws.json \ --write-out 'HTTP %{http_code}\n'HTTP 200Verify the response before reading it:
evidencectl verify age-checker-allowed.jws.json \ --context .evidence/requests/age-checker-allowed/verification.json \ --output age-checker-allowed.verified.jsonVERIFIEDThe application was authenticated, its age-checks policy matched the request, and Evidence Gateway
called the registry only after both checks passed.
Add an application without restarting
Section titled “Add an application without restarting”Keep Evidence Gateway and Registry Mint running. Register service-router under the existing
service-routing policy:
evidencectl access client add service-router \ --policy service-routing \ --generate-local-keyAdded client service-router with policy service-routing.Registry Mint reload requested.The command writes the public registration to access/clients/service-router.yaml, keeps the
private key under .evidence/clients/, and asks Registry Mint to reload its complete client
registry. The message confirms that the reload was requested, not that Registry Mint accepted the
new registry. The next token exchange provides that functional proof. Evidence Gateway does not restart
because both access policies were already part of its governed configuration.
Review the active client assignments:
evidencectl access client listCLIENT STATUS POLICIESage-checker active age-checksservice-router active service-routingUse the application assigned the policy
Section titled “Use the application assigned the policy”Prepare an age-bracket request as service-router:
evidencectl request prepare age-bracket \ --purpose service-path-selection \ --subject person_id=person-456 \ --client service-router \ --name service-router-allowedSend and verify the response:
curl --silent --show-error --fail-with-body \ --config .evidence/requests/service-router-allowed/authorization.curl \ --request POST \ --url http://127.0.0.1:8080/v1/evidence \ --header 'Content-Type: application/json' \ --header 'Accept: application/jose+json' \ --data-binary @.evidence/requests/service-router-allowed/request.json \ --output service-router-allowed.jws.json \ --write-out 'HTTP %{http_code}\n'
evidencectl verify service-router-allowed.jws.json \ --context .evidence/requests/service-router-allowed/verification.json \ --output service-router-allowed.verified.jsonHTTP 200VERIFIEDThe successful token exchange proves that Registry Mint accepted the live client-registry reload.
service-router belongs to the policy required for this question. Preparation made zero Evidence
Gateway HTTP requests, curl made the single POST /v1/evidence assertion request, and
evidencectl verify checked the response offline.
Try a question the application was not granted
Section titled “Try a question the application was not granted”Prepare the same age-bracket request using the age-checker identity:
evidencectl request prepare age-bracket \ --purpose service-path-selection \ --subject person_id=person-456 \ --client age-checker \ --name age-checker-refusedThe command can prepare the request because age-bracket is a valid project question and
age-checker is a registered client. The client preparation path closes the request and its
verification expectations without calling Evidence Gateway or deciding whether this application
may ask the question. Registry Mint only issues the token. Evidence Gateway makes the authorization
decision when you send the request.
Send the request:
curl --silent --show-error \ --config .evidence/requests/age-checker-refused/authorization.curl \ --request POST \ --url http://127.0.0.1:8080/v1/evidence \ --header 'Content-Type: application/json' \ --header 'Accept: application/jose+json' \ --data-binary @.evidence/requests/age-checker-refused/request.json \ --output age-checker-refused.json \ --write-out 'HTTP %{http_code}\n'HTTP 403Inspect the safe problem response:
python3 -m json.tool age-checker-refused.json{ "type": "https://registrystack.org/problems/evidence/not_authorized", "title": "Request is not authorized", "status": 403, "code": "not_authorized", "operation": "<opaque-operation-id>"}The access token is valid, but the client’s age-checks policy does not authorize the
age-bracket question. Changing only the authenticated application changes the access decision.
The registry terminal shows no new GET /people/person-456, because Evidence Gateway refuses the
request before source access. The response does not reveal which application, question, or policy
caused the refusal.
Revoke an application
Section titled “Revoke an application”Stop issuing new access tokens to age-checker:
evidencectl access client revoke age-checkerRevoked client age-checker.Registry Mint reload requested.The command updates access/clients/age-checker.yaml and requests another Registry Mint reload
without restarting Evidence Gateway. Revocation cannot erase a stateless access token already issued to
the application. That token remains valid for up to 300 seconds.
Try to prepare a fresh request as the revoked client:
if evidencectl request prepare adult-status \ --purpose age-check \ --subject person_id=person-123 \ --client age-checker \ --name age-checker-revokedthen echo 'unexpected request preparation success' >&2 exit 1fievidencectl: unknown or revoked active client age-checkerevidencectl rejects an unknown or revoked named client locally, before contacting Registry Mint
or publishing request artifacts. service-router remains registered and keeps its
service-routing membership.
Inspect the final audit operation
Section titled “Inspect the final audit operation”Stop the local services before reading their completed audit chain:
evidencectl dev stopevidencectl audit show --last-operationLocal Evidence stoppedACCESS REFUSED requester=<pseudonym> reason=not_authorizedThe privacy-safe refusal event contains a requester pseudonym and the closed not_authorized
reason. The event does not contain the rejected requirement, purpose, selector, authority, or
response format. It also does not contain a client identifier or access token. The revoked-client
preparation remains local and creates no Evidence Gateway audit event because no HTTP request was
sent.
Clean up
Section titled “Clean up”Remove the stopped generated runtime while preserving the editable questions, access policy, and request artifacts:
evidencectl dev cleanReturn to the registry terminal and press Ctrl+C.
What you proved
Section titled “What you proved”- Authentication identifies the calling application but grants no question by itself.
- Many applications can share a governed access policy without client-specific Evidence Gateway config.
- A client added while the services run can obtain a token without restarting Evidence Gateway or Registry Mint.
- Each application receives only the questions included in its assigned policies.
- Evidence Gateway refuses unauthorized questions before reading the source.
- Evidence Gateway retains a privacy-safe audit event for an authenticated authorization refusal.
- Revoking a local client requests a Registry Mint reload and prevents new local request preparation.
- Client membership changes affect new tokens while existing tokens remain valid for up to 300 seconds.
- Adding a question or changing an access policy requires a new Evidence Gateway generation.
- Source authentication and consumer trust remain separate from caller access.