> ## Documentation Index
> Fetch the complete documentation index at: https://trust.denialbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cryptography policy

> Annex A.8.24 + A.5.17 — policy governing cryptographic controls, key management, and approved algorithms at Denialbase.

<Info>
  This policy governs when we encrypt, with what, and how we manage keys. [Encryption](/trust/encryption) is the implementation detail; this is the policy that implementation must conform to.
</Info>

**Owner**: CTO (implementation) · **Approved by**: Security Officer · **Policy version**: 0.9 (draft) · **Reviewed**: Annually

## Requirement by data classification

Per the [Data classification policy](/trust/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

<CardGroup cols={2}>
  <Card title="Symmetric" icon="lock">
    **AES-256-GCM** for authenticated encryption (the default for Active Record Encryption and GCP CMEK).
  </Card>

  <Card title="Asymmetric" icon="key">
    **RSA-2048+** or **ECDSA P-256+** for signing. **Ed25519** preferred for new signing needs.
  </Card>

  <Card title="Hashing" icon="fingerprint">
    **SHA-256** or **SHA-512** for integrity. **Argon2id** or **bcrypt** for password storage (Devise uses bcrypt by default).
  </Card>

  <Card title="Transport" icon="network-wired">
    **TLS 1.2** minimum; **TLS 1.3** preferred. SSLv3, TLS 1.0, TLS 1.1 disabled at the load balancer.
  </Card>
</CardGroup>

### 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, `.env` files, workstations, or anywhere outside those systems.

### Access

* Runtime service account (Cloud Run, worker VM) has `secretmanager.secretAccessor` only 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](/trust/access-control-policy).

### Rotation

Per the [SECRET\_ROTATION.md](https://github.com/Denialbase/denialbase/blob/master/docs/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:

1. **Immediate**: rotate the affected key (emergency procedure — accept brief session disruption if needed).
2. **Within 1 hour**: audit log review for anomalous use of the compromised key.
3. **Within 24 hours**: determine blast radius; notify affected customers if PHI exposure possible.
4. **Within 7 days**: full post-mortem including root cause and corrective actions.

See [Incident response](/trust/incident-response).

## 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

<AccordionGroup>
  <Accordion title="Session management">
    Sessions are JWTs signed with HS256 using a 64-byte secret. HttpOnly + Secure + SameSite=Lax cookies. See [Authentication](/trust/authentication).
  </Accordion>

  <Accordion title="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.
  </Accordion>

  <Accordion title="Password hashing">
    Devise default bcrypt with cost factor 12 (dev) / 13 (prod) — upgradeable without re-hashing.
  </Accordion>

  <Accordion title="Magic-link tokens">
    128-bit `SecureRandom` tokens; hashed before DB storage; single-use; short TTL (15 min).
  </Accordion>

  <Accordion title="TOTP secrets">
    RFC 6238 with 160-bit secrets; encrypted in the database via AR encryption.
  </Accordion>

  <Accordion title="Passkeys / WebAuthn">
    Standard WebAuthn using the user's platform or roaming authenticator; no server-side private key material.
  </Accordion>

  <Accordion title="CSRF tokens">
    Signed tokens tied to the session; verified on every state-changing request.
  </Accordion>

  <Accordion title="Webhook signatures (inbound)">
    HMAC-SHA256 with provider-specific shared secrets.
  </Accordion>
</AccordionGroup>

## 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](/trust/risk-register).

## Related

* [Encryption](/trust/encryption) — implementation detail
* [Authentication](/trust/authentication) — session and MFA mechanisms
* [Access control](/trust/access-control-policy) — who can use what keys
