Security architecture
Private keys are generated and used only inside the isolated key service; API requests pass a fail-closed policy engine; tenants are isolated at four layers.
Architecture Overview
Qpher is built as a microservices platform with clear security boundaries. The API Gateway handles authentication and rate limiting before routing requests to internal services. Private key operations are confined to the KMS-Orchestrator service, which is the only component with access to key material. All inter-service calls are authenticated (a Google-signed identity token, a Qpher service token, or both), and every request carries tenant context for isolation enforcement.
Cryptographic Foundation
Qpher's post-quantum operations run on liboqs, the Open Quantum Safe project's open-source C library; we do not implement cryptographic primitives ourselves. Through liboqs, Qpher implements NIST FIPS 203 (ML-KEM-768 and the category 5 ML-KEM-1024) for key encapsulation, FIPS 204 (ML-DSA-65 and the category 5 ML-DSA-87) for digital signatures and FIPS 205 (SLH-DSA) for hash-based signatures. Our cryptographic module has not been validated by NIST's CMVP. The liboqs version and its source checksum are pinned in every image build.
Hybrid PQC + Classical Cryptography
Qpher offers post-quantum-only and hybrid modes. A hybrid mode pairs a post-quantum algorithm with a classical one, so breaking either one alone is not enough: X-Wing (X25519 + ML-KEM-768), based on an IETF CFRG draft, for key encapsulation, and a composite ECDSA P-256 + ML-DSA-65 signature, based on an IETF LAMPS draft with Qpher's own encoding (verified through Qpher). Qpher Vault wraps each new document key with X-Wing and signs with the composite signature by default.
Non-Exportable Keys
Private keys are generated inside the KMS-Orchestrator, an isolated key service, and only that service uses them. No API endpoint, administrative interface, or internal service can export private key material. The database stores a key handle (a reference to the encrypted key file), never the key bytes themselves. All cryptographic operations requiring the private key — decryption and signing — are performed within the KMS-Orchestrator and the result is returned to the calling service.
Encryption at Rest
In the key service's storage, each private key is encrypted by a key held in Google Cloud KMS; Qpher stores only the ciphertext, and the Cloud KMS key never leaves Cloud KMS. Backup copies made before this scheme was introduced in May 2026 are encrypted with AES-256-GCM under a key kept in Google Secret Manager.
Application-Level Tenant Isolation
Qpher uses a shared database with strict application-level tenant isolation enforced through four layers: (1) TenantScopedRepository base class that injects tenant_id into every query, (2) database-level CHECK constraints and composite unique indexes, (3) ServiceContext propagation ensuring tenant_id flows through all internal calls, and (4) API Gateway injection of tenant_id from the authenticated API key — tenant_id is never derived from user input.
API Policy Engine
Requests to the Qpher API pass a dedicated policy engine before they reach the target service. The engine applies a first-deny-wins rule chain — plan restrictions, quota limits and method-level access controls — and the API gateway fails closed: if the engine cannot be reached, the request is denied. Requests from the Qpher Vault app are authorized by the Vault service itself.
Multi-Factor Authentication
Qpher supports multi-factor authentication in Qpher Portal and in the Qpher Vault app: a TOTP authenticator (RFC 6238) with ten single-use recovery codes, and email OTP only as a last-resort fallback after two failed attempts with the primary factor. SMS is deliberately not supported (NIST SP 800-63B restricts it; SIM-swap risk). An organization owner or admin on a paid plan can require MFA for every member once the organization has a Vault team; after a grace period (7 days by default), members who have not enrolled must enroll before they can continue, in Qpher Portal and in the Qpher Vault app. MFA is set up separately for Qpher Portal and for Qpher Vault.
Step-Up Re-Verification
Sensitive actions — password change, API key rotation, team-member removal, subscription checkout or cancel, and PQC key rotation — require a second proof of presence taken immediately before the action, even inside an already-authenticated session. The user enters their TOTP code (or current password if MFA is not enabled) and receives a short-lived, single-use step-up token carried as the X-Step-Up-Token header on the sensitive request. This reduces the blast radius if a session cookie is ever compromised: the stolen session alone cannot rotate a key, remove a teammate, or change the password. API-key integrations bypass step-up by design — API keys are already the highest-trust credential and do not gain meaningfully from a second factor at that tier.
Encryption in Transit
All external traffic to Qpher uses TLS; TLS 1.3 is negotiated with clients that support it. 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. API keys travel in request headers over HTTPS and are never put in URLs or query strings.