# 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 `kfuse-fed` chart only. Standard (`kfuse`) deployments follow the same EBS encryption steps, but FedRAMP compliance also requires the managed services (RDS, ElastiCache, MSK) and S3 buckets to be encrypted — those are covered in their respective setup pages. |

## 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](https://docs.kloudfuse.com/platform/4.0.2/setup/storage/iops-aws/#prerequisites))
- CloudTrail enabled in the AWS account for KMS audit logging

Set the required environment variables before running the commands on this page:

```console
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:

```console
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:

```console
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:

```console
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 `<ebs-csi-irsa-role>` with the IAM role used by the `ebs-csi-controller-sa` service account in your cluster, and `<eks-node-role>` with your EKS managed node group IAM role. Both can be found in the EKS console under **Compute → Node Groups**. |

## Create an Encrypted StorageClass

Define a StorageClass that references the CMK. All PVCs using this StorageClass will be encrypted with the customer-managed key.

```yaml
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
```

Apply the StorageClass to your cluster:

```console
kubectl apply -f storageclass-encrypted-gp3.yaml
```

## Configure Helm Values

Reference the encrypted StorageClass across all stateful Kloudfuse components in your `custom-values.yaml`:

```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 FedRAMP install, combine this with the managed services values from [Cloud Services](https://docs.kloudfuse.com/platform/4.0.2/setup/cloud-services/overview/) 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:

```console
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"
```

## Validate Encryption

After deploying Kloudfuse, confirm that all PVC-backed EBS volumes are encrypted with the CMK:

```console
# List PVs and their corresponding EBS volume IDs
kubectl get pv -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.csi.volumeHandle}{"\n"}{end}'
```

```console
# 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:

```console
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:

```console
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:

```console
aws cloudtrail lookup-events \ 
  --lookup-attributes AttributeKey=ResourceName,AttributeValue="$KMS_KEY_ID" \ 
  --region "$AWS_REGION" \ 
  --max-results 20
```

## References

- [AWS FedRAMP compliance overview](https://aws.amazon.com/compliance/fedramp/)
- [Amazon EBS encryption](https://docs.aws.amazon.com/ebs/latest/userguide/EBSEncryption.html)
- [Amazon EBS encryption by default](https://docs.aws.amazon.com/ebs/latest/userguide/encryption-by-default.html)
- [Creating KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)
- [Rotating AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html)
- [KMS key policies](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)
- [AWS EBS CSI driver StorageClass parameters](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/parameters.md)
- [Amazon EBS CSI driver for EKS](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html)
- [NIST SP 800-53 Rev 5 — Security and Privacy Controls](https://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final)
- [FedRAMP Security Controls Baseline](https://www.fedramp.gov/assets/resources/documents/FedRAMP_Security_Controls_Baseline.xlsx)
