Functional Requirements Catalog
Derived, not authored. Every requirement below is extracted from an existing concept doc or its cited source (proto/controller/entity) — nothing here is new scope. Treat this as a BA-style index into the specs, not a replacement for them — each row cites where to read the full contract.
Audience: anyone who needs “what must the system do” as a flat, actor-organized list — product planning, test-case derivation, or onboarding a new contributor to the behavior surface before the architecture surface.
How to read this
- FR ID — stable identifier, grouped by domain (
FR-ISS-*issuer,FR-HLD-*holder, etc.). Not the same numbering as the concept docs’ own guardrail letters (C1,G1,H1,V1) — those are constraints on how, these are what the system does. - Status —
Built,In Progress, orPlanned, taken from the source doc at time of writing. Not automatically kept in sync — re-check the source doc if this page’s date is old. - Source — the authoritative doc/section. Disagreements resolve in the source’s favor.
- Functional requirements only. Cross-cutting non-functional constraints (mTLS, rate limits, encryption-at-rest) are listed once at the end rather than repeated per domain.
Actors
| Actor | Definition |
|---|---|
| Issuer | An accredited institution issuing credentials — custodial (Attest ID holds the key) or BYOK (issuer holds it). |
| Holder | The credential subject — owns a wallet, claims/shares/proves credentials. |
| Verifier | Checks a credential’s authenticity — anonymous by default, optionally a registered organization. |
| Custodian | A fourth role: attests to a document it collected but did not originally issue (Tier-2). |
| Admin | Platform operator — approves issuers/custodians/verifiers, manages config, audits. |
| System | Automated actors: schedulers, the LLM client, background jobs. |
FR-ISS: Issuer Onboarding & Identity
Source: System Design §8.3, §9.3.1; BYOK Signing Spec §5.1; Issuer API Keys
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-ISS-1 | An institution shall be able to self-register as an issuer (POST /issuer/register), custodial or BYOK, without prior admin action. | Issuer | Built |
| FR-ISS-2 | Every new issuer registration shall land PENDING_APPROVAL unconditionally — no path to ACTIVE straight out of registration, for either signing mode. | Issuer, Admin | Built |
| FR-ISS-3 | A PENDING_APPROVAL or REJECTED issuer shall be able to sign in but reach only a holding-bay status page — no business functionality — until an Admin approves it. | Issuer, Admin | Built |
| FR-ISS-4 | An Admin shall be able to approve or reject a pending issuer, and suspend/reinstate/revoke an active one. | Admin | Built |
| FR-ISS-5 | An issuer shall be able to rotate its signing key, with version history retained for historical verification. | Issuer | Built |
| FR-ISS-6 | An issuer shall be able to configure SSO (OIDC or SAML 2.0) for its own portal sign-in. | Issuer | Built |
| FR-ISS-7 | A custodial issuer shall be able to issue and manage server-to-server API keys (create, list masked, revoke) for headless integrations, without needing an interactive session. | Issuer | Built |
| FR-ISS-8 | A revoked API key shall stop authenticating on the very next request — no propagation delay. | System | Built |
FR-BYOK: BYOK Signing
Source: BYOK Signing Spec; BYOK Reference SDK & Oxford Demo Issuer
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-BYOK-1 | An issuer shall be able to register a public key only (BYOK) and sign every credential itself; Attest ID shall never receive or store the private key. | Issuer | Built |
| FR-BYOK-2 | The platform shall verify a BYOK-submitted signature against the issuer’s registered public key before accepting a credential, rejecting an invalid one with 400. | System | Built |
| FR-BYOK-3 | A BYOK issuer shall generate credential_id, issuanceDate, and the proof’s created timestamp itself and submit them with the signed request. | Issuer | Built |
| FR-BYOK-4 | A reference SDK and demo issuer shall exist so a third party can implement or validate a from-scratch BYOK client against the same contract. | Issuer | Built |
FR-CRED: Credential Issuance & Lifecycle
Source: System Design §8.1, §6.1
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-CRED-1 | An active issuer shall be able to issue a single W3C Verifiable Credential, custodial or BYOK-signed. | Issuer | Built |
| FR-CRED-2 | An issuer shall be able to batch-issue credentials via a single JSON request (/credentials/batch), each record optionally carrying its own BYOK signature. | Issuer | Built |
| FR-CRED-3 | An issuer shall be able to revoke a credential it issued, changing its lifecycle status. | Issuer | Built |
| FR-CRED-4 | A revocation shall optionally capture and classify a reason (MISCONDUCT/DATA_CORRECTION/EXPIRED_ACCREDITATION/ADMINISTRATIVE/OTHER). | Issuer, System | Built |
| FR-CRED-5 | A credential shall be retrievable by ID, returning its current status and metadata. | Verifier, Holder | Built |
FR-VER: Credential Verification
Source: System Design §8.2
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-VER-1 | Any party shall be able to verify a credential’s Ed25519 signature and status without authentication (POST /credentials/verify). | Verifier | Built |
| FR-VER-2 | A shareable verification link shall resolve a credential, verify it, and log the access for the holder’s transparency trail, in one request (GET /verify/{share_token}). | Verifier, Holder | Built |
| FR-VER-3 | Verification shall be stateless and resolve issuer keys via the Issuer Registry rather than local storage, so it scales independently. | System | Built |
| FR-VER-4 | Every verification event shall be recorded in an immutable audit trail, queryable by the holder and by admins. | System, Holder, Admin | Built |
FR-HLD: Holder Authentication & Wallet
Source: Holder Authentication
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-HLD-1 | A holder shall be able to sign in passwordlessly via magic-link email. | Holder | Built |
| FR-HLD-2 | A holder shall be able to register and sign in with a WebAuthn passkey. | Holder | Built |
| FR-HLD-3 | A holder shall be issued a 24-word recovery code as a fallback when both magic-link and passkey are unavailable. | Holder | Built |
| FR-HLD-4 | No sign-in attempt shall reveal whether an email/account exists (no enumeration) on any auth endpoint. | System | Built |
| FR-HLD-5 | A holder’s session shall be delivered as an HttpOnly cookie, never a JS-readable token. | System | Built |
FR-VFR: Verifier/Employer Identity
Source: Verifier / Employer Identity
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-VFR-1 | An organization shall be able to self-register as a verifier, landing PENDING_APPROVAL. | Verifier | Built |
| FR-VFR-2 | An Admin shall be able to approve or reject a pending verifier registration. | Admin | Built |
| FR-VFR-3 | A registered, approved verifier shall be able to sign in via magic link and have its organization name attributed automatically and authoritatively on every verification it performs. | Verifier | Built |
| FR-VFR-4 | Anonymous, account-free verification shall remain available and unaffected by the registered-verifier feature. | Verifier | Built |
FR-CAT: Master Data Registry (Catalog & Learner Records)
Source: Master Data Registry
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-CAT-1 | The platform shall maintain a jurisdiction-agnostic catalog of qualifications, units, skill sets, micro-credentials, identity documents, and licences, versioned so a superseded entry is never deleted. | Admin, System | Built |
| FR-CAT-2 | Each jurisdiction shall be independently configurable (frameworks, code sets, document types) without a schema change — onboarding a new market is a data change. | Admin | Built |
| FR-CAT-3 | The platform shall record a learner’s identity, national identifiers (encrypted at rest), enrolments, and outcomes, and link them (softly) to issued credentials. | Issuer, System | Built |
| FR-CAT-4 | An issuer shall be able to register its accreditation scope against a jurisdiction’s regulator (issuer_scheme_registration) with a registration number and scoped catalog entries. | Issuer, Admin | Built |
| FR-CAT-5 | The platform shall support generating a regulator-specific export (e.g. AVETMISS NAT files) by mapping core fields to that scheme’s export fields via a small, extensible resolver strategy set. | Admin, System | Built |
FR-CST: Custodian Onboarding & Attestation
Source: Custodian Onboarding
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-CST-1 | An organization shall be able to register as a Custodian (a fourth role, distinct from Issuer) with its own DID/key custody. | Custodian | Built |
| FR-CST-2 | A Custodian shall be able to upload a batch of third-party credential documents for intake, with no document bytes ever persisted in the platform’s own storage beyond cold storage. | Custodian | Built |
| FR-CST-3 | The system shall extract structured fields from an uploaded document via on-demand LLM vision, suggesting (never auto-committing) a holder match and a catalog-entry match. | System | Built |
| FR-CST-4 | A human reviewer shall confirm or correct the holder match and extracted fields before any attestation is created. | Custodian | Built |
| FR-CST-5 | A confirmed review shall produce a Tier-2 CustodianAttestationCredential, signed with the Custodian’s own key, distinguishable from a Tier-1 original issuance in every verification response (provenance block). | Custodian, System | Built |
| FR-CST-6 | A reviewer shall be able to view a watermarked, non-downloadable preview of the source document when extracted fields are insufficient to review confidently, gated by a second-level authorization check for elevated-sensitivity documents. | Custodian | Built |
| FR-CST-7 | A holder shall be able to claim a Custodian-attested credential into their wallet, and it shall display distinctly from a Tier-1 credential. | Holder | Built |
FR-CMP: Custodian Compliance
Source: Custodian Compliance
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-CMP-1 | A custodian attestation’s expiry shall be derived from the source document’s actual expiry (or the catalog’s validity rule), not a flat 365-day default from attestation time. | Custodian, System | Built |
| FR-CMP-2 | A Custodian shall have a cross-batch register of every credential it has attested, with live status (VALID/EXPIRING_SOON/EXPIRED/REVOKED) computed at read time. | Custodian | Built |
| FR-CMP-3 | A Custodian shall have a roster of the people its attestations belong to. | Custodian | Built |
| FR-CMP-4 | The system shall send pre-expiry and post-expiry reminders to both the holder (claimed or unclaimed) and the Custodian, on a configurable offset schedule, without double-sending. | System | Built |
| FR-CMP-5 | The system shall track re-performance obligations (a credential that must be redone) as a scheduled lifecycle (DUE → SCHEDULED → COMPLETED/CANCELLED/derived OVERDUE), closed only by a fresh attested document — never a manual “renew”. | Custodian, System | Built |
| FR-CMP-6 | A holder shall be able to consent to sharing their wallet profile data with a Custodian for roster/compliance purposes. | Holder, Custodian | Built |
| FR-CMP-7 (Phase 7) | A Custodian shall be able to manage its own credential catalog directly and attest without requiring an intake batch (direct attestation, evidence uploaded or system-generated). | Custodian | In Progress |
FR-SRC: Custodian Portal Search
Source: Custodian Portal Search
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-SRC-1 | A custodian user shall be able to jump to any record (person, credential, batch, document, group) from a global, app-bar search. | Custodian | Built |
| FR-SRC-2 | A custodian user shall be able to filter People, Credentials, or Intake lists by a per-scope, server-enforced allow-list of filters. | Custodian | Built |
| FR-SRC-3 | A custodian team shall be able to save a search (text + filters) and share it across the team, and set a personal default per scope. | Custodian | Built |
| FR-SRC-4 | A saved search referencing a group shall never leak cross-organization data — a foreign or unknown group id resolves as not-found, never as data. | System | Built |
FR-WFC: Custodian Workforce & Compliance Gap Analysis
Source: Custodian Workforce Compliance
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-WFC-1 | A Custodian shall be able to define groups (e.g. by site/role/contractor status) and per-group credential requirements. | Custodian | Built |
| FR-WFC-2 | The system shall derive, at read time, each person’s requirement state (MET/EXPIRING_SOON/EXPIRED/REVOKED/MISSING/NOT_YET_DUE) and a per-person roll-up, without storing or caching a gap state. | System | Built |
| FR-WFC-3 | A Custodian shall be able to bulk-import people into the roster/groups. | Custodian | Built |
| FR-WFC-4 | The system shall forecast upcoming lapses by group/role so training capacity can be planned ahead. | Custodian | Built |
| FR-WFC-5 | A Custodian shall be able to grant a time-boxed waiver against a specific gap, distinct from and never counted as “met”. | Custodian | Built |
| FR-WFC-6 | A holder shall be able to consent to disclose specific requirement states to a Custodian via a scoped proof link, without exposing group membership or other people’s data. | Holder | Built |
| FR-WFC-7 | A holder shall be able to push evidence to a Custodian unprompted (consented share), in addition to responding to a Custodian’s ask. | Holder | Built |
FR-CLM: Holder Claim Integrity
Source: Holder Claim Integrity
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-CLM-1 | A name-only fuzzy match between a document and a holder account shall never auto-bind a credential — it shall be a suggestion only, requiring the claimant to prove ownership. | System | Built (Phase 1) |
| FR-CLM-2 | The system shall generate a document-derived knowledge challenge the claimant must answer correctly to claim a Tier-2 credential, never LLM-judged. | Holder, System | Built (Phase 2) |
| FR-CLM-3 | A repeated wrong answer to a knowledge challenge shall back off, then lock, requiring fresh authentication to retry. | System | Built (Phase 4) |
| FR-CLM-4 | The system shall compute an identity-check risk signal at claim time; an uncertain/false result shall escalate to a hold, never auto-deny. | System | Built (Phase 3) |
| FR-CLM-5 | A claim placed on hold shall auto-clear or escalate to an admin per defined risk criteria, rather than blocking indefinitely. | System, Admin | Built (Phase 5) |
| FR-CLM-6 | Every step of the claim flow shall be recorded in a tamper-evident, audit-chained log, never a bare log line. | System | Built (Phase 6) |
| FR-CLM-7 | A holder shall be able to dispute a claim after the fact (“this wasn’t me”) and trigger a reversal path. | Holder | Planned (Phase 7) |
| FR-CLM-8 | An unclaimed placeholder-DID credential shall be claimable via either a claim link or a fresh onboarding invite. | Holder | Planned (Phase 5c onboarding-invite path) |
FR-CNV: Cross-Custodian Attestation Convergence
Source: Cross-Custodian Attestation Convergence — spec only, no code yet
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-CNV-1 | A credential’s VC shall embed the issuer’s display name so a second custodian can recognize a prior attester directly from the presented credential. | System | Planned |
| FR-CNV-2 | When a second custodian, or the real issuer, later touches the same underlying record, the system shall auto-link the two attestations when the match is unambiguous — no admin click required. | System | Planned |
| FR-CNV-3 | An admin shall be pulled in only for a genuinely ambiguous match, to resolve it or to oversee/undo an automatic link — never to approve every match. | Admin | Planned |
FR-DSC: Verifier Provenance Disclosure
Source: Verifier Provenance Disclosure — spec only, no code yet
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-DSC-1 | When a verifier checks a credential that has since been superseded by a more authoritative record, the verification response shall disclose that fact, reusing the existing live status check with no extra round trip. | Verifier, System | Planned |
| FR-DSC-2 | Provenance disclosure shall be advisory only — it shall never change the credential’s own validity outcome. | System | Planned |
FR-LLM: LLM-Assisted Features
Source: LLM Integration
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-LLM-1 | A verifier shall see a plain-language summary and cross-border equivalency note alongside a verification result. | Verifier | Built |
| FR-LLM-2 | An admin shall see a plain-English anomaly narrative on the network dashboard, and be able to search audit logs using natural language (translated to structured filters, never executed directly by the model). | Admin | Built |
| FR-LLM-3 | An issuer shall get an AI-suggested CSV column mapping for bulk issuance, and an AI-classified revocation reason at revoke time — both reviewed/editable before being applied. | Issuer | Built |
| FR-LLM-4 | An admin configuring a regulatory export field map shall get an AI-suggested mapping from a plain-language description, constrained to fields the platform can actually source. | Admin | Built |
| FR-LLM-5 | An issuer’s KYC document and a holder’s ID-check photo shall be analyzed by vision extraction, informationally only — never gating approval or blocking any action. | Issuer, Holder | Built |
| FR-LLM-6 | Every LLM-assisted feature shall degrade cleanly to “unavailable” when the model endpoint is unset, disabled, or unreachable — no feature is load-bearing for core issuance/verification correctness. | System | Built |
| FR-LLM-7 | A user shall be able to semantically search the catalog and ask a plain-language support question, answered from an in-memory embedded index of catalog/docs content. | Issuer, Admin | Built |
FR-ADM: Admin Console
Source: System Design §6.4; Admin Console
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-ADM-1 | An admin shall be able to manage admin users with role-based access (ADMIN/OPERATOR/VIEWER). | Admin | Built |
| FR-ADM-2 | An admin shall be able to view and update global system configuration (thresholds, feature flags, notification settings). | Admin | Built |
| FR-ADM-3 | Every administrative action shall be recorded in an immutable audit trail, queryable and natural-language-searchable. | Admin, System | Built |
| FR-ADM-4 | An admin shall be able to view aggregate network-wide platform statistics and system health. | Admin | Built |
| FR-ADM-5 | An admin with the ADMIN role shall be able to live-tail a running service’s container logs as a stream, from the Admin Console itself. | Admin | Built |
FR-IDV: Identity Verification — Liveness & Facial Match
Source: IDV Liveness & Facial Verification — named gap only, not scoped, not built
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-IDV-1 | The system shall confirm a live, physically-present human (anti-spoofing/liveness) at the moment of a holder claim. | Holder | Planned — unscoped |
| FR-IDV-2 | The system shall match the live face against a reference image tied to the claimed identity. | Holder, System | Planned — unscoped |
No API shape, vendor, or data-retention design exists for either row — see the source doc before treating these as actionable.
FR-LMS: Course Delivery & Retakes
Source: Course Delivery & Retakes (LMS) — design spec, no code/schema/service built
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-LMS-1 | A holder shall be able to retake an online-deliverable course/assessment in credential-wallet, assigned by a custodian’s re-performance schedule or taken self-serve. | Holder | Planned |
| FR-LMS-2 | A custodian/issuer shall be able to connect their own LMS (LTI 1.3, SCORM/xAPI, or a signed webhook) so a completion there closes the loop in Attest. | Custodian, Issuer | Planned |
| FR-LMS-3 | A custodian/issuer with no existing LMS shall be able to author and publish a minimal native course (lessons + one assessment) in Attest. | Custodian, Issuer | Planned |
| FR-LMS-4 | A course with a practical component shall never auto-close a re-performance schedule or auto-issue a credential from the online portion alone. | System | Planned |
FR-WFP: Workforce Platform Expansion (Payroll & Rostering)
Source: Workforce Platform Expansion — named direction only, not scoped, not built
| FR ID | Requirement | Actor | Status |
|---|---|---|---|
| FR-WFP-1 | The custodian platform shall process payroll (wages, tax withholding/remittance, banking) for workforce members. | Custodian | Planned — unscoped |
| FR-WFP-2 | The custodian platform shall support shift/labor rostering, gated by workforce compliance state. | Custodian | Planned — unscoped |
No jurisdiction, licensing, data-residency, or build-vs-integrate design exists for either row — see the source doc before treating these as actionable.
Cross-Cutting Non-Functional Requirements
These aren’t separate user-facing features — constraints every FR above is built under.
| NFR | Requirement | Source |
|---|---|---|
| NFR-1 | Every internal gRPC connection shall require mutual TLS with no plaintext fallback. | Internal gRPC mTLS |
| NFR-2 | The API Gateway shall rate-limit every route independently (Redis-backed, per authenticated user/issuer or per IP). | API Gateway |
| NFR-3 | No sign-in flow across any actor (holder, verifier, issuer, custodian) shall allow account enumeration. | Holder/Verifier/Custodian identity docs |
| NFR-4 | Custodial private keys shall be encrypted at rest (AES-256-GCM at the application layer today; target design is HSM/KMS before onboarding an external issuer whose custody isn’t otherwise trusted). | System Design §9.1 |
| NFR-5 | A Custodian shall never persist the original bytes of a collected document beyond cold storage; extraction reads are transient, in-memory, single-use. | Custodian Onboarding |
| NFR-6 | Every schema change shall go through Flyway migrations, in-place edits to each service’s V1__schema.sql/V2__seed_data.sql only (no V3+ files). | CLAUDE.md, Database Schema Ownership |
Summary
| Status | Count (approx., FR rows only) |
|---|---|
| Built | ~64 |
| In Progress | 1 (FR-CMP-7) |
| Planned | 18 (FR-CLM-7/8, FR-CNV-1..3, FR-DSC-1..2, FR-IDV-1..2, + IDV unscoped, FR-LMS-1..4, FR-WFP-1..2 + unscoped) |
The overwhelming majority of this platform’s functional surface is built, not aspirational — the genuinely open functional work clusters almost entirely in one arc (chain-of-custody: the holder-claim dispute path, cross-custodian convergence, and verifier provenance disclosure in full) plus one entirely unscoped idea (IDV liveness/facial match). See Chain of Custody Overview for that arc’s own launch-blocking assessment, and CLAUDE.md’s “Roadmap Context” for the authoritative current backlog — this catalog is a map of what, not a substitute for either’s when.