Omni Docs
Core Concepts

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:

  1. The developer manages a SERVER_MASTER_KEY securely inside the proxy environment.
  2. The proxy generates or recovers a unique Client Key for each user.
  3. The proxy encrypts the Client Key using the SERVER_MASTER_KEY and escrows it in the configured store.
  4. 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:

  1. mock-token-* - local testing shortcut; the suffix becomes the user id.
  2. llm_ovh_sk_test_mock* - local test API key shortcut.
  3. omni_dev_mock* - local developer token shortcut.
  4. llm_ovh_sk_live_* and llm_ovh_sk_test_* - validated by the core-config API key verification endpoint.
  5. omni_dev_* - validated by the core-config developer token verification endpoint.
  6. 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.

Initializing Diagram Engine...

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 to memory (default), kv, or appwrite.
  • OMNI_SECRETS_KV: Cloudflare KV namespace binding used when STORAGE_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 when STORAGE_PROVIDER=appwrite.
  • LLM_GATEWAY_URL: Upstream gateway base URL. Defaults to https://api.llm.ovh when 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: true

The 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.

On this page