← SCP Explorer

Restrict KMS key encryption

Allows encryption with a specific KMS key only when performed through an approved deployment pipeline role.

Policy description

What this SCP does

This Service Control Policy (SCP) restricts KMS key encryption operations to only be performed through an approved deployment pipeline role by denying access to all other principals. This ensures encryption operations are performed only through secure, approved channels.

By using a deny-based policy with an exception for the deployment pipeline role, this SCP follows AWS best practices for SCPs while implementing the principle of least privilege for encryption operations. This ensures that sensitive data can only be encrypted through approved, automated processes rather than by individual users.

Validation strategy

How to test this SCP works

To validate this SCP, test encryption operations with different roles against a specific KMS key.

  • Invalid test: Attempt to encrypt data using a regular role (should be denied)
  • Valid test: Attempt to encrypt data using the DeployPipelineRole (should succeed)

For thorough testing, create a test KMS key, configure the SCP with the specific key ARN and deployment role ARN, and then test encryption operations from multiple different roles. The SCP should deny encryption attempts from all roles except the specified DeployPipelineRole.

SCP policy & validation scenarios

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyKMSEncryptionExceptDeployPipeline", "Effect": "Deny", "Action": "kms:Encrypt", "Resource": "arn:aws:kms:us-west-2:123456789012:key/example-key-id", "Condition": { "ArnNotEquals": { "aws:PrincipalArn": "arn:aws:iam::123456789012:role/DeployPipelineRole" } } } ] }
# Create a KMS key aws kms create-key --description "Test Restricted Key" # Create a deployment pipeline role aws iam create-role \ --role-name DeployPipelineRole \ --assume-role-policy-document file://trust-policy.json # Create a test user role aws iam create-role \ --role-name TestUserRole \ --assume-role-policy-document file://trust-policy.json # Try to encrypt data with the key using different roles # Should be denied for TestUserRole but allowed for DeployPipelineRole
import boto3 import json # Initialize IAM and KMS clients iam_client = boto3.client('iam') kms_client = boto3.client('kms') # Create test resources try: # Create a KMS key key_response = kms_client.create_key(Description='Test Restricted Key') key_id = key_response['KeyMetadata']['KeyId'] key_arn = key_response['KeyMetadata']['Arn'] print(f"Created KMS key: {key_id}") # Create deployment pipeline role deploy_trust_policy = { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole" } ] } deploy_role = iam_client.create_role( RoleName='DeployPipelineRole', AssumeRolePolicyDocument=json.dumps(deploy_trust_policy) ) deploy_role_arn = deploy_role['Role']['Arn'] print(f"Created deployment role: {deploy_role_arn}") # Create test user role test_role = iam_client.create_role( RoleName='TestUserRole', AssumeRolePolicyDocument=json.dumps(deploy_trust_policy) ) test_role_arn = test_role['Role']['Arn'] print(f"Created test user role: {test_role_arn}") # Create key policy that references the SCP condition key_policy = { "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": {"AWS": f"arn:aws:iam::{boto3.client('sts').get_caller_identity()['Account']}:root"}, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow DeployPipelineRole", "Effect": "Allow", "Principal": {"AWS": deploy_role_arn}, "Action": "kms:Encrypt", "Resource": "*" } ] } # Update key policy kms_client.put_key_policy( KeyId=key_id, PolicyName='default', Policy=json.dumps(key_policy) ) print("Note: To fully test this SCP, you'd need to:") print(f"1. Update the SCP to reference this specific key ARN: {key_arn}") print(f"2. Update the SCP to reference this specific role ARN: {deploy_role_arn}") print("3. Assume each role and attempt to encrypt data with the key") print("Encryption should be denied for TestUserRole but allowed for DeployPipelineRole") # Test encryption (this is simplified - would actually need role assumption) test_data = b'Test data for encryption' print("Attempting encryption directly (before SCP is applied):") try: response = kms_client.encrypt( KeyId=key_id, Plaintext=test_data ) print("Successfully encrypted data") except Exception as e: print(f"Error encrypting data: {e}") # Clean up try: # Schedule key deletion kms_client.schedule_key_deletion( KeyId=key_id, PendingWindowInDays=7 ) iam_client.delete_role(RoleName='DeployPipelineRole') iam_client.delete_role(RoleName='TestUserRole') print("Scheduled key deletion and cleaned up roles") except Exception as e: print(f"Error during cleanup: {e}") except Exception as e: print(f"Error in test setup: {e}")