mirror of
https://github.com/openai/codex.git
synced 2026-04-25 07:05:38 +00:00
## Why Clients need a stable app-server protocol surface for enrolling a local device key, retrieving its public key, and producing a device-bound proof. The protocol reports `protectionClass` explicitly so clients can distinguish hardware-backed keys from an explicitly allowed OS-protected fallback. Signing uses a tagged `DeviceKeySignPayload` enum rather than arbitrary bytes so each signed statement is auditable at the API boundary. ## What changed - Added v2 JSON-RPC methods for `device/key/create`, `device/key/public`, and `device/key/sign`. - Added request/response types for device-key metadata, SPKI public keys, protection classes, and ECDSA signatures. - Added `DeviceKeyProtectionPolicy` with hardware-only default behavior and an explicit `allow_os_protected_nonextractable` option. - Added the initial `remoteControlClientConnection` signing payload variant. - Regenerated JSON Schema and TypeScript fixtures for app-server clients. ## Stack This is PR 1 of 4 in the device-key app-server stack. ## Validation - `just write-app-server-schema` - `cargo test -p codex-app-server-protocol`
165 lines
5.3 KiB
JSON
Generated
165 lines
5.3 KiB
JSON
Generated
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"definitions": {
|
|
"DeviceKeySignPayload": {
|
|
"description": "Structured payloads accepted by `device/key/sign`.",
|
|
"oneOf": [
|
|
{
|
|
"description": "Payload bound to one remote-control controller websocket `/client` connection challenge.",
|
|
"properties": {
|
|
"accountUserId": {
|
|
"type": "string"
|
|
},
|
|
"audience": {
|
|
"$ref": "#/definitions/RemoteControlClientConnectionAudience"
|
|
},
|
|
"clientId": {
|
|
"type": "string"
|
|
},
|
|
"nonce": {
|
|
"type": "string"
|
|
},
|
|
"scopes": {
|
|
"description": "Must contain exactly `remote_control_controller_websocket`.",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"type": "array"
|
|
},
|
|
"sessionId": {
|
|
"description": "Backend-issued websocket session id that this proof authorizes.",
|
|
"type": "string"
|
|
},
|
|
"targetOrigin": {
|
|
"description": "Origin of the backend endpoint that issued the challenge and will verify this proof.",
|
|
"type": "string"
|
|
},
|
|
"targetPath": {
|
|
"description": "Websocket route path that this proof authorizes.",
|
|
"type": "string"
|
|
},
|
|
"tokenExpiresAt": {
|
|
"description": "Remote-control token expiration as Unix seconds.",
|
|
"format": "int64",
|
|
"type": "integer"
|
|
},
|
|
"tokenSha256Base64url": {
|
|
"description": "SHA-256 of the controller-scoped remote-control token, encoded as unpadded base64url.",
|
|
"type": "string"
|
|
},
|
|
"type": {
|
|
"enum": [
|
|
"remoteControlClientConnection"
|
|
],
|
|
"title": "RemoteControlClientConnectionDeviceKeySignPayloadType",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"accountUserId",
|
|
"audience",
|
|
"clientId",
|
|
"nonce",
|
|
"scopes",
|
|
"sessionId",
|
|
"targetOrigin",
|
|
"targetPath",
|
|
"tokenExpiresAt",
|
|
"tokenSha256Base64url",
|
|
"type"
|
|
],
|
|
"title": "RemoteControlClientConnectionDeviceKeySignPayload",
|
|
"type": "object"
|
|
},
|
|
{
|
|
"description": "Payload bound to a remote-control client `/client/enroll` ownership challenge.",
|
|
"properties": {
|
|
"accountUserId": {
|
|
"type": "string"
|
|
},
|
|
"audience": {
|
|
"$ref": "#/definitions/RemoteControlClientEnrollmentAudience"
|
|
},
|
|
"challengeExpiresAt": {
|
|
"description": "Enrollment challenge expiration as Unix seconds.",
|
|
"format": "int64",
|
|
"type": "integer"
|
|
},
|
|
"challengeId": {
|
|
"description": "Backend-issued enrollment challenge id that this proof authorizes.",
|
|
"type": "string"
|
|
},
|
|
"clientId": {
|
|
"type": "string"
|
|
},
|
|
"deviceIdentitySha256Base64url": {
|
|
"description": "SHA-256 of the requested device identity operation, encoded as unpadded base64url.",
|
|
"type": "string"
|
|
},
|
|
"nonce": {
|
|
"type": "string"
|
|
},
|
|
"targetOrigin": {
|
|
"description": "Origin of the backend endpoint that issued the challenge and will verify this proof.",
|
|
"type": "string"
|
|
},
|
|
"targetPath": {
|
|
"description": "HTTP route path that this proof authorizes.",
|
|
"type": "string"
|
|
},
|
|
"type": {
|
|
"enum": [
|
|
"remoteControlClientEnrollment"
|
|
],
|
|
"title": "RemoteControlClientEnrollmentDeviceKeySignPayloadType",
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"accountUserId",
|
|
"audience",
|
|
"challengeExpiresAt",
|
|
"challengeId",
|
|
"clientId",
|
|
"deviceIdentitySha256Base64url",
|
|
"nonce",
|
|
"targetOrigin",
|
|
"targetPath",
|
|
"type"
|
|
],
|
|
"title": "RemoteControlClientEnrollmentDeviceKeySignPayload",
|
|
"type": "object"
|
|
}
|
|
]
|
|
},
|
|
"RemoteControlClientConnectionAudience": {
|
|
"description": "Audience for a remote-control client connection device-key proof.",
|
|
"enum": [
|
|
"remote_control_client_websocket"
|
|
],
|
|
"type": "string"
|
|
},
|
|
"RemoteControlClientEnrollmentAudience": {
|
|
"description": "Audience for a remote-control client enrollment device-key proof.",
|
|
"enum": [
|
|
"remote_control_client_enrollment"
|
|
],
|
|
"type": "string"
|
|
}
|
|
},
|
|
"description": "Sign an accepted structured payload with a controller-local device key.",
|
|
"properties": {
|
|
"keyId": {
|
|
"type": "string"
|
|
},
|
|
"payload": {
|
|
"$ref": "#/definitions/DeviceKeySignPayload"
|
|
}
|
|
},
|
|
"required": [
|
|
"keyId",
|
|
"payload"
|
|
],
|
|
"title": "DeviceKeySignParams",
|
|
"type": "object"
|
|
} |