S3 with Encryption
This example shows how to back up RabbitMQ messages to S3 with server-side encryption and IAM roles instead of static credentials.
Server-Side Encryption Options
AWS S3 supports three types of server-side encryption:
| Type | Key Management | Config |
|---|---|---|
| SSE-S3 | AWS-managed keys | Default on most buckets |
| SSE-KMS | AWS KMS customer-managed key | Requires KMS key ARN |
| SSE-C | Customer-provided key | Key sent with each request |
rabbitmq-backup uses the object_store crate, which works with SSE-S3 and SSE-KMS transparently when configured at the bucket level.
Step 1: Enable Default Encryption on the Bucket
SSE-S3 (AES-256)
aws s3api put-bucket-encryption \
--bucket rabbitmq-backups-encrypted \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
},
"BucketKeyEnabled": true
}
]
}'
SSE-KMS (Customer Managed Key)
# Create a KMS key
KMS_KEY_ID=$(aws kms create-key \
--description "RabbitMQ backup encryption key" \
--query 'KeyMetadata.KeyId' --output text)
# Create an alias for easy reference
aws kms create-alias \
--alias-name alias/rabbitmq-backup \
--target-key-id $KMS_KEY_ID
# Enable SSE-KMS on the bucket
aws s3api put-bucket-encryption \
--bucket rabbitmq-backups-encrypted \
--server-side-encryption-configuration "{
\"Rules\": [
{
\"ApplyServerSideEncryptionByDefault\": {
\"SSEAlgorithm\": \"aws:kms\",
\"KMSMasterKeyID\": \"$KMS_KEY_ID\"
},
\"BucketKeyEnabled\": true
}
]
}"
Step 2: Create an IAM Policy
The IAM policy must include KMS permissions when using SSE-KMS:
rabbitmq-backup-policy-encrypted.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3Access",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::rabbitmq-backups-encrypted",
"arn:aws:s3:::rabbitmq-backups-encrypted/*"
]
},
{
"Sid": "KMSAccess",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/YOUR-KMS-KEY-ID"
}
]
}
aws iam create-policy \
--policy-name RabbitMQBackupEncryptedPolicy \
--policy-document file://rabbitmq-backup-policy-encrypted.json
Step 3: Use IAM Roles (No Static Credentials)
EC2 Instance Profile
Attach the policy to an IAM role used by the EC2 instance:
# Create the role
aws iam create-role \
--role-name rabbitmq-backup-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}'
# Attach the policy
aws iam attach-role-policy \
--role-name rabbitmq-backup-role \
--policy-arn arn:aws:iam::123456789012:policy/RabbitMQBackupEncryptedPolicy
# Create instance profile and attach role
aws iam create-instance-profile --instance-profile-name rabbitmq-backup
aws iam add-role-to-instance-profile \
--instance-profile-name rabbitmq-backup \
--role-name rabbitmq-backup-role
EKS (IRSA)
serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: rabbitmq-backup
namespace: rabbitmq-backup
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/rabbitmq-backup-role
Step 4: Configure rabbitmq-backup
With IAM roles, no credentials are needed in the config:
backup-s3-encrypted.yaml
mode: backup
backup_id: "encrypted-backup-001"
source:
amqp_url: "amqp://backup_user:${RABBITMQ_PASSWORD}@rabbitmq.example.com:5672/%2f"
management_url: "http://rabbitmq.example.com:15672"
management_username: backup_user
management_password: "${RABBITMQ_PASSWORD}"
queues:
include:
- "*"
storage:
backend: s3
bucket: rabbitmq-backups-encrypted
region: us-east-1
prefix: prod/
# No access_key or secret_key -- uses IAM role
backup:
compression: zstd
compression_level: 3
prefetch_count: 100
max_concurrent_queues: 4
include_definitions: true
stop_at_current_depth: true
offset_storage:
backend: sqlite
db_path: ./offsets.db
s3_key: state/offsets.db
sync_interval_secs: 30
metrics:
enabled: true
port: 8080
Step 5: Run the Backup
rabbitmq-backup backup --config backup-s3-encrypted.yaml
Step 6: Verify Encryption
Check that objects are encrypted:
aws s3api head-object \
--bucket rabbitmq-backups-encrypted \
--key prod/encrypted-backup-001/manifest.json \
--query 'ServerSideEncryption'
Expected output for SSE-S3:
"AES256"
Expected output for SSE-KMS:
"aws:kms"
Step 7: Restore from Encrypted Backup
The restore configuration is identical -- S3 handles decryption transparently:
restore-s3-encrypted.yaml
mode: restore
backup_id: "encrypted-backup-001"
target:
amqp_url: "amqp://admin:${RABBITMQ_PASSWORD}@rabbitmq.example.com:5672/%2f"
management_url: "http://rabbitmq.example.com:15672"
management_username: admin
management_password: "${RABBITMQ_PASSWORD}"
storage:
backend: s3
bucket: rabbitmq-backups-encrypted
region: us-east-1
prefix: prod/
restore:
restore_definitions: true
publish_mode: exchange
publisher_confirms: true
rabbitmq-backup restore --config restore-s3-encrypted.yaml
Additional Security: Bucket Policy
Deny unencrypted uploads to the bucket:
bucket-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnencryptedUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::rabbitmq-backups-encrypted/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": ["AES256", "aws:kms"]
}
}
},
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::rabbitmq-backups-encrypted",
"arn:aws:s3:::rabbitmq-backups-encrypted/*"
],
"Condition": {
"Bool": { "aws:SecureTransport": "false" }
}
}
]
}
aws s3api put-bucket-policy \
--bucket rabbitmq-backups-encrypted \
--policy file://bucket-policy.json
Checklist
- Bucket created with default encryption enabled
- IAM policy includes S3 and KMS permissions
- IAM role attached (instance profile, IRSA, or static credentials)
- No credentials in config file (using IAM role)
- Bucket policy denies unencrypted uploads
- Bucket policy enforces HTTPS
- Backup runs successfully
- Objects verified as encrypted via
head-object