Skip to content

SSM parameters encryption should be enabled

SSM Parameter Store frequently holds database credentials, API keys, license keys, and other configuration secrets. Storing these as String parameters means anyone with ssm:GetParameter access can read the raw value in API and console responses.

SecureString adds a KMS encryption layer that requires both SSM read permission and kms:Decrypt on the associated key. This lets you grant broad parameter read access for non-sensitive config while restricting secret access through KMS key policies.

Retrofit consideration

Changing an existing SSM parameter from String to SecureString requires destroying and recreating the resource, leaving a brief gap where the parameter doesn't exist. Services reading the parameter during that window will fail with a ParameterNotFound error. Plan these changes during a maintenance window.

Implementation

Choose the approach that matches how you manage Terraform.

Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.

module "ssm_parameter" {
  source  = "nistcsf.compliance.tf/terraform-aws-modules/ssm-parameter/aws"
  version = ">=2.0.0"

  name  = "/abc123/parameter"
  value = "example-value"
}

If you use terraform-aws-modules/ssm-parameter/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.

module "ssm_parameter" {
  source  = "terraform-aws-modules/ssm-parameter/aws"
  version = ">=2.0.0"

  name  = "/abc123/parameter"
  value = "example-value"

  type = "SecureString"
}

Use AWS provider resources directly. See docs for the resources involved: aws_ssm_parameter.

resource "aws_ssm_parameter" "this" {
  name  = "/pofix/abc123/param"
  value = "example-value"

  type = "SecureString"
}

What this control checks

The control checks type on each aws_ssm_parameter resource. "SecureString" passes; "String" or "StringList" fails. The optional key_id argument specifies which KMS key encrypts the value. When omitted, AWS defaults to the aws/ssm managed key. To pass, every aws_ssm_parameter must set type = "SecureString". Set key_id to a customer-managed key ARN or alias if you need tighter access control.

Common pitfalls

  • Type change forces parameter replacement

    Terraform treats a change from type = "String" to type = "SecureString" as a forced replacement (forces new resource). During that window the parameter doesn't exist, and anything reading it by name will get a ParameterNotFound error. Use create_before_destroy lifecycle rules where possible, or plan the cutover carefully.

  • Default AWS-managed key limits cross-account access

    When key_id is omitted, the parameter encrypts with the aws/ssm AWS-managed key. That key's policy cannot be modified, so cross-account kms:Decrypt grants are impossible. If any other account or service needs to read the parameter, you must specify a customer-managed KMS key via key_id.

  • Terraform state still contains the plaintext value

    Even with type = "SecureString", the value argument in aws_ssm_parameter is stored in plaintext in Terraform state. Encrypt your state backend (S3 with SSE-KMS, Terraform Cloud, etc.) and restrict terraform state pull access to prevent secret exposure.

  • Not all parameters need SecureString

    Feature flags, endpoint URLs, and region names don't require encryption. Blanket SecureString enforcement adds KMS API calls that affect cost at high access volumes. Scope this control to parameters that hold credentials, secrets, or PII. Naming conventions or tags on aws_ssm_parameter resources make it straightforward to separate sensitive from non-sensitive parameters in policy.

Audit evidence

Auditors typically want an inventory of all SSM parameters showing type as SecureString. AWS Config with a rule like ssm-parameter-encryption-enabled provides continuous evidence. The CLI command aws ssm describe-parameters returns each parameter's Type field and is easy to produce on demand.

Supplementary evidence includes KMS key policies showing which principals can decrypt, and CloudTrail GetParameter events showing that WithDecryption is required for retrieval. Console screenshots showing the lock icon on encrypted parameters are also acceptable.

Framework-specific interpretation

NIST Cybersecurity Framework v2.0: PR.DS is about protecting data at rest and in transit, and KMS-encrypted SecureString parameters satisfy that requirement for anything stored in Parameter Store. SecureString also supports PR.AA: KMS key permissions become a second authorization gate, separate from SSM IAM policies, so access to the decrypted value requires both.

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: ssm_parameter_encryption_enabled

  • Checkov Check: CKV2_AWS_34

  • Powerpipe Control: aws_compliance.control.ssm_parameter_encryption_enabled

Last reviewed: 2026-03-09