Security
This page consolidates the security claims the landing page makes into one document procurement teams can read in a single sitting. Each item is tagged honestly: shipped means the runtime enforces it today and it's customer-verifiable; partial means it's enforced for the listed scope but has named exclusions; roadmap means committed-direction but not yet shipping.
Data at rest shipped
- HMAC secrets sealed under a per-process Data Encryption Key (DEK) using AES-256-GCM. Sealed envelope is what sits on disk; cleartext lives only on the process stack during a verify operation. A stolen disk yields ciphertext only.
- X25519 per-customer envelope encryption on every audit-log row: row content is encrypted to the customer's public sealing key at write time. We can't decrypt rows we just wrote. Customers receive their X25519 private PEM once at issue time and hold it themselves.
- Hash-chained audit log per
(tenant, app_id). Each row carriesprev_hashandrow_hash; mutation of any historical row breaks the chain visibly. Customers verify their own slice viaGET /v1/auditand can computerow_hashoffline using the published canonical-JSON rule (whitepaper §4). - API key storage: bearer keys are hashed with SHA-256 before persistence; the plaintext is shown to the customer once at issue time and never persisted server-side.
Data in flight shipped
- TLS 1.2+ mandatory for every endpoint, terminated at the Azure Front Door / Container App ingress with a Microsoft-issued certificate.
- HSTS preload declared
(
max-age=63072000; includeSubDomains; preload). - Content-Security-Policy on every HTML response denies inline scripts, restricts form-action to Stripe checkout, and pins frame-ancestors to none.
- No third-party CDN for first-party assets — all customer-facing HTML is served directly from the runtime. Zero third-party JavaScript trackers.
Per-response cryptographic receipts shipped
Every /v1/* response carries two independent receipts that
bind the response to the running build and the audit chain head:
-
HMAC tamper signature — header
X-Cogos-Signature(algorithm inX-Cogos-Signature-Algo, currentlyhmac-sha256). Computed over the canonicalized response body using a per-key shared secret returned to the customer at key issue time. Customer recomputes locally and compares; any divergence proves the response was altered in flight. -
Ed25519 attestation receipt — header
X-Cogos-Attestation(algorithm inX-Cogos-Attestation-Algo, currentlyed25519). A signed token whose payload commits to the request hash, response hash, running build version, and the audit-chain head as of the response. The signing public key is published at /attestation.pub and rotates each container restart; the key ID is in the token. A customer who archives attestations on a cadence can prove later that the chain was not rewritten between two anchor points.
Image supply chain shipped
- cosign-signed container images built by Azure Container Registry. Verification public key is at /cosign.pub.
- Distroless runtime based on
gcr.io/distroless/nodejs20. No shell, no package manager, runs asnonroot(UID 65532), read-only root filesystem ready. - Admission gate rejects container starts whose cosign verification fails. Deploy script is documented as fail-closed; rollback is via revision-deactivate, never force-recreate.
- No third-party hosted LLM in the request path. Inference is substrate-resolved; only first-party infrastructure on the inference path. The single external dependency on the substrate path is the optional live-search provider, declared per-call in the audit row.
Customer authentication shipped
- Bearer keys with the format
sk-cogos-<hex32>. Rotated perPOST /v1/keys/rotatewith a 24-hour grace window; a leaked key auto-quarantines the moment a scanner pattern fires from the same IP within 60 seconds of an authorized hit. - Optional Ed25519 keypair auth — customer
generates a keypair on their side, sends the public key to us,
signs each request with the private key. We hold no
re-usable customer secret. Issuance via the
scheme=ed25519param onPOST /admin/keys.
Runtime hardening shipped
- No
/adminendpoint advertised on the public surface; admin routes are gated byX-Admin-Keyand an explicit allowlist of operator-tier paths. - Rate limiting: per-IP and per-tenant token-bucket
limiters with separate buckets; per-tenant cap reads from the
package
rpm_limitfield so each tier carries its own ceiling. Free tier: 20 RPM. Business: 1,200 RPM. See SLA. - Per-package prompt-size ceiling
(
max_prompt_tokens_per_call) prevents per-request compute-cost abuse independent of monthly quota. - Continuous external probing — a Container App Job runs scheduled probes against this domain daily from a separate region, recording responses for the audit trail.
Key management partial
- Customer-facing keys (bearer secret, HMAC shared secret, X25519 sealing key) are issued once and held by the customer. We do not retain reusable customer auth material at rest after issuance for the ed25519 scheme; bearer scheme stores only the SHA-256 hash.
- Server-side signing keys (per-response Ed25519 attestation keypair) are generated in-process and rotated each container restart. The active public key is at /attestation.pub with the matching kid in the response header.
- Honest gap: we do not yet operate a customer- facing key vault for storing customer secrets in our envelope. If a customer needs key-escrow or HSM-backed storage of their own material, that's an enterprise-contract conversation today.
Compliance roadmap roadmap
The following are committed-direction, not shipping:
- SOC 2 Type I → Type II. Path is named; audit engagement is not yet booked.
- ISO 27001. Sequenced after SOC 2 Type II.
- Evidence packs available before formal audits land — pen-test reports, control-architecture mapping, vendor list, sub-processor list (/sub-processors) are available on inquiry today.
Responsible disclosure
Found a security issue? Email support@5ceos.com with the subject line "Security Disclosure". Include reproduction steps and an estimate of the affected tenants. We acknowledge within 1 business day, triage within 3 business days, and we'll keep you informed through the fix. We do not currently run a paid bug-bounty program; we publicly credit researchers in /trust advisories after the fix ships, with the researcher's permission.