Skip to content

Bridge iOS companion boundary

Status: local 0.0.4 implementation proposal and testable skeleton.

Scope

The iOS companion is a notification client for the existing Bridge. It is not an alternative project store, an agent runtime, or a place to persist source code. The iPhone owns the notification permission and APNs device lifecycle; the server owns project authorization, encrypted token storage and delivery policy.

The first release includes:

  1. OAuth 2.1 Authorization Code with PKCE through the system browser.
  2. Keychain storage for the short-lived access token, refresh token and local device id.
  3. Explicit APNs environment (production in Release, development in Debug).
  4. Registration, preferences, and revocation against the Bridge API.
  5. Safe UI states that never render access tokens, refresh tokens, APNs device tokens, or authorization headers.

Apple Watch is intentionally covered by iPhone notification mirroring. A watchOS target is not part of this boundary.

OAuth and binding

The app uses a registered public client id and the redirect URI eu.heyaira.bridge://oauth/callback. Each authorization request includes a fresh PKCE verifier, S256 challenge, state, and the HeyAira MCP resource. The callback state is checked before code exchange. The app has no client secret.

The Bridge API receives only the OAuth access token over TLS. The server validates the token hash, resource, expiry, revocation state and bound instance before resolving the project actor. This prevents a mobile client from selecting a project by request body alone.

Mobile API lifecycle

permission -> OAuth/PKCE -> APNs registration
    -> POST /bridge/v1/mobile/devices
    -> PUT  /bridge/v1/mobile/devices/{id}/preferences
    -> POST /bridge/v1/mobile/devices/{id}/revoke

The raw APNs token is held in memory only for the registration request. The server-side mobile token vault stores the encrypted token. Sign-out revokes the server record and deletes the local device id and OAuth tokens.

Verification boundary

The local contract tests are deterministic and use synthetic configuration. They verify the source-level security boundary and endpoint contract. A real Xcode build, device registration, APNs delivery, TestFlight upload and App Store release require a host with Xcode, an explicitly registered OAuth client, Apple signing access and a separate deployment authorization. None of those credentials or external side effects belong in this repository or in a work receipt.