Platform Public Key
Fetch the platform master key before encrypting a document — required for DEK wrapping so the secure enclave can process your upload.
Before you can upload an encrypted document, you need one half of a two-lock safe: the enclave's public key. You hold your personal key; the enclave holds its private key; the server holds neither. This page explains what to fetch, why, and how to cache it.
What The Platform Master Key Is
The Platform Master Key (PMK) is an asymmetric key pair that lives entirely inside the secure enclave. Its private half never leaves the hardware — it cannot be exported, read by server operators, or accessed outside the attested enclave environment.
Think of the DEK wrapping operation as a sealed courier pouch. You lock the pouch with the enclave's padlock (the PMK public key) before handing it to the server. The server carries the pouch but cannot open it. Only the enclave — the only entity that holds the matching private key — can unseal it.
The public portion of this key is what you fetch from this endpoint.
Attestation and the PMK. Before the enclave can expose the PMK, the key management service verifies that the enclave binary matches the expected measurements (PCR values). The enclave can only access its private key after passing this attestation check. The public key you receive is therefore bound to a specific, verified enclave build — not just to whoever is running the server.
The PMK is distinct from your personal master key (UMK). Your UMK is derived from your password and stays on your device. The PMK is hardware-protected by the key management service and accessible only inside the attested enclave. See Key Hierarchy for the full picture.
Why You Fetch It Before Encrypting
When you upload a document, your client generates a random Document Encryption Key (DEK) and encrypts the document with it. Before you can send anything to the server, you must wrap that DEK twice:
- With your UMK — so you can decrypt the document later without the enclave.
- With the PMK public key — so the enclave can unwrap the DEK, verify the document, generate a tamper-evident seal, and create search index tokens.
The wrapped_dek_pmk field in the document creation request carries this second wrapped copy. Without it, the enclave cannot process your document and it will remain in pending_ocr state indefinitely.
This fetch is Step 1 of the upload flow. See Document Upload for the full seven-step sequence.
The Hybrid Scheme
The PMK uses a hybrid key encapsulation scheme that pairs two algorithms:
| Component | Algorithm | Role |
|---|---|---|
| Classical | ECC NIST P-256 | Key encapsulation using established cryptography |
| Post-quantum | ML-KEM-1024 | Key encapsulation resistant to quantum attacks |
Both algorithms must be broken simultaneously for an attacker to recover the DEK. This "harvest now, decrypt later" protection means documents wrapped today remain private even against a future adversary with a capable quantum computer.
The ecc_public_key field in the response carries the classical ECC portion. Your device uses it to perform ECDH key agreement and wrap the DEK; the secure enclave reverses this using its hardware-protected private key during document processing.
What your device does with ecc_public_key:
- Decode the base64 value to recover the raw NIST P-256 public key bytes.
- Perform ECDH key agreement between the decoded point and an ephemeral private key you generate.
- Derive a wrapping key from the shared secret using HKDF-SHA256.
- Wrap the DEK using the derived wrapping key with AES-256-GCM authenticated encryption.
- Encode the wrapped DEK as base64 and submit it as
wrapped_dek_pmkin Step 4 of the upload flow.
The secure enclave reverses this: it uses its P-256 private key via the key management service to reproduce the shared secret, re-derives the wrapping key, and unwraps the DEK.
Where This Fits In The Upload Flow
Fetching the PMK public key is Step 1 of the seven-step upload flow. You cannot complete Step 3 (encrypt your document) without it, because wrapped_dek_pmk is a required field in Step 4 (create the document record).
Step 1 GET /v1/public-keys/server ← this page
Step 2 POST /v1/documents/reservations
Step 3 [client-side encryption]
Step 4 POST /v1/documents
Step 5 PUT /v1/documents/{id}/content
Step 6 Poll /v1/documents/{id}
Step 7 POST /v1/searchThe key can be cached across multiple uploads. You do not need to re-fetch it for every document — only when you detect a rotation (see Caching below).
The Request
No authentication required. No request body.
curl https://api.kyndex.co/v1/public-keys/serverResponse
200 OK
{
"key_id": "pmk-prod-2025-01",
"key_spec": "ECC_NIST_P256",
"ecc_public_key": "QkdQdWJsaWNLZXlCYXNlNjRFbmNvZGVkRXhhbXBsZQ==",
"algorithm": "hybrid",
"description": "Platform Master Key for DEK wrapping (classical ECC portion)"
}Response Fields
| Field | Type | Description |
|---|---|---|
key_id | string | Stable identifier for this key version. Changes on PMK rotation. |
key_spec | string | Algorithm for the ECC key portion. Currently ECC_NIST_P256. |
ecc_public_key | string (base64) | The classical ECC public key. Use this to wrap your DEK. |
algorithm | string | Always hybrid — indicates the platform's hybrid classical + post-quantum scheme. |
description | string | Human-readable description of this key's role. |
Using key_id in your client. Cache the entire response object keyed by key_id. When you wrap a DEK, record which key_id you used — this lets you invalidate only the affected cache entry on rotation rather than dropping all cached state. The server does not return key_id in the document creation response, so your client must track the association locally between wrapped DEKs and the key_id active at wrap time.
Caching
The server responds with Cache-Control: public, max-age=86400. The PMK rotates approximately once per year — caching it for 24 hours is safe and reduces round-trips on every upload.
Recommended implementation:
on startup:
fetch GET /v1/public-keys/server
store { key_id, ecc_public_key, fetched_at }
before each DEK wrap:
if (now - fetched_at) > 86400s → re-fetch and update cache
use cached ecc_public_key
on document creation 400 with KEY_VERSION_MISMATCH:
evict cache
re-fetch GET /v1/public-keys/server
re-wrap DEK with new key
retry document creationHow to detect rotation:
When the PMK rotates, the server purges the CDN cache and begins serving a response with a new key_id. Your client should detect a rotation in one of two ways:
- Cache miss or stale TTL — your 24-hour cached key expired and you re-fetched automatically.
wrapped_dek_pmkrejection — the server returns a400with error codeKEY_VERSION_MISMATCHon document creation. Evict your cached key, re-fetch, and re-wrap your DEK before retrying.
Do not hard-code a specific key_id or public key bytes. Always store the full response and
compare key_id values across fetches to detect rotation. A mismatch means re-fetch before
wrapping.
Error Responses
All errors follow RFC 7807 Problem Details with Content-Type: application/problem+json.
| Status | Error Code | When |
|---|---|---|
429 | RATE_LIMITED | Too many requests from this IP. Back off and retry. |
500 | KEY_FETCH_FAILED | Key management service unavailable — the secure enclave must pass attestation before it can return the key. Retry with exponential backoff. |
A 500 from this endpoint is always transient. The enclave boots and re-attests on startup; requests during that window will fail until attestation completes (typically a few seconds).
Related
- Document Upload — Step 1 of the upload flow uses this endpoint directly.
- Key Hierarchy — Full cryptographic context: how the PMK fits into personal keys, organization keys, and the hardware trust boundary.
- Enclave Architecture — How attestation works and what PCR values guarantee about the enclave binary.
- Encryption Guarantees — The hybrid classical + post-quantum scheme applied throughout the platform.