# Private Party authentication contracts Party Governance owns canonical identity resolution and registration. The API authentication edge verifies the browser's OIDC transaction and presents enrolled evidence through this private broker protocol. Session issuance, AUP acceptance and provider account readiness remain separate decisions. ## Versions and activation | Version | Source | Authentication edge | Routing key | Status | | --- | --- | --- | --- | --- | | 1 | [v1 Protobuf](proto/pharos/party_governance/authentication/v1/authentication.proto) | Retained Themelio assertion, including `legacy_session_ref` | `request.party_governance.authentication` | Implemented optional bridge | | 2 | [v2 Protobuf](proto/pharos/party_governance/authentication/v2/authentication.proto) | API-owned OIDC transaction, bound to `login_attempt_id` | `request.party_governance.authentication.v2` | Implemented owner ingress; API attester enrolment required | | 3 | [v3 Protobuf](proto/pharos/party_governance/authentication/v3/authentication.proto) | API-owned OIDC with required stable identity and complete source attributes | `request.party_governance.authentication.v3` | Explicit v3 issuer enrolment | The [implemented ingress](../../../services/beto/contexts/party_governance/adaptors/messaging/authentication/README.md) describes the verification protocols and their separate enrolments. V1 field numbers, signed claims and retained bytes keep their existing meaning. V2 uses a distinct Protobuf package and routing key. It reserves the former registration field 5 and its `legacy_session_ref` name; login attempt identity uses field 6. The broker manifest grants only the API caller the versioned authentication request kinds. V2 has a separate durable queue, `ref.party_governance.authentications.v2`. The owner requires `PARTY_API_AUTHENTICATION_ENROLMENTS`; absent enrolment rejects registration and leaves retained v1 available through its existing enrolment. Browser cutover additionally requires API session handling and the coordinated legacy auth adaptor; a Beto registration reply alone activates neither. ## V2 request and evidence `contract_version` is exactly 2. Request, command, correlation and login attempt IDs are canonical lowercase UUIDs. The API creates the login attempt before redirecting to the enrolled identity provider. It identifies that browser login transaction; it is neither a browser credential nor a legacy session reference. `evidence_ref` is `sha256:` followed by the lowercase SHA-256 hex digest of the complete signed assertion. The [authentication contract catalogue](../../authentication/README.md) and [assertion schema](../../authentication/assertion.schema.json) define the API assertion's protected header, signed claims and verification rules. Its command identity and login attempt must match this envelope. Exact issuer, subject and authentication-time evidence qualify identity; browser-selected Party IDs, email matches and provider bearer tokens cannot establish it. Retries preserve command ID, correlation ID, login attempt, assertion bytes and evidence reference. Transport request IDs may change. Reusing a command ID with changed material input is an idempotency conflict. The consumer checks trusted broker caller identity as well as the enrolled assertion. Unknown fields, duplicate or ambiguous input, missing required values and unsupported versions are rejected at the boundary. Evidence freshness and current Party eligibility are checked again on receipt replay. An original successful decision cannot override later disablement or a changed authentication generation. Expired evidence requires a fresh login; retry cannot manufacture a new assertion under the old command identity. ## V2 outcomes Replies contain version 2, the current request ID and exactly one typed outcome: - `registration`: canonical PartyId, positive authentication generation and root revision, whether the command registered the Party, and the original login attempt ID. The API verifies all correlations before issuing a session. - `rejected`: invalid input/evidence, ineligible authentication, forbidden caller or conflicting command identity. A rejection provides no session authority. - `unavailable`: a dependency failure prevents a confirmed reply. Registration may already have committed; preserve command identity when resolving that uncertain outcome. Unspecified and unknown enum values, missing outcomes and mismatched correlation are invalid replies. Generations and revisions fit unsigned positive JSON-safe integers (`1..9007199254740991`). Generated Protobuf decoding supplies wire types; the owner adaptor enforces these semantic checks, including rejecting duplicate oneof fields rather than accepting Protobuf's last-value behaviour. The registration transaction changes one PartyAuthentication root and commits its receipt, outcome and outgoing intents atomically. Accepted attribute observation has its own durable delivery. A registration reply confirms identity resolution; normal access additionally requires current session, policy and operation-specific authority. Provider credentials never appear in requests, replies or Party events. ## V3 stable identity and complete attributes V3 uses contract version 3, a separate package/queue and `pharos-party-authentication-v3+jwt` with audience `party_governance.authentication.v3`. Its [assertion schema](../../authentication/assertion-v3.schema.json) requires `voperson_id`; the [attribute inventory and recovery rules](../../authentication/README.md#identity-attribute-inventory-and-recovery) define source precedence, bounds, enrolment and operator recovery. The envelope and registration field numbers preserve their v2 meanings. Rejection codes 1–5 retain their meanings; 6 is `recovery_required` and 7 is `identity_conflict`. Both are terminal login rejections with no session authority. Existing packages, signed v1/v2 evidence and stored checkpoints remain unchanged. The new Go package lives at `generated/v3` as `authenticationv3`. ## Generation and compatibility checks `scripts/generate_party_authentication.py` reproduces all versions in the API and Beto owner adaptor trees. V1 retains its existing generated path and package. V2 lives under each existing `generated/v2/` directory as `authenticationv2`. The generator's check mode detects missing, changed and obsolete generated Go bindings without changing handwritten files. The API's `adaptors/messaging/authentication/contract_test.go` pins the existing v1 wire bytes and the new v2 message identities, field reservations and typed outcomes. Verifier, transport framing and enrolment tests run in Beto's native unit lane. `python3 scripts/project_broker_integration.py` qualifies the actual owner transaction and both broker routes, including receipt replay, disable/re-enable fencing and coexistence under one canonical Party identity. The OIDC provider and browser cutover require their separate qualification.