Skip to content

Open a post-quantum (ML-KEM) session

Establish a session key with a post-quantum key encapsulation mechanism, so that request and response bodies travel encrypted under it in addition to TLS.

Who can do it

Any client. The handshake needs no token: it runs before sign-in, and the session it opens is then used by the token request and by authenticated calls.

Before you start

  • Choose a KEM the deployment admits. GET /api/v3/pqc-handshake/supported-algorithms lists them; the SDK uses ML-KEM-768 unless told otherwise.
  • Plan for the streaming and interoperability operations: they are never sent under the session key, and a streaming request that carries the session headers is refused.

Steps

  1. With the Java SDK, turn the transport on in the properties you pass to AnkaSecureSdk: pqc.transport.enabled=true and, optionally, pqc.kem.algorithm=<KEM> (default ML-KEM-768) and pqc.session.ttl.seconds (default 600: the SDK reuses a session for that many seconds after it opened it, then performs a new handshake). A KEM the SDK does not support is refused when the SDK is built, before any request. The SDK then performs the handshake, encrypts every request that has a body (the token request included) and decrypts the responses; streaming, interoperability and handshake requests, and requests without a body, are sent unchanged.
  2. With the crypto CLI, set the same properties in its configuration file, ~/.ankasecure-crypto/config.properties unless --config-path names another. A file written by AnkaSecureCLI init already carries them, with the transport off. The CLI passes the whole file to the SDK, which applies them as above; AnkaSecureCLI view-session shows PQC Transport: Enabled and the KEM it resolves, or names the supported KEMs when the configured one is not among them. With the transport on, use the explicit streaming commands (such as encrypt-file-stream) for large files.
  3. Over the API, generate a key pair for the chosen KEM and call POST /api/v3/pqc-handshake/init with {"clientPublicKeyBase64": "<public key>", "algorithm": "ML-KEM-768"}. The answer carries ciphertextBase64 and sessionId. Decapsulate the ciphertext with your private key to obtain the AES-256 session key, then send each request with X-PQC-Transport: true and X-PQC-Session: <sessionId> and its body encrypted under that key. The body format is described in PQC transport in the SDK.
  4. Use the session within 5 minutes. A new session expires then unless a request that proves an identity, an authenticated call or the token request, uses it first; that first use extends it to 4 hours.

What you see when it worked

The handshake answers 200 with ciphertextBase64 and sessionId. Encrypted calls answer with an encrypted body that the session key opens. A refusal written before the transport layer could encrypt anything, such as a lost session, arrives as a plain application/problem+json.

If it fails

What you see Cause What to do
400 The body is missing or not valid JSON, or the public key is missing, oversized, invalid or not a key of the requested algorithm, or the algorithm is not one the deployment lists Send a public key of a listed algorithm
415 unsupported-media-type The request is not application/json Send JSON
503 .../errors/pqc-session-capacity with Retry-After The deployment holds its maximum number of pending sessions; no key exchange ran Retry the whole handshake after the interval
503 dependency-not-ready with Retry-After A platform dependency is temporarily unavailable; no session exists Retry the whole handshake after the interval
400 with extensions.code pqc.session.notfound on a later call The server no longer holds the session Open a new session; the SDK does this once on its own and resends the request
400 .../errors/pqc-transport-not-available-for-streaming A streaming request was sent with the session headers Resend it without them; TLS already protects it

Without the console

The handshake has no console screen.

Surface How
Java SDK pqc.transport.enabled, pqc.kem.algorithm and pqc.session.ttl.seconds in the properties passed to AnkaSecureSdk
Crypto CLI The same properties in the CLI configuration file (~/.ankasecure-crypto/config.properties by default); AnkaSecureCLI view-session shows the transport state
API POST /api/v3/pqc-handshake/init (operation initializeHandshake)