Skip to main content

Security Architecture

This page describes how requests reach Qpher's services, where private keys are used and stored, how tenants are separated, and what happens when a component fails.

Core Guarantee

Private keys are generated and used only inside the isolated key service (KMS-Orchestrator); API requests pass a policy engine that fails closed.

Service Diagram​

Qpher uses a microservices architecture. Calls between Qpher services also go over HTTPS and are authenticated with a Google-signed identity token checked by Cloud Run, a Qpher service token, or both.

The KMS-Orchestrator is the service that loads private keys. The API Gateway routes KEM, signature and key-management calls to it. Qpher Vault and Qpher Legacy requests are authorized by vault-backend, which calls the KMS-Orchestrator directly, not through the API Gateway. The KMS-Orchestrator returns the results of operations — ciphertexts, plaintexts, signatures, shared secrets and unwrapped keys — never a private key.

Gateway Auth Pipeline​

Every API request passes through a 7-stage authentication and authorization pipeline before reaching any backend service.

StageWhat HappensOn Failure
1. Skip checkThe health endpoint, public sign-in and sign-up endpoints, and webhooks (verified separately) skip API-key authentication--
2. Extract API keyRead the x-api-key header401 Missing API key
3. Resolve tenantHash the key and look up the tenant401 Invalid API key
4. Inject contextAttach X-Tenant-ID and X-Request-ID headers--
5. Rate limitCheck per-tenant rate limits via Redis429 Rate limit exceeded
6. Policy checkEvaluate access rules in the Policy Engine403 Access denied
7. RouteForward the request to the appropriate service--

Every request that carries an API key passes all seven stages before it reaches a backend service.

Private Keys Are Used Only Inside the KMS-Orchestrator​

The most important security boundary in Qpher is the KMS-Orchestrator, the isolated key service:

  • Private keys are generated inside the KMS-Orchestrator, and no API returns them.
  • In production, each private key is encrypted by a key held in Google Cloud KMS before it is stored (see Encryption at Rest).
  • The database stores a handle (a reference path), not the key bytes themselves.
  • There is no API endpoint to export or download a private key.

When you call /kem/decrypt or /signature/sign, the API Gateway forwards your request to the KMS-Orchestrator, which loads the private key, performs the operation, and returns only the result.

Tenant Isolation​

Qpher is a multi-tenant platform. Each customer gets a separate tenant, isolated at four layers: repository filtering, database constraints, request context and gateway enforcement.

  1. Repository layer -- Every database query includes a tenant_id filter.
  2. Database constraints -- Unique indexes are scoped to (tenant_id, ...), preventing data collisions between tenants.
  3. Context propagation -- The gateway injects X-Tenant-ID into every downstream request. Services never derive the tenant ID from user input.
  4. Gateway enforcement -- The API key lookup determines the tenant. A tenant can only access resources associated with their own API key.

Fail-Closed Design​

Qpher follows a fail-closed philosophy: when something goes wrong, the system denies access rather than allowing it.

ScenarioBehavior
Policy Engine is unavailableAPI requests are denied (503)
Tenant lookup failsRequest is rejected (401 for an unknown key, 503 if the Tenant Service cannot be reached)
Rate-limit store (Redis) is unavailableThe gateway counts requests per instance, with each limit divided by the number of instances, until Redis returns
Missing configuration at startupService refuses to start
PQC cryptographic operation failsError is returned, never falls back to weaker crypto

This approach means a brief outage can block API requests rather than let them through unchecked.

Cryptographic Foundation — Open Quantum Safe​

Qpher uses liboqs (Open Quantum Safe) for its post-quantum algorithms. Qpher does not implement post-quantum primitives from scratch; it builds on the Open Quantum Safe project's open-source library.

ComponentRole
liboqs (C library)Post-quantum algorithms: ML-KEM (FIPS 203), ML-DSA (FIPS 204) and SLH-DSA (FIPS 205)
liboqs-pythonPython bindings used by the KMS-Orchestrator
ValidationWe implement NIST FIPS 203, 204 and 205; our cryptographic module has not been validated by NIST's CMVP. As of June 2026 the CMVP-validated AWS-LC 3 module (#5298) covers ML-KEM but not ML-DSA.
Why not our own implementation?

Rolling your own cryptography is one of the most common security anti-patterns, so Qpher uses the Open Quantum Safe implementations instead of writing its own.

The liboqs version used in production is pinned and recorded in every Docker image build. The full list of open-source libraries Qpher depends on is published at qpher.ai/legal/open-source.

Hybrid PQC + Classical Cryptography​

Qpher supports two cryptographic modes, giving customers the choice based on their risk tolerance and compliance requirements.

Two Kinds of "Hybrid"​

The term "hybrid" appears in two different contexts in post-quantum cryptography. It is important to understand the distinction:

TermWhat It MeansIn Qpher
KEM-DEM hybridKyber768 (KEM) + AES-256-GCM (DEM) — combining a PQC key exchange with a symmetric cipher for payload encryptionEvery /kem/encrypt call
PQC + classical hybridCombining a PQC algorithm with a traditional algorithm (e.g., X25519 + Kyber768) so that security holds even if one algorithm is brokenOpt-in: algorithm: "X-Wing" or "Composite-ML-DSA"

Qpher's server-side encryption (/kem/encrypt) is KEM-DEM hybrid (see KEM-DEM Hybrid Encryption): each call combines the KEM (ML-KEM-768 by default) with AES-256-GCM.

PQC + Classical Hybrid Mode​

Opt-in hybrid mode

Hybrid PQC + classical algorithms provide defense-in-depth by combining a PQC algorithm with a battle-tested classical algorithm. Add "algorithm": "X-Wing" or "algorithm": "Composite-ML-DSA" to your API requests. Omitting the parameter defaults to PQC-only mode.

Qpher offers hybrid mode that combines PQC algorithms with classical algorithms for defense-in-depth. It is opt-in:

OperationPQC-Only (default)Hybrid (opt-in)
KEMML-KEM-768 (Kyber768)X-Wing: X25519 + ML-KEM-768
SignaturesML-DSA-65 (Dilithium3)Composite-ML-DSA: ECDSA P-256 + ML-DSA-65

Why hybrid matters: PQC algorithms are rigorously standardized but relatively new. Classical algorithms like X25519 and ECDSA have decades of battle-testing. Hybrid mode ensures that even if a breakthrough in lattice cryptanalysis were discovered, the classical component would maintain security. Once PQC algorithms have accumulated more real-world deployment history, PQC-only mode will be the recommended long-term default.

What's Next​