Skip to content

Bridge persistence and enrollment atomicity

BridgeIdentityRegistry and BridgeEnrollmentService are deterministic domain contracts. The BridgePersistenceAdapter is the narrow PostgreSQL boundary for the same state. The phase-1 authenticated HTTP enrollment transport in bridge_transport.py calls the adapter on the request-owned transaction connection.

Stored data

The adapter stores only:

  • project and Bridge identity metadata;
  • lifecycle status and allowed account references;
  • challenge identifiers, public-key fingerprints, expiry and consumed time;
  • SHA-256 hashes of challenge nonces.
  • SHA-256 hashes of one-time bootstrap credentials and opaque Bridge tokens.

It never accepts or stores private keys, raw nonces, signatures, raw access tokens, or provider credential payloads. The transport verifies the Ed25519 proof before asking the adapter to activate a Bridge and inserts only the token hash in the same transaction.

Atomic activation

consume_and_activate owns one asyncpg transaction:

  1. lock the project-scoped Bridge identity with SELECT ... FOR UPDATE;
  2. lock the project-scoped challenge with SELECT ... FOR UPDATE;
  3. reject missing, mismatched, revoked, non-pending, consumed or expired state;
  4. set consumed_at exactly once;
  5. activate the pending identity and bind the allowed account references;
  6. commit both writes together.

If activation fails, the transaction rolls back the challenge consumption. A second request cannot consume the same challenge after the first successful activation because the identity is no longer pending and the row locks serialize concurrent transactions.

The adapter fences every lookup and update with project_id. A Bridge ID or challenge from another project is not visible through this contract. The bootstrap credential carries approved account references; the Bridge cannot choose those references in its request.

Rollout boundary

Migrations 013_bridge_identities.sql, 014_bridge_enrollment_challenges.sql, and 015_bridge_enrollment_transport.sql are additive. No production Bridge is activated in this local task. The exact HTTP contract is documented in Bridge enrollment HTTP contract.