This policy governs when we encrypt, with what, and how we manage keys. Encryption is the implementation detail; this is the policy that implementation must conform to.
Requirement by data classification
Per the Data classification policy:| Classification | At rest | In transit | Additional |
|---|---|---|---|
| Restricted — PHI | AES-256 via CMEK + column-level AR encryption | TLS 1.2+ | PHI scrubbing before LLM/observability egress |
| Confidential | AES-256 via CMEK | TLS 1.2+ | Secrets only in Secret Manager |
| Internal | Encryption at rest inherited from Google Workspace/tool provider | TLS to the tool | — |
| Public | No requirement | TLS (HTTPS) for integrity | — |
Approved algorithms
Symmetric
AES-256-GCM for authenticated encryption (the default for Active Record Encryption and GCP CMEK).
Asymmetric
RSA-2048+ or ECDSA P-256+ for signing. Ed25519 preferred for new signing needs.
Hashing
SHA-256 or SHA-512 for integrity. Argon2id or bcrypt for password storage (Devise uses bcrypt by default).
Transport
TLS 1.2 minimum; TLS 1.3 preferred. SSLv3, TLS 1.0, TLS 1.1 disabled at the load balancer.
Prohibited
- MD5, SHA-1 — not allowed for integrity or signing (still allowed for non-security checksums like ETags).
- DES, 3DES, RC4 — not allowed anywhere.
- Weak RSA (< 2048-bit), DSA, DH with weak parameters.
- Self-signed certificates on any production endpoint.
- Home-rolled crypto — use vetted libraries only.
Key management
Key types
| Key | Purpose | Storage | Rotation |
|---|---|---|---|
| Cloud SQL CMEK | At-rest encryption for Postgres | GCP KMS | Automatic, every 90 days |
| GCS CMEK | At-rest encryption for GCS buckets | GCP KMS | Automatic, every 90 days |
| Memorystore CMEK | At-rest encryption for Redis | GCP KMS | Automatic, every 90 days |
| Terraform state CMEK | At-rest encryption for TF state bucket | GCP KMS | Automatic, every 90 days |
| Active Record primary key | Column-level encryption of PHI | GCP Secret Manager | Manual — requires re-encryption (see below) |
| Active Record deterministic key | Column-level encryption of queryable PHI (e.g. names) | GCP Secret Manager | Manual — requires re-encryption |
| Active Record key-derivation salt | Input to AR encryption KDF | GCP Secret Manager | Manual |
JWT signing key (DEVISE_JWT_SECRET_KEY) | Session JWTs | GCP Secret Manager | Manual (dual-secret support for zero-downtime) |
| TLS certificates | HTTPS termination | Managed by GCP Load Balancer | Auto-renewed |
| OAuth client secrets | Third-party OAuth integrations | GCP Secret Manager | Per third-party rotation + annual |
Generation
- Keys generated via approved sources: GCP KMS (for CMEK),
SecureRandom.hex(64)for application secrets, GCP for service account Workload Identity (no key material, token exchange). - No keys derived from user input (passwords, email).
- No keys embedded in source, env files, or CI variables.
Storage
- GCP Secret Manager for all application-layer secrets.
- GCP KMS for CMEK and anything that uses Google-managed key material.
- Memorystore for session tokens / OTP tokens (short-TTL, not cryptographic keys themselves).
- Never in source control,
.envfiles, workstations, or anywhere outside those systems.
Access
- Runtime service account (Cloud Run, worker VM) has
secretmanager.secretAccessoronly on the secrets it needs. - No developer has direct read access to production secrets.
- Secret access events are audit-logged in GCP Cloud Audit Logs.
- Break-glass read is possible under the access control policy.
Rotation
Per the SECRET_ROTATION.md runbook and summarized on this page.| Key | Cadence | Mechanism |
|---|---|---|
| CMEK keys | 90 days | Automatic (GCP KMS) |
| JWT signing key | 90 days | Dual-secret rotation (zero downtime) |
| AR encryption keys | Only on compromise | Re-encryption required |
| Database password | 180 days | Coordinated redeploy |
| API keys (third-party) | 365 days or per provider | Manual |
| OAuth client secrets | 365 days | Manual + provider coordination |
Compromise response
If any key is suspected of compromise:- Immediate: rotate the affected key (emergency procedure — accept brief session disruption if needed).
- Within 1 hour: audit log review for anomalous use of the compromised key.
- Within 24 hours: determine blast radius; notify affected customers if PHI exposure possible.
- Within 7 days: full post-mortem including root cause and corrective actions.
Certificate management
- All external endpoints use TLS certificates managed by GCP Load Balancer.
- Automatic renewal; no manual cert installation in production.
- Staging and prod have independent certificate pools.
- Pinned to Google’s trusted CA hierarchy.
Cryptographic use in the application
Session management
Session management
Sessions are JWTs signed with HS256 using a 64-byte secret. HttpOnly + Secure + SameSite=Lax cookies. See Authentication.
PHI column encryption
PHI column encryption
Active Record Encryption with AES-256-GCM. Deterministic mode for queryable columns (names, emails, member IDs); non-deterministic for free-text and date columns.
Password hashing
Password hashing
Devise default bcrypt with cost factor 12 (dev) / 13 (prod) — upgradeable without re-hashing.
Magic-link tokens
Magic-link tokens
128-bit
SecureRandom tokens; hashed before DB storage; single-use; short TTL (15 min).TOTP secrets
TOTP secrets
RFC 6238 with 160-bit secrets; encrypted in the database via AR encryption.
Passkeys / WebAuthn
Passkeys / WebAuthn
Standard WebAuthn using the user’s platform or roaming authenticator; no server-side private key material.
CSRF tokens
CSRF tokens
Signed tokens tied to the session; verified on every state-changing request.
Webhook signatures (inbound)
Webhook signatures (inbound)
HMAC-SHA256 with provider-specific shared secrets.
Hardcoded-secret prevention
- gitleaks runs on every commit (CI + pre-push).
- Brakeman flags suspicious crypto patterns in Ruby.
- 1Password for any human-held secret; no secrets in personal notes or chat.
- Pair-programming review of any crypto-adjacent code.
Export controls
Denialbase uses standard symmetric and asymmetric algorithms available from the United States under ECCN 5D002 with self-classification and (where applicable) BIS filings. Distributions are via GCP’s hosted infrastructure; we don’t export standalone cryptographic code.Exceptions
Any deviation from this policy requires written approval from the Security Officer with a documented rationale, risk acceptance, and expiry. Tracked in the Risk register.Related
- Encryption — implementation detail
- Authentication — session and MFA mechanisms
- Access control — who can use what keys