Skip to content
Registry StackDocsDevelopment (unreleased)

Return a governed value

For the assertion provider

View as Markdown

Complete Get your first Evidence Gateway assertion before starting this tutorial. You will add a governed age-bracket question to that project while keeping its adult status question. The same date of birth can then answer either question without disclosing the date or exact age.

Outcome
A verified assertion containing one controlled age-bracket value.
Time
About 10 minutes
Level
Local development with synthetic data
Prerequisites
The completed first Evidence Gateway assertion tutorialIts adult-status project and registry.pyPython 3A shell with curl

Adult status answers a yes-or-no criterion. A service that selects different paths for children, young adults, and older adults needs more information, but still does not need a date of birth or exact age.

This tutorial permits four answers:

  • under-18
  • 18-to-24
  • 25-to-64
  • 65-or-older

The provider reviews this closed list. The caller cannot request a narrower bracket or an exact age.

In the terminal that owns the Python registry, return to the first-evidence-assertion directory and start the same source again:

Terminal window
python3 registry.py

Leave the registry running. The source still returns each synthetic person’s identifier, name, and date of birth. This tutorial will use the child record, person-456, to exercise a different registry lookup from the first tutorial.

In another terminal, enter the existing project:

Terminal window
cd adult-status

Create a second question definition alongside questions/adult-status.yaml:

id: age-bracket
question: Which age bracket does this person belong to?
purpose: service-path-selection
subject:
role: person
selector: person_id
source:
operation: getPerson
facts:
- name: date_of_birth
path: /date_of_birth
combine: exactly-one
collectionBounds: {}
answers:
- concept: age_bracket
type: controlled-category
values: [under-18, 18-to-24, 25-to-64, 65-or-older]
derivation: derivations/age-bracket.rhai
disclosure:
allow: [age_bracket]

The new question uses the same OpenAPI operation, projected fact, and subject mapping as adult status. values defines the complete category list. The local compiler turns that list into the codelist enforced by the Evidence Gateway runtime.

Create this new derivation alongside derivations/adult-status.rhai:

fn answer(facts, selectors, context) {
let born = parse_date(required(facts.date_of_birth, "date_of_birth_missing"));
if compare_dates(context.legal_local_date, add_calendar_years(born, 18)) < 0 {
#{age_bracket: "under-18"}
} else if compare_dates(context.legal_local_date, add_calendar_years(born, 25)) < 0 {
#{age_bracket: "18-to-24"}
} else if compare_dates(context.legal_local_date, add_calendar_years(born, 65)) < 0 {
#{age_bracket: "25-to-64"}
} else {
#{age_bracket: "65-or-older"}
}
}

The script chooses one category from the reviewed list. Evidence Gateway rejects any other return value before constructing or signing an assertion.

Capture the edited project in a new immutable local generation:

Terminal window
evidencectl dev --detach
Evidence Gateway ready at http://127.0.0.1:8080
Mint ready at http://127.0.0.1:8081

The command compiles both files in questions/ into the same local Evidence Gateway service. The adult status question remains available. Authentication, source bounds, signing, verification, and audit apply to both questions.

Prepare a request for the updated question:

Terminal window
evidencectl request prepare age-bracket \
--purpose service-path-selection \
--subject person_id=person-456 \
--name age-bracket

Send the prepared request across the real HTTP boundary:

Terminal window
curl --silent --show-error \
--config .evidence/requests/age-bracket/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-bracket/request.json \
--output age-bracket.jws.json

Verify the response before reading the category:

Terminal window
evidencectl verify age-bracket.jws.json \
--context .evidence/requests/age-bracket/verification.json \
--output age-bracket.verified.json
VERIFIED

Inspect the verified payload:

Terminal window
python3 -m json.tool age-bracket.verified.json

The relevant supported value has this shape:

{
"providesValueFor": "urn:registrystack:evidence:local:concept:age-bracket:age_bracket",
"value": "under-18"
}

The source value 2012-05-20 is currently in the under-18 category. The verified assertion does not include the date of birth, exact age, name, or person_id.

Minimum disclosure is relative to the authorized purpose. A boolean was enough for the first question. A controlled category is enough for this service-path decision. Evidence Gateway protects both without treating boolean answers as the only minimized form.

Stop the local Evidence Gateway services:

Terminal window
evidencectl dev stop

Inspect the last verified operation:

Terminal window
evidencectl audit show --last-operation
ACCESS AUTHORIZED age-bracket service-path-selection requester=<pseudonym>
DISCLOSURE RELEASED age_bracket

The audit names the disclosed concept, not the category value or source fact.

Remove the stopped generated runtime while preserving the editable project and request artifacts:

Terminal window
evidencectl dev clean

Return to the registry terminal and press Ctrl+C.