Skip to content
Registry StackDocsv0.41.0

Threat model

View as Markdown

This page summarizes the cross-product threat model. Product specifications and source-owned security tests remain authoritative for exact behavior. Base Registry Engine (BReg) owns the governed record boundary described below.

  • Authoritative registry records and history.
  • Person-level source data. Evidence reads source data in place and releases only a computed, disclosure-shaped answer; no source row crosses the assertion boundary.
  • Private signing keys. Only public verification material leaves the service, so offline verification requires no protected access.
  • Caller and source credentials, subject selectors, and source responses.
  • Governed packages and runtime configuration.
  • Audit integrity and availability of required service and recovery paths.

Evidence Gateway is a minimum-disclosure assertion service. Registry Platform supplies shared security primitives so authentication, HTTP policy, audit, cryptography, and secret handling remain reviewable in one place instead of diverging between services. Demo integrations sit outside this production boundary and do not establish a production freshness or replay-protection profile.

BoundaryMain control
Caller to productOIDC authentication, explicit authorization, bounded request parsing
BReg to PostgreSQLCompiled schema and operations, least-privilege database identity
Evidence to sourceFixed destination and request, credential isolation, transport and response bounds
Evidence to verifierSigned assertion, published verification material, audience and expiry checks
Product to audit storageValue-free records, durable append path, fail-closed behavior where required
Operator to packageClosed schemas, digest verification, reviewed activation and rollback

Evidence authentication and source boundaries

Section titled “Evidence authentication and source boundaries”

Evidence Gateway runs one reviewed OIDC bearer profile with one trusted issuer and exact audience, token-type, and algorithm allowlists. One configured principal claim is authoritative; it does not fall back to client_id, azp, a proxy header, or a request field. Only operational and discovery routes are unauthenticated, and none reveals enabled definitions or requester permissions.

The caller names a predefined requirement revision, purpose, and bounded subject selectors. One authorization decision binds the requester, requirement, purpose, roles, selector profiles, authority, origin tuple, and audience. Partial grants cannot be combined. Possession of a selector or a caller-supplied consent reference is lookup input, not authority. Evidence authorizes before credential resolution or source access and constructs the released assertion from validated, declared concept values.

Evidence reaches data through one of two fixed transports owned by the core:

  • A fixed HTTP JSON request pins origin, method, path authority, headers, authentication, TLS, projection, redirect denial, proxy denial, and one request per acquisition stage. Request scripts may prepare only bounded query pairs and at most one JSON body.
  • A reviewed SQL statement runs against a local read-only SQLite extract. It has no origin, network route, database credential, or caller-selected statement. Rust binds a bounded map of scalar values by index, and the runtime caps rows, cells, statement steps, time, response bytes, and concurrency.

Every source response is validated against its governed schema before extraction. Lookup collapses to match, no match, or ambiguous; Evidence does not fetch broad candidate sets, follow pages, score candidates, or expose counts. Raw source responses are neither persisted nor logged.

  • Secret material in deployment configuration: an HTTP source credential is named by a logical secret reference instead of stored in the bundle. A statement source has no credential by construction. Credential-free HTTP is admitted only for local assurance at a canonical numeric loopback origin.
  • Token forgery: signatures, issuer, audience, token type, and algorithm are checked before token claims are trusted. Route scopes and grants remain governed even when a token is valid.
  • Sender-constrained token replay as bearer: Evidence denies an access token with a proof-of-possession confirmation claim because it validates no sender proof.
  • Privilege escalation: authorization is deny-by-default and requires exactly one complete grant and authority-path match before source access. Reach is never widened by request input.
  • Membership and authorization oracles: no-match, ambiguous, missing-fact, and inconsistent results collapse to one public shape. Authorization refusals collapse to evidence.denied. Detailed categories stay in value-free audit.
  • Cross-purpose tracking: subject bindings use a keyed, domain-separated derivation over audience, purpose, role, selector profile, key version, and the complete canonical selector bundle.
  • Error, log, and telemetry leakage: public problems carry stable codes. Selector, source, and disclosed values do not appear in logs or native audit. Metrics are off by default and use a separate private listener with closed labels.
  • Over-collection: callers cannot supply thresholds, expressions, scripts, source fields, paths, headers, relationship types, or response projections. Undeclared concepts and values outside governed type, codelist, cardinality, precision, or size bounds are rejected.
  • Payload substitution: signed flattened JWS is the default. Unsigned output uses a distinct media type and requires permission in both the immutable bundle and matched grant; the strict verifier rejects it.
  • Release without accountability: final response bytes are produced before the disclosure-release audit entry is durably accepted, and only then released.
  • Hot policy mutation and tenant confusion: the runtime has no override, reload, merge, or fallback. One process has one issuer-governance boundary, bundle lifecycle, signer, and audit boundary.
  • SSRF and uncontrolled egress: the fixed HTTP executor owns origin, method, path authority, authentication, TLS, headers, redirect denial, proxy denial, and request count. The statement transport opens one local file and has no network destination an attacker can steer.
  • Hostile or defective reviewed scripts: the script engine has no filesystem, environment, network, process, module, ambient clock, or randomness. Operation ceilings stop runaway execution. A statement script never receives SQL text, an extract path, file handle, or database connection.

Audit as a control. Evidence writes a mandatory access-attempt entry before each acquisition stage and a disclosure-release entry after signing but before returning the response. A failure blocks the corresponding action. Native audit contains reviewed identifiers and decision categories, not raw selectors, source values, credentials, tokens, or subject identifiers. A keyed, versioned, domain-separated pseudonym covers the canonical selector bundle where correlation is required.

The audit log is not chained or signed, so the writing host can rewrite or delete local entries. Tamper evidence and completeness require shipping sealed files or stdout to append-only storage. One process may write each audit path because the writer takes an exclusive lock. Investigation also depends on retaining the pseudonym key and request context.

The model assumes every reachable deployment is probed continuously at machine speed. Refusal shapes therefore avoid distinguishing signals, and source calls remain fixed by governed configuration. Request schemas expose no caller-supplied expression, script, path, header, or projection. Parsers and scripts apply size, count, and operation ceilings so one request cannot buy unbounded work.

Nightly and merge-queue fuzz smoke covers platform token and API-key parsing, SD-JWT issuance and holder-proof input, reviewed SQLite statement parsing, Evidence verification, authoring readers, and Manifest YAML and rendered-artifact JSON. It does not cover every request path or every presentation path behind an otherwise valid signature.

Human review remains load-bearing under sustained probing. It must cover the whole enabled disclosure surface, project semantics, dependency update cadence, and edge rate controls.

Field encryption draws a boundary inside the database

Section titled “Field encryption draws a boundary inside the database”

BReg can store a restricted field as an AES-256-GCM envelope under a data-encryption key wrapped by Vault or OpenBao Transit. This protects values from database administrators, replicas, dumps, backups, and SQL injection that reaches only ciphertext. It does not protect values from the running process or a holder of the Transit credential because both can obtain plaintext.

When the key cannot be unwrapped, entities with encrypted fields answer with HTTP 503 runtime.field_encryption.unavailable while entities without encrypted fields continue serving. Equality lookups use an HMAC-SHA-256 blind index, which deliberately exposes equality, presence, and cardinality to a database reader. Plaintext backups taken before encryption remain outside the boundary until retired or encrypted.

The implementation uses the FIPS build of AWS-LC with no non-FIPS runtime fallback. Registry Stack does not claim certification of itself.

  • Health, readiness, and offline checks do not certify Transit policy or key custody. A local-assurance deployment can be internally consistent without production-grade custody.
  • Combined disclosure remains a human review. Differently named disclosure families can overlap, and rate limits do not make an unsafe bundle safe.
  • Startup does not detect overlapping authority paths. Ambiguity denies at request time but appears as an unexplained refusal.
  • Rate limits are per process and in memory. Replicas multiply budgets and restart resets them, including the failed-selector enumeration defense.
  • Released assertions have no recall, revocation, status list, or presentation-time check. Validity windows and key publication determine how long they verify.
  • The request nonce is echoed correlation data, not replay prevention. Evidence does not enforce uniqueness or consume it.
  • Secret provisioning, key custody and rotation, audit retention, backups, database access, network isolation, TLS, edge quotas, monitoring, dependency response, incident response, source correctness, and legal authority remain operator duties.
  • Project approval remains semantic. Validators cannot decide whether an institution chose the lawful purpose, correct source fields, derivation, or disclosure default.

A BReg publisher can turn record-derived counts into a release readable by profiles without record access. The compiler confines the population and dimension domains and requires caller-independent source visibility across the entire derived dependency closure. Live reads reuse ordinary list predicates. The runtime verifies package activation and freshness before committing an immutable version; current definition digests fence released reads.

The runtime cannot update or delete release tables. A migration-owned PostgreSQL function records a withdrawal and deletes its content atomically. Audit gates cover request attempts and returned bytes and contain references and lifecycle metadata, never cell values or unit counts.

Suppression and deterministic rounding accept inference through totals, interval arithmetic, zeros, differencing, and auxiliary information. They supply no cumulative privacy budget. See live counts and statistical releases before deciding which populations may be released.

These are non-goals for this version. None of them should be read into a Registry Stack conformance claim:

  • A credential lifecycle: Evidence Gateway’s SD-JWT VC output is a second serialization of the same stateless assertion. There is no issuance session, credential offer, status list, revocation, reissuance, persisted credential state, or OID4VCI endpoint of any kind, in either subject binding mode. Under the default audience-scoped mode there is no holder binding ceremony either, and an optional caller-supplied holder key is echoed unverified into a confirmation claim rather than proved. A requirement that declares the holder-bound mode adds a proof of possession the relying party checks at presentation, and nothing else: the service appends no key-binding JWT, issues no challenge, and retains no presentation or replay state.
  • Delegated or federated evaluation between peers: no service in this model evaluates a question on another deployment’s behalf, and there is no trust-chain discovery, peer registry, or cross-institution evaluation route.
  • Identity resolution: lookup is match, no-match, or ambiguous. Evidence Gateway is not an identity-resolution or record-linkage engine and returns no candidate material.
  • Cross-verifier credential use under the default binding mode: an audience-scoped subject binding makes an assertion meaningful to one relying party and correlatable across none. A requirement that declares the holder-bound mode opts out of this non-goal deliberately, and accepts the correlation that follows: holder key reuse links a holder across every verifier that sees it, and the service can neither prevent nor detect that. Batch issuance under distinct keys reduces the deterministic key-based link; it does not make credentials unlinkable, because members still share an issuance timestamp, purpose, requirement, Evidence Type, configuration revision, and disclosed values.
  • Replay prevention at presentation: a relying party verifying a key-binding JWT compares the nonce from the challenge it issued, and comparing a nonce is not consuming it. The same presentation bytes verify again under the same stateless policy. RFC 9901 section 7.3 places the challenge lifecycle in the surrounding protocol, so issuing a nonce, retaining it, and retiring it are the relying party’s own duties.
  • External policy enforcement of any kind: no runtime service in this stack evaluates an external policy. There is no policy decision point, no ODRL term enforcement, and no policy discovery. Registry Manifest can publish a policy reference, and that reference describes intent rather than naming a control the stack applies.
  • Certified standards compliance: Aligning with a standard is not conforming to it. Speaking the shape of OIDC, OAuth 2.0, SD-JWT VC, CCCEV, or the rest does not certify conformance to any of them, and CCCEV-shaped output is not conformant to CCCEV 2.2.0.
  • A hostile local account on the machine that runs adopter tooling: bregctl, evidencectl, caseworkctl, schedulingctl, and the other authoring and scaffolding commands assume a single-user machine the adopter trusts, and resisting another account on that machine is not a tooling guarantee. Some bregctl lifecycle writes walk directories by descriptor: they refuse a symbolic link they encounter, and an ancestor replaced after the walk cannot redirect them, because they keep writing into the directory they already hold. Other tooling writes use ordinary path-based file operations, and another account that can write to a parent directory can race their directory creation or redirect them through a symbolic link. Generate production key material on a machine where no other account can write anywhere along the output path. The owner, mode, and no-follow checks described for the runtimes are runtime startup checks.
  • Non-Unix targets: Evidence Gateway is Unix-only. Its secret and audit invariants depend on owner, mode, no-follow, link-count, and open-file identity checks, so the runtime does not compile for a non-Unix target rather than degrading those checks.

Use product-owned tests and production checks, then verify one realistic authenticated request, denial behavior, audit failure, dependency failure, backup, and recovery.