WebSocket API

The WebSocket API provides real-time communication between the Secrets Agent and the Mobile App for secret approval requests.

Connection

EnvironmentURLNotes
Local devws://localhost:8765Default port, configurable
Productionwss://host:portTLS required

Authentication Handshake

The WebSocket connection uses a challenge-response authentication flow with Ed25519 signatures:

  1. Client connects to the WebSocket server
  2. Server sends a challenge message with a 32-byte CSPRNG nonce
  3. Client signs the nonce with its Ed25519 private key
  4. Client sends an auth message with the signature and public key
  5. Server verifies the signature and responds with auth_ok or auth_error
Handshake sequence text
Client                          Server
  |                                |
  |  ←── challenge { nonce }       |
  |                                |
  |  ──→ auth { sig, pubkey }      |
  |                                |
  |  ←── auth_ok / auth_error      |
  |                                |

Server → Client Messages

challenge

Sent immediately after connection. Contains a one-time nonce for authentication.

FieldTypeDescription
typestring"challenge"
noncestring (hex)32-byte CSPRNG nonce, hex-encoded
timestampintegerUnix timestamp (seconds)

auth_ok

Authentication succeeded. Connection is now authorized.

FieldTypeDescription
typestring"auth_ok"
session_idstringUnique session identifier

auth_error

Authentication failed. Connection will be closed.

FieldTypeDescription
typestring"auth_error"
reasonstringError description

secret_request

A secret access request pending user approval.

FieldTypeDescription
typestring"secret_request"
request_idstringUnique request identifier
secret_namestringName of the requested secret
secret_typestringType (PASSWORD, API_KEY, etc.)
tool_namestringTool requesting access
reasonstringContext for the request
durationstringRequested access duration

ping

Keepalive ping. Client must respond with pong.

FieldTypeDescription
typestring"ping"
timestampintegerUnix timestamp

Client → Server Messages

auth

Response to the challenge message.

FieldTypeDescription
typestring"auth"
signaturestring (hex)Ed25519 signature of the nonce
public_keystring (hex)Client's Ed25519 public key

secret_response

User's response to a secret access request.

FieldTypeDescription
typestring"secret_response"
request_idstringMatching request identifier
approvedbooleantrue to approve, false to deny

pong

Keepalive response. Must be sent in reply to ping.

FieldTypeDescription
typestring"pong"

Security

  • Nonce consuming: Each challenge nonce can only be used once. Replay attacks are prevented.
  • Timestamp drift: Nonces older than 30 seconds are rejected.
  • Ed25519 signatures: 32-byte keys, 64-byte signatures. The server verifies the client's public key is registered.
  • TLS mandatory: In production, connections must use wss:// for transport encryption.
  • E2E encryption: Secret values are encrypted with X25519 ECDH + AES-256-GCM between mobile and secrets agent. The WebSocket transport never sees plaintext.

JavaScript Client Example

websocket-client.js javascript
const ws = new WebSocket('ws://localhost:8765');

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  switch (msg.type) {
    case 'challenge':
      // Sign the nonce with Ed25519 private key
      const signature = ed25519Sign(msg.nonce, privateKey);
      ws.send(JSON.stringify({
        type: 'auth',
        signature: signature,
        public_key: publicKeyHex
      }));
      break;

    case 'auth_ok':
      console.log('Authenticated:', msg.session_id);
      break;

    case 'secret_request':
      // Show approval UI to user
      showApprovalDialog(msg);
      break;

    case 'ping':
      ws.send(JSON.stringify({ type: 'pong' }));
      break;
  }
};