Skip to content

Credential broker boundary

The Bridge architecture uses OpenBao as the only secret store. HeyAira owns the provider-account metadata and the authorization decision, but it does not own raw OAuth refresh tokens, API keys, provider files, or other secret material.

Scope

Every credential lease is bound to all of these values:

  • HeyAira project;
  • provider and provider account;
  • Bridge and device;
  • provider session;
  • credential reference and immutable version;
  • a short expiry time.

The Bridge identity must be authorized for the project, device, and account before OpenBao material can be delivered. The OpenBao policy is read-only and is generated for the exact project/account/reference/version path. A policy must never contain a secret value.

Portability

Credentials marked portable may be brokered to another authorized Bridge when the provider supports that mode. Credentials marked device_bound must remain on their bound device. The broker rejects a request that attempts to copy device-bound provider CLI state to another Mac; it does not silently pretend that the provider session is portable.

Lease and revocation rules

The broker issues only short-lived lease metadata to the Bridge. Secret material is read from OpenBao only while the lease is active and is held by the runtime ephemerally. Explicit lease revocation, credential revocation, expiry, project mismatch, account mismatch, device mismatch, and stale Bridge identity all prevent further reads.

The durable audit record contains operation, project, provider, account, device, session, credential reference/version, lease ID, result, reason code, and timestamp. It never contains the secret, the response body, or a secret derived from either.

Current implementation boundary

src/heyaira/credential_broker.py is the provider-neutral domain contract. It includes a deterministic InMemoryOpenBaoFixture for tests only. The fixture is not a production vault and must not be enabled by deployment configuration. The next implementation slice will add a real OpenBao adapter and authenticated Bridge identity registration after the contract is reviewed.

The current task intentionally does not add ProviderAccount CRUD, AgentProfile, SessionPlan, session leases, task dispatch, or Bridge transport. Those depend on this boundary and are separate tasks.

OpenBao KV adapter contract

The adapter reads one OpenBao KV v2 path per request:

/v1/<mount>/data/heyaira/<project>/<provider>/<account>/<credential-ref>/v<version>

The response must contain a base64-encoded payload at data.data.payload. The decoded bytes are returned only as ephemeral runtime material. The adapter calls an injected short-lived token provider for every read and sends that token in the X-Vault-Token header; it never caches, returns, logs, or places the token in an exception. An optional namespace is sent as X-Vault-Namespace.

HTTP failures and malformed responses map to stable errors without including the response body. The adapter has deterministic transport tests and does not connect to production OpenBao until a separately reviewed Bridge identity and policy rollout exists.

Operational limits and rollback

This slice is library and contract code only. It does not change the running OpenBao instance, production policies, database migrations, or deployed containers. Rollback is a normal Git revert or release rollback before any future adapter is activated. A production rollout must first pass live negative tests for project, account, device, expiry, and revocation scope.