System-Managed Edge Proxy
Learn how the Edge Proxy abstracts auth resolution, PKMS encryption, and compatibility webhooks while preserving a zero-knowledge trust model.
The omni-edge-proxy is the contract layer in front of the upstream gateway.
It resolves user auth, transparently encrypts or decrypts PKMS payloads when a client
key is available, and preserves the upstream API as the stable interface for clients.
This middleware acts as a secure, standalone proxy between client frontends and the central gateway. It also encapsulates user token exchange and key-escrow flows, offering a drop-in replacement for the legacy webhook flows (Flow A/B).
The Trust Model
Even though the proxy handles encryption, the upstream gateway remains zero-knowledge:
- The developer manages a
SERVER_MASTER_KEYsecurely inside the proxy environment. - The proxy generates or recovers a unique Client Key for each user.
- The proxy encrypts the Client Key using the
SERVER_MASTER_KEYand escrows it in the configured store. - The upstream gateway only ever sees encrypted PKMS payloads. Without the
SERVER_MASTER_KEY, Omni cannot read user documents.
Authentication Resolution
Client requests should send Authorization: Bearer <token>.
For PKMS routes that need a client key, the proxy resolves tokens in this order:
mock-token-*- local testing shortcut; the suffix becomes the user id.llm_ovh_sk_test_mock*- local test API key shortcut.omni_dev_mock*- local developer token shortcut.llm_ovh_sk_live_*andllm_ovh_sk_test_*- validated by the core-config API key verification endpoint.omni_dev_*- validated by the core-config developer token verification endpoint.- Anything else - verified as a Firebase ID token using
FIREBASE_PROJECT_ID.
The webhook sync routes below are stricter: they always require Firebase ID tokens.
Compatibility Webhooks
The Edge Proxy keeps two legacy webhook routes alive for compatibility:
Flow A (Sync / Key Restoration)
- Endpoint:
POST /api/v1/webhooks/r1xG2bFatcOoQS0A28AQZ/sync - Purpose: Verifies the Firebase ID token, resolves the user session, and returns the escrowed Client Key wrapped inside the caller's temporary public key when provided.
- Response:
{ secret, userId, status, profile, wrapped_key, debug_log }
Flow B (Onboarding & Key Escrow)
- Endpoint:
POST /api/v1/webhooks/E6K9u35uZUEIJVnp2NivP/sync - Purpose: Verifies the Firebase ID token, validates the username, optionally encrypts the user's Client Key under the
SERVER_MASTER_KEY, and saves the profile. - Request:
{ userName, display_name, age, clientKey }
Deployment Configuration
Self-hosted developers can run the proxy completely database-less by using the memory store or Cloudflare Workers KV bindings.
Set the following environment variables:
STORAGE_PROVIDER: Set tomemory(default),kv, orappwrite.OMNI_SECRETS_KV: Cloudflare KV namespace binding used whenSTORAGE_PROVIDER=kv.SERVER_MASTER_KEY: High-entropy 32-byte secret key used to secure client keys in escrow.FIREBASE_PROJECT_ID: The project ID of your Firebase app.APPWRITE_ENDPOINT/APPWRITE_PROJECT_ID/APPWRITE_API_KEY/DATABASE_ID/USERS_COLLECTION_ID/SECRETS_COLLECTION_ID/USERNAMES_COLLECTION_ID: Required only whenSTORAGE_PROVIDER=appwrite.LLM_GATEWAY_URL: Upstream gateway base URL. Defaults tohttps://api.llm.ovhwhen omitted.CORE_CONFIG: Optional injected fetch binding for local verification against core-config.
Plaintext Ingestion (Reverse Proxy Mode)
When running the Edge Proxy locally or in your own Cloudflare environment, you can send plaintext PKMS payloads to the proxy and let it perform the encryption translation before forwarding the request upstream.
How to use the Plaintext Ingestion API
Point your request to your local proxy port (e.g., http://localhost:8787 or your deployed proxy URL) instead of the main gateway.
1. Ingest a Plaintext Note
Send a POST request to /v1/workspaces/:workspaceId/notes with a plaintext body:
curl -X POST http://localhost:8787/v1/workspaces/ws-123/notes \
-H "Authorization: Bearer <your_token>" \
-H "Content-Type: application/json" \
-d '{
"documentPayload": {
"title": "Meeting Notes",
"type": "document"
},
"blocksPayload": [
{
"id": "block-1",
"type": "text",
"content": "Met with team, E2EE proxy works."
}
],
"markdown": "# Meeting Notes\nMet with team, E2EE proxy works.",
"indexableBlocks": [
{
"id": "block-1",
"type": "text",
"content": "Met with team, E2EE proxy works."
}
],
"documentType": "document"
}'The proxy intercepts this request, automatically generates or retrieves your user Client
Key, encrypts documentPayload, blocksPayload, and markdown, leaves
indexableBlocks plaintext, and forwards the transformed body upstream. A notebook
registry write uses the same pattern but wraps the full body in { "ciphertext": "..." }.
2. Encrypted payload shape
Sensitive note fields are wrapped like this:
{
"format": "omni.om.encrypted",
"ciphertext": "..."
}markdown is encrypted as a ciphertext string rather than an envelope object.
3. Readback behavior
Readback decryption is now explicitly header-gated. Clients must send:
X-Proxy-Decrypt: trueThe proxy will prefer X-Client-Key when provided and otherwise fall back to the authenticated user's escrowed client key. Without X-Proxy-Decrypt: true, or when no client key can be resolved, note list and note detail responses are returned unchanged as stored ciphertext.