Skip to content

Trust

The trust service is the SIGNATIF trust-graph: jurisdiction trust lists per framework, an M-of-K multi-witness master list, and live reason-to-retroactivity revocations. Every response is signed in the tree-head domain, and signature headers name their suites and key ids so a verifier picks the right public keys from /keyring.

In the reference deployment it binds 127.0.0.1:8391. Reads are public; mutations and /admin/log require UNIDPP_TRUST_ADMIN_TOKEN when set.

Evidence documents (the bytes behind attestations, such as certificate PDFs, inspection reports) are never bare URLs: each is registered with a required scope, listed metadata-only, and released only under the scope: the exact bytes, signed by the service keyring, with every release journaled as the access decision. An absent or unsatisfying scope is a stated 403 naming the required scope, never a silent 404. The operator surface (GET /operators/{node}) renders one operator’s credential directory from the same registries: identity and keys, delegation position, trust-list memberships with their validity windows, master-list attestations, revocation standing. See the API reference.

Endpoint What
GET / discovery (endpoints, signing domain, revocation semantics)
GET /healthz liveness
GET /keyring the service keyring (verifier pinning)
GET /graph the trust graph
GET /anchor-bundle?jurisdiction= an anchor bundle per jurisdiction
GET /trust-lists?at=&jurisdiction=&framework= trust lists
GET /trust-lists/{jur}?at= one jurisdiction’s list
POST /trust-lists register a trust list
POST /trust-lists/{jur}/entries upsert a trust entry
GET /master-list the M-of-K master list
POST /master-list/witnesses set the witness set
POST /master-list/entries upsert a master entry
GET /revocations?at=&known_by=&window=&subject=&retroactive= revocation declarations, both readings
POST /revocations declare a revocation
POST /nodes · POST /edges graph registration
GET /evidence · GET /evidence/{id}?scope= the gated evidence catalogue and scoped release (TODO 224)
POST /admin/evidence register a gated evidence document
GET /operators/{node}?at= the operator surface: credentials with validity windows
GET /admin/log?limit=&offset= audit log (admin)

Example (recorded against the reference deployment)

Section titled “Example (recorded against the reference deployment)”
Terminal window
$ curl -s http://127.0.0.1:8391/keyring | jq '{mode, roles: (.roles | keys)}'
{
"mode": "seeded-dev",
"roles": [
"sign-ecdsa-p256",
"sign-ed25519"
]
}
$ curl -s http://127.0.0.1:8391/trust-lists | jq '.trust_lists | length'
1

seeded-dev flags the deterministic dev keyring; production sets a signing seed (see security posture).

The reason codes decide whether history survives:

  • Prospective reasons: key-compromise, cessation, supersession, affiliation-change: prior as-of verifications stay valid (timestamping protects, as with code signing).
  • Retroactive reasons: misissuance, fraudulent-issuance, authority-compromised: void ab initio within the explicit distrust window [start, end], re-valid outside it.

Both readings are computable per declaration: responses carry known_at_cutoff and voids_at_as_of.

Every body is signed over the exact bytes; headers carry x-sig-domain (tree-head), x-sig-ed25519 + x-sig-key-id-ed25519, and x-sig-ecdsa-p256 + x-sig-key-id-ecdsa-p256. Cache policy per response: current-state answers revalidate; point-in-time (?at=) answers are immutable, max-age=86400; mutations are never stored.

SIGNATIF has no service-response domain; tree-head (the operator’s signed statement of state, as used for transparency-log signed tree heads) is the documented adaptation, stated in the discovery document and not hidden.

Manifest-rendered:

Variable Meaning Default
UNIDPP_TRUST_BIND listen address 127.0.0.1:8091
UNIDPP_TRUST_ADMIN_TOKEN Bearer token for mutations and /admin/*; unset = open unset
UNIDPP_TRUST_STATE_FILE append-only JSONL journal none

Direct environment:

Variable Meaning Default
UNIDPP_TRUST_NO_SEED_FIXTURES 1 skips seeding the fixture trust graph at first start unset (seed on)
UNIDPP_TRUST_SIGN_SEED deterministic signing seed (production identity) dev seed
UNIDPP_TRUST_DEV_SEED the dev seed value documented dev seed
  • Fixtures by default. First start seeds a fixture trust graph so the service is useful to a verifier out of the box; disable with UNIDPP_TRUST_NO_SEED_FIXTURES=1 for a clean production instance.
  • Journal replay on start; the graph, lists, and revocation ledger all restore from the journal.
  • No silent unsigned answers. If a response cannot carry its signature headers, that is a bug and not a degradation mode, because the signing keyring is constructed at start or the process exits.