4.0 KiB
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
rolesitem 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_atuses 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