AWS Customer Managed Keys: Policies, Rotation, Pricing and Access

A customer managed KMS key is a key you create and control in AWS Key Management Service. You define who can use it, how it rotates, and whether it stays active. Choose a customer managed KMS key when you need control over access policies, rotation schedules, or cross-account sharing that AWS-managed keys cannot provide.

Simple explanation

Every time AWS encrypts data for you, it uses an encryption key. The question is: who controls that key?

With an AWS-managed key, AWS creates and manages the key on your behalf. You can see it in your account, but you cannot change its permissions, share it with another account, or delete it. AWS handles everything.

With a customer managed KMS key, you create the key yourself. You write the access policy that decides which users, roles, and accounts can encrypt or decrypt with it. You choose when to rotate the key material, and you can disable or delete the key if needed.

The term “CMK” (customer master key) appears in older AWS documentation and blog posts. AWS now uses “customer managed key” as the standard term. If you see CMK in legacy references, it means the same thing.

When to use a customer managed KMS key

  • Compliance requirements. Frameworks like HIPAA, PCI-DSS, and FedRAMP often require that you, not your cloud provider, control encryption keys. A customer managed KMS key satisfies this because you own the key policy.
  • Fine-grained access control. You need certain IAM roles to read encrypted data while blocking others, even if those other roles have access to the underlying resource. Key policies enforce this at the cryptographic layer.
  • Cross-account data sharing. You need another AWS account to decrypt data you encrypted. Only customer managed KMS keys support cross-account usage.
  • Key lifecycle management. You need to disable a key immediately during an incident, schedule deletion after decommissioning a workload, or control exactly how often the key material rotates.
  • Service-specific encryption choices. You want a particular S3 bucket, RDS database, or Secrets Manager secret to use a key you control rather than the default service key.

When an AWS-managed key is enough

Not every workload needs a customer managed KMS key. AWS-managed keys are a good fit when:

  • You have no compliance mandate requiring you to control your own keys.
  • Default encryption at rest is sufficient and you do not need to restrict decryption at the key level.
  • You are not sharing encrypted data across accounts.
  • You want zero key management overhead and no additional cost.
Note

AWS-managed keys still encrypt data with strong cryptography and log usage to CloudTrail. They are not weaker. They simply offer less control over who can use the key and when.

Customer managed KMS key vs AWS-managed key vs AWS-owned key

FeatureAWS-owned keyAWS-managed keyCustomer managed KMS key
Who creates itAWS (internal)AWS (per service, per account)You
Who controls the key policyAWSAWSYou
Visible in KMS consoleNoYesYes
CloudTrail usage loggingNoYesYes
Rotation controlAWS managesAWS rotates annuallyYou configure (90 days to 2560 days, or on-demand)
Can disable or deleteNoNoYes
Cross-account accessNoNoYes
CostFreeFree$1/month per key + API call charges
Best use caseDefault service encryptionStandard workloads, no special access requirementsCompliance, cross-account, fine-grained access control

How customer managed KMS keys work

The lifecycle of a customer managed KMS key follows a predictable pattern:

  1. You create the key in KMS. By default this is a symmetric key (AES-256) with key material generated by AWS inside hardware security modules (HSMs). The key material never leaves KMS in plaintext.
  2. You write a key policy that controls who can manage the key and who can use it for cryptographic operations. This is the primary access control mechanism.
  3. IAM policies and grants can provide additional access, but only if the key policy allows IAM delegation. Both sides must permit the operation.
  4. AWS services use the key through envelope encryption. A service like S3 or RDS calls KMS to generate a data key, encrypts your data locally with that data key, and stores the encrypted data key alongside the encrypted data. See the KMS overview for a full explanation of envelope encryption.
  5. CloudTrail records every use of the key. You can see which principal called which KMS action, when, and from where. This is critical for detecting suspicious activity and audit compliance.

Creating a customer managed KMS key

# Create a symmetric customer managed KMS key
aws kms create-key \
  --description "Production RDS database encryption key" \
  --key-usage ENCRYPT_DECRYPT \
  --origin AWS_KMS \
  --tags TagKey=Environment,TagValue=production TagKey=DataClass,TagValue=confidential

# Create an alias so you can reference the key by name
aws kms create-alias \
  --alias-name alias/prod-rds-key \
  --target-key-id abc12345-6789-0abc-def1-234567890abc

Why aliases matter

An alias like alias/prod-rds-key gives you a human-readable name for the key. You can use aliases in CLI commands, CloudFormation templates, and Terraform configurations instead of long key IDs or ARNs.

Aliases are mutable. You can update an alias to point to a different key at any time using aws kms update-alias. This is useful during manual key rotation: create a new key, update the alias to point to it, and new encryptions automatically use the new key without changing any application code.

Note

Because aliases can be repointed, they are not a stable identifier for a specific key. If you need to guarantee you are referencing a particular key (for audit trails or compliance evidence), use the key ARN directly.

Key policy vs IAM policy vs grants

Access to a customer managed KMS key is controlled by three mechanisms. Understanding how they interact prevents most access-related headaches.

Key policy (primary control)

The key policy is a resource-based policy attached directly to the key. It is the primary access control. If the key policy does not allow an action, no IAM policy or grant can override that.

The default key policy includes a root account delegation statement. This is critical because it allows IAM policies to work:

{
  "Sid": "Enable IAM User Permissions",
  "Effect": "Allow",
  "Principal": {"AWS": "arn:aws:iam::123456789012:root"},
  "Action": "kms:*",
  "Resource": "*"
}
Warning

Without the root account delegation statement, you must add every single principal that needs key access directly into the key policy. If you accidentally remove it and no remaining principal has kms:PutKeyPolicy permission, you permanently lock yourself out. Recovery requires AWS Support and is not guaranteed.

IAM policy (caller-side control)

An IAM policy attached to a user or role can grant KMS permissions, but only if the key policy delegates to IAM (via the root account statement above). The IAM policy controls what the caller is allowed to do. The key policy controls what the key allows to be done to it. Both must agree.

Following the principle of least privilege, grant only the specific KMS actions each role needs. Applications typically need only kms:Decrypt and kms:GenerateDataKey. Key management actions like kms:ScheduleKeyDeletion and kms:PutKeyPolicy should be restricted to security administrators.

Grants (temporary, scoped access)

Grants are a third access mechanism, commonly used by AWS services. When you enable encryption on an RDS instance or EBS volume, the service creates a grant that gives it permission to use your key for encrypt and decrypt operations. Grants are scoped to a specific principal and set of actions, and they can include constraints.

You rarely write grants yourself. They exist primarily so AWS services can use your customer managed KMS key without you having to modify the key policy every time.

Example: restricting decryption to specific roles

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnableIAMDelegation",
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::123456789012:root"},
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "AllowAppRoleToUseKey",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/AppServiceRole"
      },
      "Action": ["kms:Decrypt", "kms:GenerateDataKey", "kms:DescribeKey"],
      "Resource": "*"
    },
    {
      "Sid": "DenyAnalyticsRoleDecryption",
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/AnalyticsRole"
      },
      "Action": "kms:Decrypt",
      "Resource": "*"
    }
  ]
}

Even if the analytics role has kms:Decrypt in its IAM policy and full access to the S3 bucket, the explicit Deny in the key policy blocks decryption. This is key-level separation of duties. You can use IAM policy conditions for even more granular control, such as restricting access by VPC endpoint or source IP.

Real service examples

Here is how customer managed KMS keys fit into common AWS workloads.

S3 with SSE-KMS

When you configure a bucket to use SSE-KMS with your own key, every object uploaded is encrypted using envelope encryption with your customer managed KMS key. You can then restrict which roles can decrypt objects by controlling access to the key, independently of S3 bucket policies.

# Upload an object encrypted with your customer managed KMS key
aws s3 cp report.csv s3://my-bucket/reports/ \
  --sse aws:kms \
  --sse-kms-key-id alias/prod-data-key

RDS and EBS encryption

RDS and EBS encryption must be configured at creation time. Once enabled, the service creates grants on your key so it can perform encrypt and decrypt operations transparently. All snapshots inherit the encryption from the source volume or database.

Secrets Manager

Secrets Manager encrypts every secret with a KMS key. By default it uses the AWS-managed key aws/secretsmanager. Specifying your own customer managed KMS key lets you control which roles can decrypt secrets and provides a separate audit trail for key usage. This is especially important if you are rotating secrets automatically and need to track who accesses the decrypted values.

Cross-account data sharing

A common pattern: Account A stores encrypted data in S3. Account B needs to read and decrypt that data. Account A adds Account B’s role to the customer managed KMS key policy with kms:Decrypt and kms:DescribeKey. Account B’s role also needs an IAM policy allowing those KMS actions on Account A’s key ARN. This two-sided permission model is the same pattern used in cross-account role assumption.

Rotation options

Key rotation replaces the cryptographic material inside a key. KMS keeps all prior versions of the key material so existing encrypted data can still be decrypted. The key ID, ARN, and alias remain unchanged.

Automatic rotation

You can enable automatic rotation on symmetric customer managed KMS keys with AWS-generated key material (origin AWS_KMS). AWS KMS supports configurable rotation periods from 90 days to 2560 days (approximately 7 years). The default is 365 days.

# Enable automatic rotation with a 365-day period
aws kms enable-key-rotation --key-id alias/prod-rds-key

# Verify rotation status
aws kms get-key-rotation-status --key-id alias/prod-rds-key

On-demand rotation

You can also trigger an immediate rotation at any time using aws kms rotate-key-on-demand. This is useful if you suspect key material has been exposed and need to rotate without waiting for the next scheduled rotation.

Note

Both automatic and on-demand rotation are only available for symmetric keys with AWS-generated key material (origin AWS_KMS). Keys with imported material and asymmetric keys require manual rotation instead.

Manual rotation (for imported key material or asymmetric keys)

Automatic rotation is not available for keys with imported key material or asymmetric keys. For these, you perform manual rotation: create a new key, import new material if applicable, and update the alias to point to the new key.

# Create a new key
NEW_KEY_ID=$(aws kms create-key \
  --description "prod-rds-key v2" \
  --query 'KeyMetadata.KeyId' --output text)

# Update the alias to the new key
aws kms update-alias \
  --alias-name alias/prod-rds-key \
  --target-key-id $NEW_KEY_ID

After updating the alias, new encryptions use the new key. Old data remains decryptable with the old key. Do not delete the old key until you have confirmed all dependent data has been re-encrypted or is no longer needed.

Important

Rotation does not re-encrypt existing data. Data encrypted with older key material stays encrypted with that material. KMS retains all prior key material versions indefinitely so decryption continues to work. If you need data encrypted with the latest material, you must re-encrypt it explicitly.

Disable vs schedule deletion

When you no longer need a key, you have two options. Choosing the right one matters because one is reversible and the other is not.

Disabling a key

Disabling a key immediately prevents all cryptographic operations. Any service or application that tries to encrypt or decrypt with the key will fail. But the key still exists and you can re-enable it at any time. This is the right choice when:

  • You suspect the key has been compromised and need to stop usage immediately while you investigate.
  • You are decommissioning a workload but are not yet certain all encrypted data has been migrated.
  • You want a reversible safety measure before committing to permanent deletion.

Scheduling deletion

Scheduling deletion sets a waiting period of 7 to 30 days (default 30). During the waiting period, the key is disabled and cannot be used. You can cancel deletion at any time before the waiting period expires. Once the period ends, the key and all its material are permanently destroyed. Any data encrypted with the key becomes permanently inaccessible.

# Schedule deletion with a 30-day waiting period
aws kms schedule-key-deletion \
  --key-id alias/old-prod-key \
  --pending-window-in-days 30

# Cancel deletion if you discover data still depends on the key
aws kms cancel-key-deletion --key-id alias/old-prod-key
Warning

Before scheduling deletion, use CloudTrail logs to search for recent usage of the key. Check for encrypted snapshots, S3 objects, and database backups that still reference it. If you are unsure, disable the key first and wait. You can always schedule deletion later. A deleted key cannot be recovered.

Cross-account access

Sharing a customer managed KMS key across accounts is a two-sided permission model. Both the key-owning account and the consuming account must explicitly allow the operation.

Step 1: key policy in the owning account

Add the external account’s role to the key policy with the specific actions it needs:

{
  "Sid": "AllowCrossAccountDecrypt",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::999999999999:role/DataConsumerRole"
  },
  "Action": ["kms:Decrypt", "kms:DescribeKey"],
  "Resource": "*"
}

Step 2: IAM policy in the consuming account

The consuming account’s role needs an IAM policy allowing the same KMS actions on the key ARN in the owning account:

{
  "Effect": "Allow",
  "Action": ["kms:Decrypt", "kms:DescribeKey"],
  "Resource": "arn:aws:kms:us-east-1:111111111111:key/abc12345-6789-0abc-def1-234567890abc"
}

This pattern is used frequently for sharing encrypted S3 data between accounts, sharing encrypted RDS snapshots, and multi-account architectures where a central security account owns the encryption keys. For more on cross-account permission patterns, see role assumption in AWS.

Note

If cross-account access is not working, check both sides of the permission model. A missing IAM policy in the consuming account or a missing principal in the key policy will both cause AccessDenied errors. The fix is almost always a missing permission on one side.

Common mistakes

  1. Assuming rotation re-encrypts existing data. It does not. Rotation creates new key material for future operations. Existing ciphertext stays encrypted with the older material. If compliance requires re-encryption, you must do it explicitly.
  2. Mixing up key policy and IAM policy. The key policy is the primary control. If the key policy does not delegate to IAM, your IAM policies have no effect on that key. If access is denied, check the key policy first.
  3. Deleting a key too early. Once the waiting period expires, everything encrypted with that key is gone. Disable the key first and monitor CloudTrail for usage before scheduling deletion.
  4. Over-creating keys and increasing cost. At $1/month per key, creating a separate key for every individual resource adds up. Group data with similar sensitivity and access requirements under shared keys unless compliance requires per-resource separation.
  5. Treating aliases as immutable identifiers. An alias can be repointed to a different key with update-alias. Code that depends on an alias should be aware the underlying key can change. Use the key ARN when you need a stable reference.
  6. Removing the root account delegation from the key policy. If you remove the root account statement and no remaining principal has kms:PutKeyPolicy, you permanently lose the ability to manage the key. Recovery requires AWS Support and is not guaranteed.
  7. Forgetting that service integrations rely on grants. When you specify a customer managed KMS key for RDS, EBS, or Lambda, the service creates grants on the key. If you modify the key policy in a way that blocks grant creation, the service integration breaks.

Frequently asked questions

What is the difference between a customer managed KMS key and an AWS-managed key?

A customer managed KMS key is one you create and fully control. You set the key policy, choose who can use it, configure rotation, and can disable or delete it. An AWS-managed key is created and managed by AWS on your behalf for a specific service. You can view it in the console and see its CloudTrail usage, but you cannot change its policy, delete it, or share it across accounts.

When should I use a customer managed KMS key?

Use a customer managed KMS key when compliance frameworks require you to control your own encryption keys, when you need fine-grained access control (restricting which roles can decrypt specific data), when you need cross-account encryption, or when you need to disable or delete a key on demand.

Can I share a customer managed KMS key across AWS accounts?

Yes. Add the external account principal to the key policy with the specific KMS actions they need (such as kms:Decrypt and kms:DescribeKey). The external account also needs an IAM policy allowing those actions on your key ARN. Both sides must permit the operation.

What happens if I disable or delete a customer managed KMS key?

Disabling a key prevents any encryption or decryption operations that depend on it, but you can re-enable it at any time. Scheduling deletion is permanent and irreversible after the waiting period (7 to 30 days). Once deleted, any data encrypted with that key becomes permanently inaccessible.

Does key rotation re-encrypt existing data?

No. When AWS KMS rotates key material, it generates new cryptographic material for future encryptions. Existing data remains encrypted with the older key material. KMS retains all prior key material versions indefinitely so decryption continues to work. Data is only re-encrypted with the new material if you explicitly re-encrypt it.

Last verified: 30 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.