Key Management Guide
Key lifecycle management for AEGIS cryptographic operations.
Key lifecycle management for AEGIS cryptographic operations.
AEGIS uses a two-tier key hierarchy: a Key Encryption Key (KEK) protects Data Encryption Keys (DEKs), which in turn encrypt payloads (PII fields, override signatures). This guide covers provisioning, rotation, and operational procedures for managing these keys.
Key Hierarchy
+------------------------------+
| KEK (Master Key) |
| Stored in: KMS / HSM / env |
| Never in: database / logs |
| Loaded: once at startup |
+-------------+----------------+
|
wraps / unwraps
|
+-------------v----------------+
| DEK (Data Key) |
| HybridKEM keypair |
| X25519 + ML-KEM-768 |
| Versioned: dek-v1-YYYYMMDD |
+-------------+----------------+
|
encrypts / decrypts
|
+-------------v----------------+
| Payload |
| PII fields (12 fields) |
| AES-256-GCM bulk cipher |
+------------------------------+KEK Provider Selection
Choose the KEK provider based on your deployment environment:
| Provider | Use When | Security Level | Install |
|---|---|---|---|
| AWS KMS | Production on AWS | Hardware-backed, audit-logged | pip install -e ".[kms]" |
| HSM (PKCS#11) | On-premises or compliance-mandated HSM | FIPS 140-2 Level 3 | pip install -e ".[hsm]" |
| Environment | Containers, Kubernetes secrets | Software-only | Built-in |
| In-Memory | Testing and CI only | Ephemeral, lost on restart | Built-in |
from aegis_governance import get_kek_provider
# Auto-detect (tries KMS -> HSM -> Environment -> In-Memory)
provider = get_kek_provider()
# Force a specific provider
provider = get_kek_provider("kms")
provider = get_kek_provider("hsm")
provider = get_kek_provider("environment")
provider = get_kek_provider("in_memory")AWS KMS Setup
Prerequisites
- AWS account with KMS access
- IAM permissions:
kms:Encrypt,kms:Decrypt,kms:GenerateDataKey - A symmetric KMS key (AES-256)
Configuration
Set environment variables:
| Variable | Description | Example |
|---|---|---|
AEGIS_KMS_KEY_ID | KMS key ARN or alias | arn:aws:kms:us-west-2:123456789012:key/... |
AEGIS_KMS_WRAPPED_PRIVATE_KEY | Base64-encoded KMS-encrypted HybridKEM private key | (generated during provisioning) |
AEGIS_MASTER_KEK_PUBLIC | Base64-encoded HybridKEM public key (1,216 bytes) | (generated during provisioning) |
from aegis_governance import AWSKMSKEKProvider
# From environment variables (recommended)
provider = AWSKMSKEKProvider.from_environment()
# Or from explicit parameters
provider = AWSKMSKEKProvider(
kms_key_id="arn:aws:kms:us-west-2:123456789012:key/...",
wrapped_private_key=wrapped_bytes,
public_key_bytes=public_bytes,
)HSM (PKCS#11) Setup
Prerequisites
- PKCS#11-compatible HSM (AWS CloudHSM, YubiHSM 2, SoftHSM2)
- PKCS#11 shared library installed on the system
- Pre-provisioned AES-256 wrapping key in the HSM
Configuration
| Variable | Description | Example |
|---|---|---|
AEGIS_HSM_PKCS11_LIB | Path to PKCS#11 shared library | /opt/cloudhsm/lib/libcloudhsm_pkcs11.so |
AEGIS_HSM_TOKEN_LABEL | HSM token label | aegis-governance |
AEGIS_HSM_PIN | User PIN | (from secrets manager) |
AEGIS_HSM_WRAPPING_KEY_LABEL | AES wrapping key label | aegis-kek-v1 |
AEGIS_HSM_WRAPPED_PRIVATE_KEY | Base64-encoded wrapped HybridKEM private key | (generated during provisioning) |
AEGIS_MASTER_KEK_PUBLIC | Base64-encoded HybridKEM public key | (generated during provisioning) |
from aegis_governance import HSMKEKProvider
provider = HSMKEKProvider.from_environment()
# Session pool size defaults to 4The HSM provider uses CKM_AES_KEY_WRAP_KWP (RFC 5649) for key wrapping.
Environment Variable KEK Setup
For containerized deployments where KMS/HSM is not available:
| Variable | Description |
|---|---|
AEGIS_MASTER_KEK_PUBLIC | Base64-encoded HybridKEM public key (1,216 bytes) |
AEGIS_MASTER_KEK_PRIVATE | Base64-encoded HybridKEM private key (2,432 bytes) |
Security Limitation
Environment variable keys are stored in plaintext in the container environment. Use KMS or HSM for production deployments where possible.
from crypto.kek_provider import EnvironmentKEKProvider
provider = EnvironmentKEKProvider()Signing Key Provisioning
Override signatures require separate keypairs for each custodian.
Generate Custodian Keypairs
from crypto.bip322_provider import BIP322Provider
import base64
provider = BIP322Provider()
# Generate keypair for Risk Lead
risk_priv, risk_pub = provider.generate_keypair()
print(f"Risk Lead private key: {base64.b64encode(risk_priv).decode()}")
print(f"Risk Lead public key: {base64.b64encode(risk_pub).decode()}")
# Generate keypair for Security Lead
sec_priv, sec_pub = provider.generate_keypair()
print(f"Security Lead private key: {base64.b64encode(sec_priv).decode()}")
print(f"Security Lead public key: {base64.b64encode(sec_pub).decode()}")Key Distribution
| Recipient | Receives | Storage |
|---|---|---|
| Risk Lead | Private key + public key | Secure personal storage (hardware token preferred) |
| Security Lead | Private key + public key | Secure personal storage (hardware token preferred) |
| AEGIS deployment | Both public keys | Configuration / environment variables |
Private keys must never be shared between custodians or stored in the AEGIS deployment itself.
Key Rotation
Scheduled Rotation
Rotate keys on a regular schedule (recommended: quarterly for DEKs, annually for KEKs).
DEK Rotation:
DEKs are versioned (dek-v1-YYYYMMDD). The DEKRotator in
src/telemetry/encryption.py handles automatic DEK rotation:
- New events are encrypted with the current DEK version
- Old events remain readable with their original DEK version
- The KEK can decrypt any DEK version
KEK Rotation:
- Generate a new KEK in KMS/HSM
- Re-wrap all existing DEKs with the new KEK
- Update environment variables / configuration
- Verify decryption works with the new KEK
- Retire the old KEK after a grace period
Emergency Rotation
If a key compromise is suspected:
- Immediately generate new keypairs for affected custodians
- Revoke the compromised keys
- Re-sign any pending override requests with new keys
- Audit all override decisions made with the compromised key
- Rotate DEKs if encryption keys were affected
PII Encryption Pipeline
AEGIS encrypts 12 PII fields across three priority levels:
Critical Fields (6)
| Field | Description |
|---|---|
actor_assignments | Role-to-actor mapping for workflow |
override_justification | Why override was requested |
risk_lead_signature | Risk Lead's cryptographic signature |
security_lead_signature | Security Lead's cryptographic signature |
decision_actor | Actor who made the governance decision |
decision_rationale | Rationale behind the governance decision |
High Priority Fields (4)
| Field | Description |
|---|---|
workflow_id | Workflow instance identifier |
author_id | Proposal author identifier |
actor_id | Actor/caller identifier |
combined_hash | Combined signature hash |
Medium Priority Fields (2)
| Field | Description |
|---|---|
requested_by | Override requestor |
signer_id | Cryptographic signer identifier |
Enabling PII Encryption
from telemetry.encryption import create_pii_enricher
from telemetry.pipeline import TelemetryPipeline
from aegis_governance import get_kek_provider
# Set up KEK provider and get public key
kek = get_kek_provider()
public_key = kek.get_public_key()
# Create PII encryption enricher
enricher = create_pii_enricher(
public_key=public_key,
dek_version="dek-v1-20260101",
)
# Wire into telemetry pipeline
pipeline = TelemetryPipeline()
pipeline.add_enricher(enricher)Encrypted fields follow this schema:
{
"agent_id": {
"_encrypted": true,
"_algorithm": "x25519+ml-kem-768+aes-256-gcm",
"_dek_version": "dek-v1-20260101",
"_ciphertext": "base64-encoded-blob",
"_plaintext_hash": "sha256-for-integrity",
"_encrypted_at": "2026-01-01T00:00:00Z"
}
}Environment Variable Reference
All AEGIS crypto environment variables in one place:
| Variable | Purpose | Required By |
|---|---|---|
AEGIS_KMS_KEY_ID | AWS KMS key ARN | KMS KEK provider |
AEGIS_KMS_WRAPPED_PRIVATE_KEY | KMS-wrapped HybridKEM private key | KMS KEK provider |
AEGIS_MASTER_KEK_PUBLIC | HybridKEM public key (1,216 bytes, base64) | All KEK providers except in-memory |
AEGIS_MASTER_KEK_PRIVATE | HybridKEM private key (2,432 bytes, base64) | Environment KEK provider |
AEGIS_HSM_PKCS11_LIB | Path to PKCS#11 library | HSM KEK provider |
AEGIS_HSM_TOKEN_LABEL | HSM token label | HSM KEK provider |
AEGIS_HSM_PIN | HSM user PIN | HSM KEK provider |
AEGIS_HSM_WRAPPING_KEY_LABEL | HSM AES wrapping key label | HSM KEK provider |
AEGIS_HSM_WRAPPED_PRIVATE_KEY | HSM-wrapped HybridKEM private key | HSM KEK provider |
Related Documentation
- Crypto Overview -- Entry point for all crypto in AEGIS
- Override Workflow -- Two-key approval process
- Python SDK: Key Management -- API reference