Skip to main content
emnode / learn
Compliance Medium severity

AWS Security Hub · ES

ES.1: ES domains should encrypt at rest

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub ES.1 check?

ES.1 fails when a legacy Elasticsearch domain runs with encryption at rest switched off. Encryption at rest wraps the domain's indices, automated snapshots, swap files, and logs on its EBS volumes with an AWS KMS key.

Why does ES.1 matter?

An ES domain typically holds indexed logs, search corpora, or analytics data — frequently with PII like email addresses, IP addresses, or account identifiers buried in log lines. Without encryption, all of that sits on disk as plaintext, readable by anyone who reaches the underlying storage. Encryption at rest is a near-universal requirement across PCI DSS, HIPAA, SOC 2, and ISO 27001.

How do I fix ES.1?

  1. Create a new domain with encryption at rest enabled and a KMS key.
  2. Snapshot the existing domain and restore its indices into the encrypted one.
  3. Cut traffic over to the new domain and decommission the unencrypted one.
  4. Make encryption at rest a default in your domain provisioning templates.

Remediation script · bash

# 1. Bulk-enable free SSE-SQS on every unencrypted queue in the region.
for q in $(aws sqs list-queues --query 'QueueUrls[]' --output text); do
  state=$(aws sqs get-queue-attributes --queue-url $q \
    --attribute-names KmsMasterKeyId SqsManagedSseEnabled --query 'Attributes' --output text)
  [ -z "$state" ] && aws sqs set-queue-attributes --queue-url $q \
    --attributes '{"SqsManagedSseEnabled":"true"}' && echo "encrypted $q"
done

# 2. High-throughput stream: SSE-KMS with a 5-minute data-key reuse window to keep KMS cost flat.
aws kinesis start-stream-encryption --stream-name payment-events \
  --encryption-type KMS \
  --key-id arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

# 3. Find unencrypted recovery points (Backup.1 reads IsEncrypted per recovery point, not per vault).
aws backup list-recovery-points-by-backup-vault --backup-vault-name prod-backups \
  --query 'RecoveryPoints[?IsEncrypted==`false`].[RecoveryPointArn,ResourceType]' --output table

# 4. Confirm an at-rest Config rule is evaluating so regressions are caught automatically.
aws configservice describe-compliance-by-config-rule --config-rule-names sqs-queue-encrypted \
  --query 'ComplianceByConfigRules[].Compliance.ComplianceType'

Full walkthrough (console steps, edge cases and verification) in the lesson Encrypt other services at rest (queues, streams, logs, ML).

Is ES.1 a false positive?

Encryption at rest cannot be enabled on an existing domain — it must be set at creation, so remediation is a rebuild-and-migrate rather than a toggle.

Part of the learning path Encrypt everything
  • ES.2 A legacy Elasticsearch domain is publicly accessible
  • ES.3 ES should encrypt node-to-node traffic
  • ES.4 ES error logging to CW should be enabled
  • ES.5 ES domains should have audit logging
  • ES.6 ES domains should have >= 3 data nodes
  • ES.7 ES domains should have >= 3 dedicated master nodes
  • ES.8 ES should use latest TLS policy