AWS KMS
AWS Key Management Service (KMS) encrypts secrets using AWS-managed keys. The encrypted ciphertext is stored in your fnox.toml file.
Comparison: KMS vs Secrets Manager
| Feature | AWS KMS | AWS Secrets Manager |
|---|---|---|
| Storage | Local (encrypted in fnox.toml) | Remote (in AWS) |
| Secrets in git | Yes (encrypted) | No (references only) |
| Pricing | $1/key/month (one key for all secrets) | $0.40/secret/month |
| Rotation | Manual | Automatic |
| Offline | No (needs AWS API) | No (needs AWS API) |
Use KMS when: You want secrets in git with AWS-managed keys.
Use Secrets Manager when: You want centralized storage without secrets in git.
Quick Start
# 1. Create KMS key
aws kms create-key --description "fnox secrets encryption"
# Note the KeyId
# 2. Configure provider
cat >> fnox.toml << 'EOF'
[providers.kms]
type = "aws-kms"
key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
region = "us-east-1"
EOF
# 3. Encrypt a secret
fnox set DATABASE_URL "postgresql://prod.example.com/db" --provider kms
# 4. Get secret (decrypts via KMS)
fnox get DATABASE_URLPrerequisites
- AWS account
- AWS credentials configured
- KMS key created
- IAM permissions
IAM Permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["kms:Decrypt", "kms:Encrypt", "kms:DescribeKey"],
"Resource": "arn:aws:kms:REGION:ACCOUNT:key/KEY-ID"
}
]
}Setup
1. Create KMS Key
Via AWS CLI:
aws kms create-key \
--description "fnox secrets encryption" \
--key-usage ENCRYPT_DECRYPT
# Output includes KeyId - copy thisOr use AWS Console → KMS → Create Key.
2. Configure AWS Credentials
Same as AWS Secrets Manager.
3. Configure fnox Provider
[providers.kms]
type = "aws-kms"
key_id = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
region = "us-east-1"The key_id can be:
- Full ARN:
arn:aws:kms:us-east-1:123456789012:key/... - Key ID:
12345678-1234-1234-1234-123456789012 - Alias:
alias/my-key
Credentials
| Field | Required | Description |
|---|---|---|
profile | No | AWS CLI profile name from ~/.aws/config. Falls back to the default credential chain if omitted. |
role_arn | No | IAM role to assume before calling KMS |
With role_arn set, fnox calls sts:AssumeRole and uses the resulting credentials for encrypt and decrypt. The credentials from profile (or the default chain) are the source credentials for that call, which covers the SOPS pattern of an SSO profile plus a key-holding role in another account:
[providers.kms]
type = "aws-kms"
key_id = "alias/my-key"
region = "eu-west-1"
profile = "sso-dev"
role_arn = "arn:aws:iam::123456789012:role/kms-user"Usage
Encrypt and Store
fnox set DATABASE_URL "postgresql://prod.example.com/db" --provider kmsResult in fnox.toml:
[secrets]
DATABASE_URL = { provider = "kms", value = "AQICAHhw...base64...ciphertext..." } # ← Encrypted, safe to commit!Decrypt and Get
fnox get DATABASE_URLHow It Works
Encryption (
fnox set):- Calls AWS KMS
EncryptAPI - Stores base64 ciphertext in fnox.toml
- Calls AWS KMS
Decryption (
fnox get):- Calls AWS KMS
DecryptAPI - Returns plaintext
- Calls AWS KMS
Multi-Environment Example
# Development: age encryption (free)
[providers]
age = { type = "age", recipients = ["age1..."] }
[secrets]
DATABASE_URL = { provider = "age", value = "encrypted-dev..." }
# Production: AWS KMS
[profiles.production.providers]
kms = { type = "aws-kms", key_id = "arn:aws:kms:us-east-1:123456789012:key/...", region = "us-east-1" }
[profiles.production.secrets]
DATABASE_URL = { provider = "kms", value = "AQICAHhw..." } # ← KMS encrypted ciphertextKey Rotation
When rotating KMS keys:
- Create new KMS key
- Update fnox.toml with new
key_id - Re-encrypt all secrets:bash
fnox set DATABASE_URL "$(fnox get DATABASE_URL)" --provider kms fnox set API_KEY "$(fnox get API_KEY)" --provider kms
Costs
AWS KMS pricing (as of 2024):
- $1.00 per key per month
- $0.03 per 10,000 operations
Example:
- 1 KMS key = $1.00/month
- 1,000 deployments × 10 secrets × 10 decrypt calls = $0.30/month
- Total: ~$1.30/month
Much cheaper than Secrets Manager for many secrets!
Pros
- ✅ Secrets in git (version control)
- ✅ AWS-managed encryption keys
- ✅ IAM access control
- ✅ CloudTrail audit logs
- ✅ Cheaper than Secrets Manager (one key for all secrets)
- ✅ No per-secret charges
Cons
- ❌ Requires AWS account and network access
- ❌ Costs money ($1/key/month)
- ❌ More complex than age encryption
- ❌ Manual rotation (vs automatic in Secrets Manager)
Next Steps
- AWS Secrets Manager - Remote storage alternative
- Age Encryption - Free local encryption
- Real-World Example - Complete AWS setup