# Encryption Policy
**Document ID**: KD-POL-009
**Owner**: Chief Technology Officer
**Approved By**: CEO, Arivaran
**Effective Date**: 2026-03-19
**Next Review Date**: 2027-03-19 (recomputed 2026-10-02 on the stated semi-annual cycle from the Effective Date; the 2026-09-19 occurrence was not recorded, and this date does not assert that a review has taken place)
**Review Cycle**: Semi-annual
**Classification**: Internal
## 1. Purpose
This policy defines the cryptographic requirements for KuiperDesk, covering data in transit, data at rest, key management, and the PKI trust chain. KuiperDesk stores customer backup data that may contain sensitive personal and business information. Encryption is the last line of defense: if all other controls fail and an attacker obtains raw storage access, encryption must render the data useless. This policy ensures cryptographic controls are strong, consistently applied, and properly managed throughout the key lifecycle.
## 2. Scope
This policy covers:
- All network communication between KuiperDesk components (agent-to-service, service-to-service, node-to-node)
- All customer data at rest in SeaweedFS and PostgreSQL (PgEdge on hub, CNPG on satellites)
- The PKI trust chain from CloudHSM root CA through OpenBao intermediate to leaf certificates
- Key management lifecycle (generation, storage, distribution, rotation, destruction)
- Cryptographic algorithm selection and FIPS compliance
## 3. Policy Statements
### 3.1 FIPS Compliance
3.1.1. All KuiperDesk infrastructure nodes (VPS-3, product hub clusters EU1: kd-prod-b / US1: kd-prod-a) run AlmaLinux (or Ubuntu for EU1) **configured** with FIPS mode enabled at the kernel level (`fips=1` boot parameter). This routes cryptographic operations through the OS's OpenSSL FIPS provider module. The **Operational-Environment** binding against the immutable shipping artifact is **self-asserted, not independently validated** — see `kuiperdesk/product/assurance/exceptions-register.yaml` (EXC-0001) and `cbom.json`; do not assert "FIPS validated" beyond that evidence (#11564).
> **#4960 — the host OS and the shipped container do NOT carry the same module; do not cite one certificate for both.** Our **container runtime** is UBI9 and ships Red Hat's version-frozen provider, module version `3.0.7-395c1a240fbfffd8` = **CMVP #4857** (FIPS 140-3, Active, sunset 2029-10-28) — that is the module the services actually use, and it is pinned + asserted (`aaSatGwSvc/Dockerfile`, `SATGW_FIPS_140_3_VERSIONS`). An **AlmaLinux 9 host**, by contrast, ships AlmaLinux's own rebuild — measured as `3.5.5-20d86bb700396c6e`, reported under the name "Red Hat Enterprise Linux OpenSSL FIPS Provider" — which is **not** the module version #4857 lists and is not covered by it. A host-level `fips=1` claim on AlmaLinux is therefore an *approved-mode configuration* claim, **not** a CMVP-certificate claim. <!-- cmvp-citation-lint: wrong-certificate correction, not a claim #4933 -->(This paragraph previously cited "CMVP #4933 on the RHEL/AlmaLinux 9.x OE"; #4933 is a Pitney Bowes postal security device, and the RHEL/AlmaLinux conflation was wrong on its own terms.)
3.1.2. SELinux is enforcing on all nodes, which in FIPS mode restricts processes to using only FIPS-approved algorithms for system-level cryptographic operations.
3.1.3. The FIPS requirement applies to infrastructure-level encryption. Application-level encryption (e.g., client-side encryption by aaagent) uses algorithms from the FIPS-approved list but may use non-FIPS-validated implementations where FIPS-validated libraries are not available on the client platform.
### 3.2 Data in Transit
3.2.1. **Agent-to-Service (Double Encryption)**: Communication between the aaagent Windows client and KuiperDesk backend services is double-encrypted:
- **Layer 1 (Network)**: TLS 1.3 (AES-256-GCM or ChaCha20-Poly1305 depending on hardware support) — gRPC mTLS over the aaSatGwSvc tunnel for cross-node traffic; RKE2 control-plane TLS within the cluster
- **Layer 2 (Application)**: TLS 1.3 with mTLS authentication over the WireGuard tunnel
This ensures that even if the WireGuard key is compromised, the TLS layer protects the data, and vice versa.
3.2.2. **Service-to-Service (Intra-Cluster)**: Pod-to-pod communication within the RKE2 cluster uses:
- Cilium WireGuard transparent encryption for all inter-pod traffic (enabled at the CNI level)
- TLS for service-to-database communication (aaHashSvc to PostgreSQL, aaTwinSvc to PostgreSQL — PgEdge on hub, CNPG on satellites) using certificates issued by cert-manager from the OpenBao intermediate CA
3.2.3. **Node-to-Node**: Cross-node communication (e.g. CNPG replication) traverses a TLS-encrypted gRPC tunnel via aaSatGwSvc. All control-plane traffic (etcd, kubelet API) is encrypted by RKE2's built-in TLS; pod-to-pod traffic is governed by Cilium NetworkPolicy.
3.2.4. **Web Traffic**: All HTTPS endpoints (aaDash, Keycloak, Forgejo, Grafana, Harbor) terminate TLS at the nginx Ingress controller using certificates issued by cert-manager. Minimum TLS version: 1.2. Preferred: TLS 1.3.
3.2.5. **Prohibited**: Unencrypted HTTP, TLS 1.0, TLS 1.1, and SSL are prohibited on all KuiperDesk endpoints. Cleartext gRPC is prohibited in production.
### 3.3 Data at Rest
3.3.1. **Kubernetes Secrets (etcd)**: etcd encryption is enabled in the RKE2 configuration using AES-CBC-256 with a key managed by RKE2. All Kubernetes Secrets (database passwords, API keys, TLS private keys) are encrypted before being written to etcd.
3.3.2. **LUKS Volume Encryption (Planned)**: Full-disk encryption using LUKS2 with AES-XTS-256 is planned for all data volumes on the product hub clusters (EU1: kd-prod-b, US1: kd-prod-a). Until LUKS is implemented, this is documented as a risk item in the risk register with the following compensating controls:
- Physical access to OVH VPS is restricted by OVH's data center security (SOC 2 certified)
- Application-level encryption (TLS, WireGuard) protects data from network-level interception
- Client-side encryption (see 3.3.4) protects customer data even if storage is compromised
3.3.3. **Database Encryption**: PostgreSQL (PgEdge on hub, CNPG on satellites) uses pgcrypto for column-level encryption of sensitive fields where applicable. Full-disk encryption via LUKS is planned for all database volumes.
3.3.4. **Client-Side Encryption**: Customer backup blocks can be encrypted by the aaagent before upload, ensuring Arivaran cannot read the data even with full infrastructure access. Encryption tiers:
| Tier | Behavior | Key Management | Use Case |
|------|----------|---------------|----------|
| **A (Mandatory)** | All blocks encrypted client-side before upload | Customer-managed key (TPM-backed, NCrypt) | Regulated industries, maximum privacy |
| **B (Default)** | All blocks encrypted client-side before upload | Arivaran-managed key (derived per-tenant from OpenBao) | Standard deployments, key recovery possible |
| **C (Opt-In)** | Client-side encryption available but not enforced | Customer choice | Legacy compatibility, performance-sensitive |
3.3.5. Client-side encryption uses AES-256-GCM with a unique nonce per block. The encryption key is derived using HKDF-SHA256 from the master key with the tenant ID and block hash as context.
### 3.4 PKI Trust Chain
3.4.1. **Root CA**: The root certificate authority was generated in AWS CloudHSM (FIPS 140-2 Level 3). The root CA has a 20-year validity period. After generating the intermediate CA certificate, the CloudHSM cluster was backed up and terminated (see Phase 4). The root CA private key exists only in the CloudHSM backup and is never extracted.
3.4.2. **Intermediate CA**: The intermediate CA runs in OpenBao on the RKE2 cluster. It has a 10-year validity period and is signed by the root CA. The intermediate CA issues all leaf certificates for KuiperDesk services.
3.4.3. **Leaf Certificates**: Service certificates (TLS, mTLS) are issued by cert-manager using the OpenBao intermediate CA as the issuer. Leaf certificates have a 90-day validity period and are automatically renewed by cert-manager 30 days before expiration.
3.4.4. **Agent Certificates**: aaagent client certificates for mTLS are issued by the OpenBao intermediate CA via the aaTwinSvc enrollment API. Agent certificates have a 90-day validity period. The agent handles renewal automatically by requesting a new certificate before the current one expires.
3.4.5. **Certificate Revocation**: Revoked certificates are published to a CRL distributed by OpenBao. aaHashSvc and aaTwinSvc check the CRL on every TLS handshake. CRL update latency is a maximum of 1 hour (CRL refresh interval on services).
### 3.5 Key Management
3.5.1. **Key Generation**: All cryptographic keys are generated using cryptographically secure random number generators. RSA keys: minimum 3072 bits (4096 preferred). EC keys: P-256 or P-384. Ed25519 for SSH.
3.5.2. **Key Storage**:
- Root CA key: AWS CloudHSM backup (offline, FIPS 140-2 Level 3)
- Intermediate CA key: OpenBao (sealed with Shamir's Secret Sharing, 3-of-5 unseal keys)
- Service TLS keys: Kubernetes Secrets (encrypted in etcd)
- Agent mTLS keys: NCrypt/TPM on Windows endpoints (non-exportable)
- OpenBao unseal keys: Distributed to separate personnel/storage locations
3.5.3. **Key Rotation**:
- Leaf certificates: Automatic 90-day rotation via cert-manager
- etcd encryption key: Rotated annually via RKE2 configuration update
- PostgreSQL database encryption key: Rotated annually via OpenBao (PgEdge on hub, CNPG on satellites)
- TLS session keys: ephemeral per-connection (ECDHE); satgw tunnel leaf certificates auto-renewed by OpenBao (90-day rotation)
- OpenBao unseal keys: Rotated when personnel with unseal key access leave the organization
3.5.4. **Key Destruction**: When keys are retired, they are destroyed in their storage medium. For HSM-backed keys, the HSM's secure deletion mechanism is used. For software keys, the key material is overwritten and the Kubernetes Secret is deleted.
### 3.6 Algorithm Inventory
| Use Case | Algorithm | Key Size | Standard |
|----------|-----------|----------|----------|
| TLS 1.3 key exchange | X25519 / ECDHE P-256 | 256 / 256 | FIPS 186-5 |
| TLS 1.3 bulk encryption | AES-256-GCM / ChaCha20-Poly1305 | 256 | FIPS 197 / RFC 8439 |
| WireGuard tunnel | ChaCha20-Poly1305 | 256 | RFC 8439 |
| Client-side block encryption | AES-256-GCM | 256 | FIPS 197 |
| Key derivation | HKDF-SHA256 | 256 | RFC 5869 |
| Content addressing (dedup) | SHA-256 | 256 | FIPS 180-4 |
| Certificate signing (root) | RSA-4096 + SHA-384 | 4096 | FIPS 186-5 |
| Certificate signing (intermediate) | ECDSA P-384 + SHA-384 | 384 | FIPS 186-5 |
| SSH authentication | Ed25519 | 256 | RFC 8032 |
| etcd encryption | AES-CBC-256 | 256 | FIPS 197 |
| PostgreSQL volume encryption (planned) | AES-XTS-256 (LUKS) | 512 (256 effective) | FIPS 197 |
| LUKS disk encryption (planned) | AES-XTS-256 | 512 (256 effective) | FIPS 197 |
3.6.1. The following algorithms are prohibited on KuiperDesk systems: MD5, SHA-1 (except for non-security purposes like Git commit hashes), DES, 3DES, RC4, RSA-1024, and any algorithm with known practical attacks.
3.6.2. The algorithm inventory is reviewed annually and updated when cryptographic guidance changes (NIST, ANSSI) or when quantum-resistant migration timelines require planning.
## 4. Roles and Responsibilities
| Role | Responsibility |
|------|---------------|
| CTO | Approve cryptographic algorithm changes. Manage OpenBao unseal key distribution. Authorize root CA operations. |
| Infrastructure Engineers | Configure and maintain encryption on all services. Monitor certificate expiration. Execute key rotation procedures. |
## 5. Compliance Mapping
| Policy Statement | SOC 2 Criteria | ISO 27001:2022 |
|-----------------|----------------|----------------|
| 3.1 FIPS Compliance | CC6.7 | A.8.24 |
| 3.2 Data in Transit | CC6.7 | A.8.24 |
| 3.3 Data at Rest | CC6.7 | A.8.24 |
| 3.4 PKI Trust Chain | CC6.7 | A.8.24 |
| 3.5 Key Management | CC6.7 | A.8.24 |
| 3.6 Algorithm Inventory | CC6.7 | A.8.24 |
## 6. Exceptions
The lack of LUKS volume encryption is a documented exception with compensating controls (see 3.3.2). No other exceptions to encryption requirements are permitted without CTO approval and a risk register entry.
## 7. Enforcement
Non-encrypted communication or storage in production is a P2 incident. Automated monitoring detects non-TLS endpoints via Gatus health checks (which verify certificate validity) and Tetragon network tracing (which detects cleartext protocols).
## 8. Revision History
| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 1.0 | 2026-03-19 | CTO | Initial release |