EBS Volume Encryption (FedRAMP)
FedRAMP High and Moderate baselines require encryption at rest for all persistent data. This page covers configuring AWS EBS volume encryption for Kloudfuse FED deployments using a customer-managed KMS key (CMK), which satisfies the FedRAMP SC-28 (Protection of Information at Rest) control family.
|
This page applies to the |
FedRAMP Encryption Requirements
FedRAMP mandates the following for data at rest:
-
FIPS 140-2 validated encryption — AES-256 using AWS KMS with a customer-managed key satisfies this requirement for EBS.
-
Customer-managed keys (CMK) — the encryption key must be under agency control; AWS-managed keys (
aws/ebs) do not satisfy FedRAMP High key management requirements. -
Key rotation — CMKs must have automatic annual rotation enabled.
-
Audit trail — all KMS API calls must be logged to AWS CloudTrail.
| NIST SP 800-53 Control | Requirement | How EBS CMK satisfies it |
|---|---|---|
SC-28 |
Protect information at rest |
AES-256 encryption on all EBS volumes |
SC-12 |
Cryptographic key establishment and management |
Customer-managed KMS key with defined lifecycle |
SC-13 |
Cryptographic protection |
FIPS 140-2 validated AWS KMS HSMs |
AU-2, AU-9 |
Audit events and protection of audit information |
KMS key usage logged in CloudTrail |
Prerequisites
-
AWS CLI configured with permissions to create KMS keys and IAM policies
-
EKS cluster with the EBS CSI driver installed (see EBS CSI driver prerequisites)
-
CloudTrail enabled in the AWS account for KMS audit logging
Set the required environment variables before running the commands on this page:
export NAMESPACE=<your-namespace>
export AWS_REGION=<aws-region>
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export CLUSTER_NAME=<your-eks-cluster-name>
Create a Customer-Managed KMS Key
Create a dedicated CMK for EBS encryption with automatic annual rotation enabled:
KMS_KEY_ID=$(aws kms create-key \
--description "Kloudfuse EBS encryption key - FedRAMP" \
--key-usage ENCRYPT_DECRYPT \
--origin AWS_KMS \
--region "$AWS_REGION" \
--query 'KeyMetadata.KeyId' --output text)
echo "KMS Key ID: $KMS_KEY_ID"
# Create a human-readable alias
aws kms create-alias \
--alias-name "alias/kfuse-ebs-fedramp" \
--target-key-id "$KMS_KEY_ID" \
--region "$AWS_REGION"
# Enable automatic annual key rotation (required for FedRAMP)
aws kms enable-key-rotation \
--key-id "$KMS_KEY_ID" \
--region "$AWS_REGION"
Verify rotation is enabled:
aws kms get-key-rotation-status \
--key-id "$KMS_KEY_ID" \
--region "$AWS_REGION" \
--query 'KeyRotationEnabled'
The output must be true.
Configure the KMS Key Policy
The EBS CSI driver’s service account role and the EKS node IAM role must be granted kms:GenerateDataKeyWithoutPlaintext, kms:Decrypt, and kms:CreateGrant permissions. Replace the placeholders with your actual role ARNs:
aws kms put-key-policy \
--key-id "$KMS_KEY_ID" \
--policy-name default \
--region "$AWS_REGION" \
--policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::'"$AWS_ACCOUNT_ID"':root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow EBS CSI driver to use the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::'"$AWS_ACCOUNT_ID"':role/<ebs-csi-irsa-role>",
"arn:aws:iam::'"$AWS_ACCOUNT_ID"':role/<eks-node-role>"
]
},
"Action": [
"kms:GenerateDataKeyWithoutPlaintext",
"kms:Decrypt",
"kms:CreateGrant",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}'
|
Replace |
Create an Encrypted StorageClass
Define a StorageClass that references the CMK. All PVCs using this StorageClass will be encrypted with the customer-managed key.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: kfuse-encrypted-gp3
provisioner: ebs.csi.aws.com
parameters:
type: gp3
encrypted: "true"
kmsKeyId: <kms-key-arn>
iops: "6000"
throughput: "300"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain
Replace <kms-key-arn> with the full ARN of the CMK created above. Retrieve it with:
aws kms describe-key \
--key-id "$KMS_KEY_ID" \
--region "$AWS_REGION" \
--query 'KeyMetadata.Arn' --output text
Apply the StorageClass to your cluster:
kubectl apply -f storageclass-encrypted-gp3.yaml
Configure Helm Values
Reference the encrypted StorageClass across all stateful Kloudfuse components in your custom-values.yaml:
pinot:
server:
persistence:
storageClass: kfuse-encrypted-gp3
size: 500Gi
controller:
persistence:
storageClass: kfuse-encrypted-gp3
size: 100Gi
zookeeper:
persistence:
storageClass: kfuse-encrypted-gp3
size: 20Gi
kafka:
persistence:
storageClass: kfuse-encrypted-gp3
size: 200Gi
zookeeper:
persistence:
storageClass: kfuse-encrypted-gp3
size: 20Gi
kfuse-configdb:
primary:
persistence:
storageClass: kfuse-encrypted-gp3
size: 50Gi
For the full FED install, combine this with the managed services values from Cloud Services and your ingress/TLS configuration.
Enable Account-Level EBS Encryption Default (Optional)
To ensure no unencrypted EBS volume can be provisioned in the AWS account — a defense-in-depth measure aligned with FedRAMP — enable the account-level EBS encryption default:
aws ec2 enable-ebs-encryption-by-default \
--region "$AWS_REGION"
# Set the account default KMS key to your CMK
aws ec2 modify-ebs-default-kms-key-id \
--kms-key-id "$KMS_KEY_ID" \
--region "$AWS_REGION"
|
Enabling account-level default encryption applies to all new EBS volumes in the region, regardless of StorageClass settings. Verify that existing workloads in the account are compatible before enabling this setting. |
Validate Encryption
After deploying Kloudfuse, confirm that all PVC-backed EBS volumes are encrypted with the CMK:
# List PVs and their corresponding EBS volume IDs
kubectl get pv -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.csi.volumeHandle}{"\n"}{end}'
# Check encryption status for a specific volume
aws ec2 describe-volumes \
--volume-id <vol-id> \
--region "$AWS_REGION" \
--query 'Volumes[0].{Encrypted:Encrypted,KmsKeyId:KmsKeyId}'
The output should show "Encrypted": true and the KMS key ARN matching alias/kfuse-ebs-fedramp.
Check the StorageClass applied to each PVC:
kubectl get pvc -n "$NAMESPACE" \
-o custom-columns='NAME:.metadata.name,STORAGECLASS:.spec.storageClassName,STATUS:.status.phase'
All PVCs should reference kfuse-encrypted-gp3.
Audit: CloudTrail KMS Logging
FedRAMP AU-2 requires logging of cryptographic key usage. Verify that CloudTrail is recording KMS events:
aws cloudtrail get-event-selectors \
--trail-name <your-trail-name> \
--region "$AWS_REGION"
KMS GenerateDataKey, Decrypt, and CreateGrant events are automatically included in CloudTrail management events. No additional configuration is required beyond ensuring a trail is active.
To query recent KMS usage for the CMK:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=ResourceName,AttributeValue="$KMS_KEY_ID" \
--region "$AWS_REGION" \
--max-results 20