Przejdź do treści

Participant Assurance Levels

Based on:

  • doc/project/40-proposals/007-pod-identity-and-tenancy-model.md
  • doc/project/40-proposals/017-organization-subjects-and-org-did-key.md
  • doc/project/20-memos/console-participant-identity-create-and-import.md
  • doc/normative/50-constitutional-ops/ROOT-IDENTITY-AND-NYMS.md (DIA-ROOT-ID-001)
  • doc/normative/50-constitutional-ops/ATTESTATION-PROVIDERS.md (DIA-ATTEST-PROVIDERS-001)
  • doc/normative/50-constitutional-ops/ROLE-TO-IAL-MATRIX.md (DIA-ROLE-IAL-001)

This memo defines the assurance level model for participant:did:key:... subjects in Orbiplex Node. It establishes the four-level credibility hierarchy, the append-only verification fact contract, the sovereign operator trust anchor pattern, and the privacy boundary that keeps PII out of the fact log.

This model is a prerequisite for downstream consumers — procurement policy, capability access control, and federated trust presentation — that need a stable assurance level contract to design against.

Motivation

Not all participants are equally credible. An anonymous key with no external verification carries different weight than a participant whose phone number has been confirmed, or one whose government-issued identity has been attested, or one whose public key is an explicitly pinned infrastructure trust anchor.

The assurance level is not a reputation signal — it is a structural property of the identity binding itself: how strongly is this participant:did:key:... anchored to a verifiable real-world entity?

Downstream systems — procurement eligibility, capability policy gates, federation onboarding, escrow authorization — may require a minimum assurance level as a precondition. That contract must be defined once, at the identity layer, rather than reimplemented ad hoc by each consumer.

Canonical Scale: IAL0–IAL5

The Orbiplex Node assurance model is grounded in the normative DIA identity assurance level scale defined in ROOT-IDENTITY-AND-NYMS.md (DIA-ROOT-ID-001). That scale runs from IAL0 to IAL5.

The four levels used by the Participant runtime map to the canonical scale as follows:

Runtime name Canonical level Source of assurance
Unknown IAL0 no external attestation
PhoneVerified IAL1 phone OTP confirmation (source_class: phone)
GovIdVerified IAL3 eID, PESEL+registry, or equivalent strong source
SovereignOperator IAL5 software-pinned key; governance designation

IAL2 (basic multisig pseudonym) and IAL4 (legally/constitutionally unsealable pseudonym) are not exposed as distinct levels in the MVP Participant runtime. They remain part of the canonical DIA scale for use in federation and governance contexts where those levels are relevant.

GovIdVerified maps to IAL3 rather than IAL2 because the supported verification methods (eid, mobywatel, epuap, PESEL via registry) all fall under source_class: strong in ATTESTATION-PROVIDERS.md, which tops out at IAL3. Reaching IAL4 would require a separate unsealing track, which is out of scope for MVP.

SovereignOperator maps to IAL5 because it is a governance-level trust anchor, orthogonal to the attestation chain. It is defined as a distinct strength class (sovereign) in ATTESTATION-PROVIDERS.md.

Relationship to NIST SP 800-63 and eIDAS

The DIA IAL0IAL5 scale is structurally parallel to established identity assurance frameworks, adapted to the Orbiplex trust model.

NIST SP 800-63-3 defines three Identity Assurance Levels:

  • IAL1: claimed identity, no real-world verification required,
  • IAL2: evidence-based verification, remote or in-person identity proofing,
  • IAL3: in-person or supervised remote verification, physical or biometric evidence.

eIDAS (EU regulation 910/2014 and its 2.0 revision) defines three assurance levels for electronic identification:

  • Low: limited confidence in the claimed identity,
  • Substantial: substantial confidence, typically multi-factor authentication,
  • High: high confidence, multi-factor with physical presence or equivalent.

The DIA canonical levels map approximately to those frameworks as follows:

DIA level Runtime name NIST SP 800-63 eIDAS Basis
IAL0 Unknown below IAL1 below Low key exists, no binding verified
IAL1 PhoneVerified IAL1 Low possession factor (phone OTP)
IAL2 IAL1–IAL2 Low–Substantial basic multisig; not exposed in MVP runtime
IAL3 GovIdVerified IAL2 Substantial–High strong source: eID, registry, qualified sig
IAL4 IAL3 High unsealable; requires separate track
IAL5 SovereignOperator N/A N/A software-anchored governance designation

The mapping is approximate. NIST IAL2 aligns roughly with DIA IAL3 because both require evidence-based real-world identity proofing from a strong source; DIA IAL2 is the intermediate multisig fallback which has no direct NIST equivalent. DIA IAL5 has no equivalent in NIST SP 800-63 or eIDAS — those frameworks address personal identity verification and do not define a class for software-distribution trust anchors.

Assurance Levels

IAL5 SovereignOperator  >  IAL3 GovIdVerified  >  IAL1 PhoneVerified  >  IAL0 Unknown

IAL0 — Unknown

No verification has been performed. The participant is identified only by their participant:did:key:... value. Self-declared metadata such as nickname or label does not elevate this level.

This is the default state for every newly created or imported participant.

IAL1 — PhoneVerified

The participant's phone number has been confirmed via an active verification step (for example, SMS OTP). This establishes that the operator controlling the participant key also controls the claimed phone number at the time of verification.

This level does not bind the participant to a real-world legal identity. It is a possession-factor confirmation, not an identity proofing step. Corresponds to source_class: phone in ATTESTATION-PROVIDERS.md.

IAL3 — GovIdVerified

The participant has been bound to a government-issued identity record: a country code and a national identification number (for example, PL + PESEL, DE + personal ID, or similar). Verification must be performed against an authoritative source or a delegated attester.

This level provides a binding between the cryptographic participant and a legal-identity-level real-world entity. It is the strongest level achievable through claim verification in the MVP runtime. Corresponds to source_class: eid, mobywatel, epuap, or registry in ATTESTATION-PROVIDERS.md.

IAL5 — SovereignOperator

The participant's public key appears in the node's sovereign operator list — a statically configured or compiled-in set of explicitly pinned trusted keys. This designation is a governance decision, not a verification outcome.

Sovereign operator status is not derived from any verification fact. It overrides the claim-based hierarchy entirely. A sovereign operator with no verified phone or government ID still holds the highest assurance level, because the trust anchor is the explicit key pinning in the software distribution, not the verification chain. Corresponds to source_class: software-pinned in ATTESTATION-PROVIDERS.md.

Assurance Level as a Derived Property

The assurance level is not stored. It is computed by the projector from:

  1. the set of ParticipantVerificationFact events for the participant,
  2. the sovereign operator list from node configuration.

This ensures the level is always consistent with the current fact history and sovereign list. If a verification is revoked, the level drops immediately on next projection. If a participant is added to or removed from the sovereign list, the level updates on next daemon open or configuration reload.

Pseudocode:

fn compute_assurance_level(participant_id, verification_facts, sovereign_list):
    if participant_id in sovereign_list:
        return SovereignOperator
    if any GovIdVerificationConfirmed and not revoked for participant_id:
        return GovIdVerified
    if any PhoneVerificationConfirmed and not revoked for participant_id:
        return PhoneVerified
    return Unknown

Verification Facts

Verification events are recorded in the stream identity/participant-verification-fact.v1 as append-only facts. The stream follows the same pattern as identity/participant-fact.v1.

Critical constraint: the fact log must contain no data derived from the verified material — not the raw value, and not any hash of it.

Phone numbers and national ID numbers (PESEL, passport, etc.) have limited entropy and predictable structure. A hash of such a value — even blake3 — is vulnerable to brute-force enumeration: an attacker who obtains the hash can recover the original value by exhaustively hashing the small search space. For Polish phone numbers (+48 + 9 digits ≈ 10⁹ candidates) or PESEL (11 digits encoding birth date and gender, further reducing the effective search space), this attack is practical on commodity hardware.

The fact therefore records only that verification occurred — by whom, and when:

ParticipantVerificationFact
  | PhoneVerificationConfirmed
  |   participant_id: String        // participant:did:key:z...
  |   verified_at: String           // RFC 3339
  |   verifier_ref: String          // reference to attestation bundle or verifier id
  |
  | GovIdVerificationConfirmed
  |   participant_id: String
  |   country_code: String          // ISO 3166-1 alpha-2, e.g. "PL"
  |   id_kind: String               // "pesel" | "nip" | "passport" | ...
  |   verified_at: String
  |   verifier_ref: String
  |
  | VerificationRevoked
      participant_id: String
      claim_kind: String            // "phone" | "gov-id"
      revoked_at: String
      reason: Option<String>

country_code and id_kind are retained in GovIdVerificationConfirmed because they describe the verification method, not the verified value. They do not allow reconstruction of the ID number.

Local deduplication. If the node needs to detect duplicate verification attempts for the same phone number or ID (for example, to prevent one number from being linked to multiple participants), that check must use HMAC(node_secret_key, normalized_value) in a separate local store outside the fact log — never the raw value or an unsecretted hash. The HMAC key is node-local and never leaves the machine. This store is mutable and deletable, consistent with GDPR obligations.

Attestation Bundle — What the Participant Presents

When a participant presents proof of verification to another party (another node, a federation onboarding gate, a procurement policy check), they present an attestation bundle — a signed artifact produced by the verifying parties.

The attestation bundle proves that verification occurred via the verifiers' signatures. It contains no material derived from the verified data:

participant-verification-attestation.v1:
  participant_id    // participant:did:key:z...
  claim_kind        // "phone" | "gov-id"
  country_code?     // for gov-id: ISO 3166-1 alpha-2
  id_kind?          // for gov-id: "pesel" | "passport" | ...
  assurance_level   // "ial1" | "ial3"
  verified_at
  expires_at
  verifier_signatures[]   // one or more verifier signatures

The receiving party verifies the signatures, not any hash of the participant's phone number or ID. The phone number and ID number are never present in the bundle in any form.

This separation is the security boundary: the fact log records what happened locally; the attestation bundle is what crosses trust boundaries. Neither contains brute-forceable derivations of PII.

Privacy Boundary and GDPR

The append-only fact log is incompatible with GDPR Article 17 (right to erasure) if it contains personal data in any recoverable form. The design above satisfies this by ensuring the fact log contains no PII and no hash from which PII could be recovered.

If the node needs to store retrievable PII for operational reasons (for example, to re-present data to the operator), that data must live in a separate, mutable store outside the fact log, with:

  • explicit retention policy,
  • operator-accessible deletion path,
  • no cross-node replication by default.

The existence of such a store and its schema is outside the scope of this memo and should be defined in a dedicated privacy or data-retention document.

Sovereign operator trust requires no PII at all. It is purely a key-pinning designation with no personal data involved.

Sovereign Operator List

The sovereign operator list is a node-level configuration, not a fact in the log. It is loaded at Daemon::open() alongside the fact history and passed into the assurance level computation as an external parameter.

Recommended form in the node daemon TOML:

[identity]
sovereign_operators = [
    "participant:did:key:z6Mk...",
]

For keys whose trust is protocol-level rather than deployment-level (for example, a designated Orbiplex Foundation infrastructure participant), the list may be compiled into the binary as a compile-time constant. That decision is a governance call, not an implementation detail.

The sovereign operator list must be treated as a security-sensitive configuration artifact. Changes to it should be auditable at the deployment level, equivalent to changing a TLS trust anchor.

Downstream Consumers

The assurance level is a contract that the identity crate exposes for consumption by other subsystems. Anticipated consumers include:

  • procurement policy — minimum assurance level required to place an order,
  • capability access control — certain host capabilities gated by assurance level,
  • federated trust presentation — how this node presents its operator participant's assurance level to peers,
  • escrow and settlement authorization — high-value operations may require GovIdVerified or higher,
  • onboarding gates — federation admission may require a minimum level.

None of these downstream contracts are defined here. This memo establishes only the identity-layer contract. Each consumer defines its own minimum level requirement independently.

What This Memo Does Not Define

  • The verification protocol for phone confirmation (SMS OTP, carrier lookup, etc.).
  • The verification protocol for government ID (document scan, registry API, etc.).
  • The schema for the separate PII store, if one is introduced.
  • The format or validation rules for national ID numbers by country.
  • The schema for the local deduplication store using HMAC.
  • The full schema and signing contract for participant-verification-attestation.v1.
  • Threshold or delegated custody of assurance-level claims.
  • Cross-node or federated presentation of assurance levels.
  • The governance process for adding or removing sovereign operator keys.

Those should be defined in dedicated documents as the relevant workstreams mature.