Skip to main content

Key Management Policy

Key Management Policy

Organization: ALAI Holding AS — Drop Payment App Policy Number: POL-SEC-KM-001 Version: 1.0 Date: 2026-02-23 Author: ALAI Security Team Status: Draft Reviewers: CISO, CTO, DPO Next Review: 2027-02-23 (annual) or after Phase 2 AWS KMS integration Classification: Confidential — Restricted Distribution

Document History

Version Date Author Changes
0.1 2026-02-12 Security Agent (ALAI) Initial standards from security audit
1.0 2026-02-23 Security Architect (ALAI) Policy document

Sources: legal/ikt-sikkerhetspolicy.md §6.3, docs/SECURITY-COMPLIANCE/data-encryption-policy.md, security/security-hardening-implementation.md


1. Purpose & Scope

Purpose: This policy defines the lifecycle management requirements for all cryptographic keys used by ALAI Holding AS in the Drop payment application. Drop processes regulated financial data (fødselsnummer, bank accounts, transaction data, AML records) requiring systematic key management per GDPR Art. 32, DORA Art. 9(4)(d), and IKT-forskriften.

Scope: All cryptographic keys in use across:

  • Production, staging, and development environments
  • All cloud infrastructure (AWS — EEA regions, Phase 2+)
  • All developer workstations handling Confidential or Restricted data
  • All third-party integrations where ALAI holds keys (Sumsub, Neonomics, Swan, BankID)
  • JWT signing keys, database encryption keys, TLS certificate private keys, API authentication keys

Policy Owner: Alem Bašić, CISO ([email protected]) Operational Owner: ALAI Platform/Security team


2. Key Types & Purposes

2.1 Current MVP Keys

Key ID Type Algorithm Purpose Classification Protected Location
JWT-01 JWT Signing Key HMAC-SHA-256 (HS256) Sign and verify JWT session tokens All user data JWT_SECRET env var
TLS-EXT TLS Certificate Key ECDSA P-256 External HTTPS (getdrop.no) All transit data Hosting provider
SUMSUB-01 Webhook HMAC Key HMAC-SHA-256 Verify Sumsub KYC webhooks KYC data integrity SUMSUB_WEBHOOK_SECRET env var
SENTRY-01 DSN Token Bearer token Sentry error reporting Error data SENTRY_DSN env var

2.2 Phase 2 Target Keys (AWS KMS)

Key ID Type Algorithm Purpose Classification Protected Owner
KEK-01 Key Encryption Key AES-256 Master key for database DEKs Restricted Security team
KEK-02 Key Encryption Key AES-256 Fødselsnummer encryption master Restricted (L4) Security team
DEK-PII-* Data Encryption Key AES-256-GCM Per-record PII field encryption Confidential/Restricted Application
DEK-FNR-* Data Encryption Key AES-256-GCM Fødselsnummer field encryption Restricted Application
TLS-EXT TLS Certificate Key ECDSA P-256 External HTTPS Platform team
TLS-INT TLS Certificate Key Ed25519 Internal mTLS (Phase 3) Platform team
JWT-02 JWT Signing Key RS256 (RSA-4096) or EdDSA Asymmetric JWT signing Security team
BACKUP-01 Backup Encryption Key AES-256-GCM Database backup encryption Restricted Security team
SUMSUB-01 Webhook HMAC Key HMAC-SHA-256 Sumsub webhook verification KYC data integrity Engineering
NEONOMICS-01 OAuth Client Secret HMAC-SHA-256 PSD2 API authentication Engineering
SWAN-01 OAuth Client Secret HMAC-SHA-256 Swan banking API Engineering

3. Key Lifecycle

3.1 Lifecycle Overview

Generation (CSPRNG / KMS / HSM)
    ↓
Distribution (encrypted channel only — never plaintext)
    ↓
Storage (KMS / Secrets Manager / env var — never in code)
    ↓
Usage (access controlled, all operations logged)
    ↓
Rotation (scheduled — see §3.6)
    ↓
Revocation (on compromise — immediate)
    ↓
Destruction (secure erase — verified)

3.2 Generation

Entropy requirements:

  • All keys MUST be generated using a cryptographically secure random number generator (CSPRNG)
  • Minimum entropy: 256 bits for symmetric keys
  • NEVER use: timestamps, UUIDs, user-supplied passphrases, or predictable values as keys
  • NEVER generate Restricted (L4) keys in application code — use AWS KMS GenerateKey API

Approved generation methods:

Key Type Generation Method Notes
JWT secret (HS256) crypto.randomBytes(32).toString('hex') (Node.js OS CSPRNG) 256-bit
AES-256 DEK crypto.randomBytes(32) 256-bit
ECDSA P-256 openssl ecparam -name prime256v1 -genkey -noout TLS certs
Ed25519 openssl genpkey -algorithm ed25519 JWT signing (Phase 2)
RSA-4096 openssl genrsa -aes256 4096 Legacy JWT (Phase 2)
AWS KMS-managed AWS KMS GenerateKey API Restricted data keys
HMAC-SHA-256 crypto.randomBytes(32) as key material Webhook verification

Current MVP: JWT_SECRET is generated and set as environment variable by operator at deployment. Must be cryptographically random — minimum 32 bytes.

Generation environment rule: Keys protecting Restricted (L4) data (fødselsnummer) MUST be generated within AWS KMS — never in application code.


3.3 Distribution

Principles:

  • Never transmit keys in plaintext over any channel
  • Never include keys in source code, config files committed to version control, or logs
  • Never send keys via email, Slack, or any messaging platform
  • Never hardcode keys — fatal error if JWT_SECRET not set in production (enforced in auth.ts)

Distribution methods:

Scenario Method
Production runtime keys AWS Secrets Manager (Phase 2) / environment variables (MVP)
Developer secrets 1Password / Vaultwarden — never in .env committed to git
CI/CD secrets GitHub Actions encrypted secrets (scoped per environment)
Third-party API keys AWS Secrets Manager (Phase 2) / Vaultwarden for local dev
Emergency key recovery Dual approval process — see §7

Current MVP protection: .env file excluded from git via .gitignore. JWT_SECRET fatal error if missing in production enforced in src/drop-app/src/lib/auth.ts.


3.4 Storage

Storage hierarchy (Phase 2 target):

Level 1 — AWS KMS (HSM-backed)
  ├── KEK-01: Master key for database PII field encryption
  ├── KEK-02: Master key for fødselsnummer encryption (separate key)
  └── Root of trust for all derived keys

Level 2 — AWS Secrets Manager
  ├── JWT_SECRET (or JWT private key for RS256)
  ├── Database password (PostgreSQL)
  ├── Sumsub webhook HMAC key
  ├── Neonomics OAuth client secret
  ├── Swan OAuth client secret
  └── BankID client credentials

Level 3 — Application memory (ephemeral only)
  ├── DEKs during active encryption/decryption
  └── Decrypted secrets during request handling
  Note: NEVER persist Level 3 to disk or logs

Level 4 — CI/CD (GitHub Actions secrets)
  ├── Staging environment secrets
  └── Deployment credentials (scoped to specific environments)

Current MVP storage (pre-AWS):

  • JWT_SECRET: Environment variable — set at deployment by operator
  • Third-party API keys: Vaultwarden (vault.basicconsulting.no) for local dev, environment variables in deployment

Prohibited storage locations:

  • Source code or config files in version control (.env in git)
  • Application logs or Sentry error messages
  • Browser localStorage or sessionStorage
  • Email attachments or Slack messages
  • Unencrypted database columns for Restricted data

3.5 Usage

Access control principles:

Principle Implementation
Least privilege JWT secret only accessible by auth service; each integration key scoped to its service
Separation of duties Key generation separate from key deployment approval
Key purpose binding JWT signing key not used for data encryption; encryption keys not used for signing
Audit all access All AWS KMS operations logged in CloudTrail (Phase 2)
No sharing Each environment (dev/staging/prod) has separate keys

Current enforcement: JWT_SECRET loaded at startup only, fatal if missing. No key ever returned in API responses. Session tokens stored as SHA-256 hashes only.


3.6 Rotation Schedule

Key Type Rotation Period Method Owner Alert if Overdue
JWT signing key (JWT_SECRET) Quarterly Rotation with overlap period (old valid 24h) Security team Yes — 7 days overdue
Database KEK (AES-256, Phase 2) Annual AWS KMS automatic rotation Security team Yes — 14 days overdue
Database DEKs (PII, Phase 2) Quarterly Automated via key rotation API Platform Yes — 7 days overdue
TLS certificates (external) 90 days Automated (Let's Encrypt / cert-manager) Platform Yes — 14 days before expiry
TLS certificates (internal, Phase 3) 30 days Automated Platform Yes — 7 days before expiry
Sumsub webhook key Annually or on Sumsub rotation Manual via Sumsub dashboard Engineering Yes
Neonomics OAuth secret Per Neonomics policy Via Neonomics developer portal Engineering Yes
Swan OAuth secret Per Swan policy Via Swan developer portal Engineering Yes
Backup encryption key (Phase 2) Annual Manual + dual approval Security team Yes — 7 days overdue

JWT rotation overlap: Old JWT_SECRET remains valid for 24 hours after new key activation to allow in-flight sessions to complete. Users are NOT logged out on rotation.

Rotation monitoring: Calendar reminders for manual rotations. AWS KMS rotation alerts for automated keys (Phase 2).


3.7 Revocation Procedures

Trigger conditions for immediate revocation:

  • Known or suspected key compromise
  • Employee departure (for keys in personal knowledge)
  • System compromise where key was in use
  • Regulatory requirement or law enforcement order
  • Vendor security breach (Sumsub, Neonomics, Swan notify Drop)

Emergency JWT revocation procedure (< 1 hour):

Step 1: Generate new JWT_SECRET immediately
Step 2: Deploy new secret to production (zero-downtime: old valid 5min overlap)
Step 3: All existing sessions will be invalidated (revoke all in sessions table)
Step 4: Users must re-authenticate (expected UX impact — communicate via status page)
Step 5: Audit all sessions active during compromise window
Step 6: Assess if breach notification required (see data-breach-response-plan.md)
Step 7: Document in incident log
Step 8: Post-mortem within 48 hours

Database key revocation (Phase 2):

  • Disable compromised key in AWS KMS
  • Re-encrypt all data protected by compromised key with new key
  • Priority: Restricted (L4) data first → Confidential → Internal

Certificate revocation:

  • Immediately upon compromise: Revoke via CA (Let's Encrypt ACME revoke)
  • Notify all certificate consumers
  • OCSP response updated within 1 hour

3.8 Destruction

When destruction is required:

  • Key has been rotated out and overlap period expired
  • System decommissioned
  • GDPR erasure via crypto-shredding (destroy key → all data encrypted with it is unreadable)

Destruction methods:

Key Location Destruction Method Verification
AWS KMS KMS scheduled key deletion (7-day minimum waiting period) KMS audit log
AWS Secrets Manager Delete secret, verify via API Audit log
Environment variable Remove from deployment config, redeploy Deployment verification
Application memory Language runtime GC (explicit Buffer.fill(0) for sensitive buffers) Code review
Local .env file shred -vzu .env on developer machine Developer responsibility

Verification: After destruction, confirm that decryption with destroyed key fails on a test ciphertext.

Destruction log: Document every key destruction in legal/internkontroll.md with: key ID, date, reason, verification method, actor.


4. Key Hierarchy (Phase 2 Target)

AWS KMS Root (HSM-backed — EEA region)
    │
    ├── KEK-01: General PII Encryption Master (annual rotation)
    │       └── DEK-PII-{ID}: Per-record PII field DEKs (quarterly rotation)
    │               └── Encrypts: name-as-stored, email, phone (if field-encrypted)
    │
    ├── KEK-02: Fødselsnummer Master Key (annual rotation — SEPARATE from KEK-01)
    │       └── DEK-FNR-{ID}: Fødselsnummer field DEKs (quarterly rotation)
    │               └── Encrypts: users.fodselsnummer (national ID — L4 Restricted)
    │
    ├── KEK-03: AML/KYC Records Master (annual rotation)
    │       └── DEK-AML-{ID}: AML record DEKs
    │               └── Encrypts: KYC documents, AML investigation records
    │
    ├── BACKUP-KEK: Backup Encryption Master (annual rotation — different KMS region)
    │       └── Encrypts: All database backup snapshots
    │
    ├── TLS Root CA (managed by cert-manager / Let's Encrypt)
    │       ├── External TLS Certificate (*.getdrop.no — 90 day rotation)
    │       └── Internal mTLS Certificates (30 day rotation — Phase 3)
    │
    └── JWT Signing Keys (quarterly rotation)
            Current: JWT_SECRET (HS256 — symmetric)
            Phase 2: Private key (EdDSA or RSA-4096 — asymmetric)

5. Key Management System

MVP (Current):

  • JWT secret: environment variable with OS CSPRNG generation
  • Third-party secrets: Vaultwarden (vault.basicconsulting.no) for local dev
  • No formal KMS — acceptable for pre-production MVP

Phase 2 Target:

  • Primary KMS: AWS KMS (EEA region — eu-west-1 Ireland or eu-central-1 Frankfurt)
  • Secrets Manager: AWS Secrets Manager for application secrets
  • Secondary: AWS KMS cross-region replication for disaster recovery
  • HSM: AWS CloudHSM (for KEK-02 fødselsnummer — L4 Restricted data)

KMS access control (Phase 2):

Role Permissions MFA Required
key-admin Create, rotate, schedule deletion — NO decrypt YES
key-encrypt Encrypt only (specific key IDs) YES
key-decrypt Decrypt only (specific key IDs) YES
key-auditor List, describe, view audit logs — no crypto ops YES
CI/CD pipeline Encrypt only (staging key IDs) N/A (service account)
Application service Encrypt + Decrypt (specific keys, VPC constraint) N/A (IAM role)

6. Access Controls for Key Operations

Separation of duties:

Operation Required Approval Process
Create new KEK CISO + second approver (Phase 2: AWS IAM dual approval) Documented request + approval
Rotate KEK CISO (proposer) + second approver Calendar rotation + documentation
Emergency revocation CISO alone (time-critical) Immediate + incident ticket within 1 hour
Destroy key CISO + Legal (if litigation hold) Written approval before KMS deletion
Grant service access to key CISO + system owner IAM policy review

Current MVP: Alem Bašić (CEO/CISO) is sole key custodian. Dual approval to be implemented when team is hired (Phase 2).


7. Key Escrow & Recovery

Escrow policy: JWT signing key and backup encryption keys must have recovery path.

Current MVP recovery:

  • JWT_SECRET recovery: Re-generate from CSPRNG, redeploy. All users re-authenticate.
  • If JWT_SECRET is lost: Service restarts with new secret. All sessions invalidated. This is acceptable for MVP.

Phase 2 escrow for KEKs (AWS KMS):

  • AWS KMS provides multi-region redundancy — no separate escrow needed for KMS-only keys
  • AWS KMS deletion has minimum 7-day waiting period (protection against accidental deletion)
  • AWS KMS CloudTrail provides full audit trail

Phase 2 escrow for Backup encryption key (offline):

  1. Key material exported encrypted from AWS KMS (if exportable) OR
  2. Backup KMS key replication to second region (recommended for KMS-native keys)
  3. Physical escrow: Encrypted key file stored in fireproof safe + separate secure off-site copy
  4. Access: Requires CISO + one designated board member
  5. Verification: Quarterly — confirm escrow holders can access

Recovery procedure (Phase 2):

  1. CISO opens emergency key recovery request (documented)
  2. Escrow holder(s) convene
  3. Key material combined and imported to KMS
  4. All key recovery events logged and post-mortem required within 48 hours

8. Audit Logging for Key Operations

All key operations must be logged:

  • Key generation: actor, key ID, key type, timestamp
  • Encryption/decryption: actor, key ID, operation, timestamp (not data content)
  • Key rotation: actor, old key ID, new key ID, timestamp
  • Key revocation: actor, key ID, reason, timestamp
  • Key destruction: actor, key ID, verification, timestamp
  • Access grant/revoke: actor, grantee, key ID, permissions, timestamp
  • Failed access attempts: actor, key ID, reason, timestamp

Log destination (Phase 2): AWS CloudTrail → SIEM — immutable, append-only Current MVP: Manual log in legal/internkontroll.md for all key operations

Log retention: 5 years (Hvitvaskingsloven §30) — key operation logs are AML-relevant

Alert on:

  • Off-hours access to KEKs
  • Failed access attempts > 3 in 5 minutes
  • Key deletion scheduled
  • Key rotation overdue

9. Compliance Mapping

Requirement Standard Control
Encryption key management GDPR Art. 32 This policy + KMS implementation
Cryptographic key protection DORA Art. 9(4)(d) AWS KMS (Phase 2)
Key custodian documentation IKT-forskriften § 5 Key inventory table (§2)
Key rotation IKT-sikkerhetspolicy §6.3 Rotation schedule (§3.6)
Key destruction IKT-forskriften § 5 Destruction procedures (§3.8)
Access controls DORA Art. 9(4) Access controls (§6)
Crypto-shredding for GDPR erasure GDPR Art. 17 Key destruction triggers data erasure
5-year AML record retention Hvitvaskingsloven §30 Key retention aligned with data retention
Audit trail DORA Art. 10 Logging (§8)

10. Emergency Procedures — Key Compromise

Immediate response checklist (execute within 1 hour of suspected compromise):

□ Alert CISO immediately: [email protected] / +47 40 47 42 51
□ Create incident channel: #incident-key-compromise-{DATE}
□ Identify which key was compromised (JWT, database, API key)
□ Identify what data was accessible with compromised key
□ Revoke key immediately (see §3.7)
□ Generate replacement key
□ Deploy new key to all systems (zero-downtime rotation if possible)
□ For JWT: Revoke ALL active sessions (UPDATE sessions SET revoked=1)
□ For database key: Begin re-encryption of affected data (Restricted first)
□ Audit logs: What operations used the compromised key in past 30 days?
□ Assess breach notification requirement (see data-breach-response-plan.md §5)
□ Document everything in incident log
□ Post-mortem within 48 hours

Re-encryption priority (if database key compromised):

  1. Restricted (L4): Fødselsnummer, AML records — IMMEDIATE
  2. Confidential (L3): Transaction data, KYC records — within 4 hours
  3. Internal (L2): Logs, session data — within 24 hours

Estimated impact of JWT compromise:

  • All active user sessions must be invalidated
  • All users must re-authenticate
  • Expected customer impact: temporary app disruption
  • Communication: In-app notification + email explaining security measures taken

Approval

Role Name Date Signature
Author ALAI Security Team 2026-02-23
CISO Alem Bašić
CTO Alem Bašić
DPO (compliance relevance) TBD — appointment required
Management Alem Bašić