# native-session-tunnel-credentials Specification ## Purpose Define server-owned native session identity and short-lived tunnel credential disclosure without accepting client-owned policy. ## Requirements ### Requirement: Client-owned allocation policy is removed by a coordinated wire-version cutover Control wire version `2` SHALL be current, wire version `1` SHALL be n-1, wire version `0` SHALL be n-2, and `control.v2` SHALL identify the current control feature. The wire-version-2 `SessionRequest` MUST reject `policy_snapshot`; `BrokerSession` SHALL retain the Server-owned policy snapshot disclosure. This removal is intentionally incompatible with the wire-version-1 request shape and SHALL require coordinated Protocol, Server, Data Plane, and client pin updates. Declaring wire version `1` as n-1 does not permit a wire-version-1 request body to be decoded as wire version `2`. #### Scenario: Client attempts to supply policy - **WHEN** a session request contains `policy_snapshot` - **THEN** strict Protocol decoding rejects the unknown field #### Scenario: A legacy client presents a wire-version-1 request shape - **WHEN** a client uses the removed client-owned policy field or does not negotiate `control.v2` - **THEN** the wire-version-2 broker request path rejects the request instead of silently interpreting it as compatible ### Requirement: Authentication response shapes are route-specific Browser login and browser session responses SHALL use `BrowserAuthenticatedSession`, which forbids `native_identity`. Native bearer session responses SHALL use `NativeAuthenticatedSession`, which requires a `NativeSessionIdentity` containing both `client_device_id` and `device_key_id`. Both response types SHALL require every `roles` item to contain 1 through 64 UTF-8 bytes. #### Scenario: Native identity is incomplete - **WHEN** a native session response omits either identity field - **THEN** strict Protocol decoding rejects the nested object #### Scenario: Browser response leaks native identity - **WHEN** a browser login or browser session response contains `native_identity` - **THEN** strict Protocol decoding rejects the response #### Scenario: Authentication response has a malformed role - **WHEN** any `roles` item is empty or exceeds 64 UTF-8 bytes - **THEN** every generated binding rejects the response ### Requirement: Native tunnel credentials are non-cacheable `POST /api/v1/auth/tunnel-credentials` SHALL accept only native bearer authentication, no request body, and return a bounded `NativeTunnelCredential` with `Cache-Control: no-store`. `NativeTunnelCredential.expires_at` SHALL be canonical RFC 3339 UTC in every generated binding: an uppercase `T`, a `Z` suffix, and either no fractional seconds or a 1-through-9-digit non-zero-terminated fractional component. #### Scenario: Native client requests tunnel credentials - **WHEN** an authenticated native client calls the endpoint - **THEN** the response identifies the client device and key, supplies certificate and trust PEM, gives an expiry, and cannot be stored #### Scenario: Native tunnel credential uses a noncanonical expiry - **WHEN** `expires_at` uses a numeric offset or a noncanonical fractional representation - **THEN** every generated binding rejects the credential ### Requirement: Swift bindings support the macOS client deployment floor The generated Swift package SHALL declare macOS 14 as its minimum supported macOS platform. #### Scenario: Native client consumes the Swift package - **WHEN** the package manifest is resolved for the Phase 3D macOS client - **THEN** its platform declaration permits macOS 14 and later ### Requirement: Manifest public identity is the TLS server name `ConnectionManifest.gateway.public_identity` SHALL be the exact TLS server name and SHALL remain distinct from dial addresses, gateway UUIDs, certificate fingerprints, and provider identities. #### Scenario: Client connects to a gateway address - **WHEN** a client dials any advertised gateway address - **THEN** it verifies TLS against `gateway.public_identity`