Files
VerseVDI-Protocol/openspec/specs/native-session-tunnel-credentials/spec.md
T
sechmachine afcd5d99db
Verify Protocol / module (push) Successful in 1m13s
Verify Protocol / verify (push) Successful in 35s
feat(protocol): define native session credentials
2026-08-11 18:38:19 +07:00

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 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