This check flags AWS Glue security configurations that leave CloudWatch log encryption turned off, meaning your ETL job logs land in plaintext. Fix it by setting CloudWatchEncryptionMode to SSE-KMS with a KMS key when you create the security configuration.
AWS Glue runs the kind of jobs that touch your most sensitive data: customer records moving from S3 into Redshift, PII being transformed before it lands in a data lake, financial exports getting normalized for reporting. Those jobs write logs to CloudWatch, and unless you tell Glue otherwise, those logs are stored without encryption at rest.
The Glue Security Config Log Encryption Disabled check (glue_logencryption) looks at each Glue security configuration in your account and verifies that CloudWatch log encryption is enabled. If it isn't, the check fails.
What this check detects
A Glue security configuration is a reusable set of encryption settings you attach to crawlers and jobs. It controls three independent things:
- S3 encryption for data Glue writes to S3
- CloudWatch logs encryption for the job and crawler logs Glue pushes to CloudWatch
- Job bookmark encryption for the state Glue stores between runs
This check specifically inspects the CloudWatch piece. It passes when CloudWatchEncryption.CloudWatchEncryptionMode is set to SSE-KMS and a KMS key is configured. It fails when the mode is DISABLED, which is the default if you never set it.
Note: A security configuration only applies if it is actually attached to a job or crawler. A correctly configured security config that nothing references does nothing, and a job with no security config at all writes unencrypted logs regardless. This check catches the misconfigured configs, so pair it with a review of which jobs reference which configs.
Why it matters
Plaintext logs feel low-risk until you look at what actually ends up in them. Glue job logs routinely contain:
- Sample rows logged during debugging, including values from PII columns
- Schema details, table names, and connection strings
- Query fragments and transformation logic that reveal how sensitive data flows
- Error messages that dump record contents when a transform fails
When CloudWatch log encryption is disabled, those entries sit at rest using only the default AWS-managed storage protection, with no customer-managed KMS key gating access. That has two practical consequences.
First, access control gets coarser. With SSE-KMS, anyone reading the logs needs both CloudWatch Logs permissions and kms:Decrypt on the key. Without it, CloudWatch Logs permissions alone are enough. An over-permissioned IAM role or a compromised read-only user that should never see raw customer data can now read it straight out of the log group.
Second, it breaks compliance posture. Frameworks like PCI DSS, HIPAA, and SOC 2 expect encryption at rest with managed keys for systems that process regulated data. An auditor who finds a Glue pipeline handling cardholder data writing unencrypted logs is going to write a finding, and they will be right to.
Warning: Disabling encryption after data has already been logged does not retroactively encrypt old log streams. Existing plaintext logs stay plaintext. If sensitive data has been logged, plan to expire or delete the affected log streams in addition to fixing the config going forward.
How to fix it
You cannot edit an existing Glue security configuration in place. AWS treats them as immutable, so the fix is to create a new one with encryption enabled and repoint your jobs and crawlers at it. Here is the full sequence.
1. Create or pick a KMS key
You need a KMS key that Glue can use. If you do not already have one, create a customer-managed key:
aws kms create-key \
--description "Glue CloudWatch log encryption" \
--tags TagKey=purpose,TagValue=glue-logs
Note the returned KeyId. Then give the CloudWatch Logs service permission to use the key by adding this statement to the key policy:
{
"Sid": "AllowCloudWatchLogs",
"Effect": "Allow",
"Principal": {
"Service": "logs.us-east-1.amazonaws.com"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:DescribeKey"
],
"Resource": "*",
"Condition": {
"ArnLike": {
"kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:us-east-1:111122223333:log-group:/aws-glue/*"
}
}
}
Note: The service principal is region-specific (logs.us-east-1.amazonaws.com), and the encryption context condition scopes the key so it can only decrypt log groups, not arbitrary data. Adjust the region and account ID to match yours.
2. Create a new security configuration with encryption enabled
aws glue create-security-configuration \
--name glue-encrypted-config \
--encryption-configuration '{
"CloudWatchEncryption": {
"CloudWatchEncryptionMode": "SSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/YOUR-KEY-ID"
},
"S3Encryption": [{
"S3EncryptionMode": "SSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/YOUR-KEY-ID"
}],
"JobBookmarksEncryption": {
"JobBookmarksEncryptionMode": "CSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/YOUR-KEY-ID"
}
}'
This enables all three encryption types at once. If you only want to address the CloudWatch finding, set the other two modes to DISABLED, though encrypting everything is the better default.
3. Point your jobs and crawlers at the new config
Danger: Updating a running production job's security configuration affects future runs and will fail in-flight jobs if applied mid-run. Schedule the change during a maintenance window or between scheduled runs to avoid interrupting active ETL workloads.
# Update a job to use the new security configuration
aws glue update-job \
--job-name my-etl-job \
--job-update '{
"Role": "arn:aws:iam::111122223333:role/GlueJobRole",
"Command": {"Name": "glueetl", "ScriptLocation": "s3://my-bucket/scripts/job.py"},
"SecurityConfiguration": "glue-encrypted-config"
}'
The IAM role attached to the job also needs kms:GenerateDataKey and kms:Decrypt on the key, or the job will fail to write logs.
Console steps
- Open the AWS Glue console and go to Data Integration and ETL > Security configurations.
- Choose Add security configuration.
- Under CloudWatch logs encryption, check the box and select your KMS key.
- Optionally enable S3 and job bookmark encryption with the same key.
- Save, then edit each job and crawler to reference the new configuration.
Terraform
resource "aws_glue_security_configuration" "encrypted" {
name = "glue-encrypted-config"
encryption_configuration {
cloudwatch_encryption {
cloudwatch_encryption_mode = "SSE-KMS"
kms_key_arn = aws_kms_key.glue.arn
}
s3_encryption {
s3_encryption_mode = "SSE-KMS"
kms_key_arn = aws_kms_key.glue.arn
}
job_bookmarks_encryption {
job_bookmarks_encryption_mode = "CSE-KMS"
kms_key_arn = aws_kms_key.glue.arn
}
}
}
resource "aws_glue_job" "etl" {
name = "my-etl-job"
role_arn = aws_iam_role.glue.arn
security_configuration = aws_glue_security_configuration.encrypted.name
command {
script_location = "s3://my-bucket/scripts/job.py"
}
}
How to prevent it from happening again
Catching this once is easy. Keeping it from drifting back is the harder part, because the default for a new security config is unencrypted and developers tend to copy whatever already exists.
Block it in your IaC pipeline before it ships. With Checkov, the relevant rule is built in:
checkov -d . --check CKV_AWS_99
You can also write a focused OPA/Conftest policy against Terraform plan JSON that rejects any Glue security config without CloudWatch encryption:
package glue
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_glue_security_configuration"
cw := resource.change.after.encryption_configuration[_].cloudwatch_encryption[_]
cw.cloudwatch_encryption_mode != "SSE-KMS"
msg := sprintf("Glue security config '%s' has CloudWatch log encryption disabled", [resource.address])
}
Tip: Wire this policy into a CI gate that runs on every pull request touching aws_glue_security_configuration resources. A failing check on the PR is far cheaper than a failing control in an audit three months later. Lensix continuously scans deployed configs too, so you catch the ones created outside Terraform through the console or scripts.
For accounts where you want a hard guardrail, an AWS Config rule or an SCP that denies glue:CreateSecurityConfiguration calls lacking the encryption parameter gives you account-wide enforcement that survives individual team habits.
Best practices
- Encrypt all three layers, not just logs. If you are setting up encryption anyway, turn on S3 and job bookmark encryption with the same key. Bookmarks store offsets and state that can leak schema details, and S3 output is often the sensitive data itself.
- Use customer-managed KMS keys, not the default AWS-managed key. Customer-managed keys let you control rotation, audit usage through CloudTrail, and revoke access by editing the key policy. That extra control is the whole point of encrypting in the first place.
- Set a retention policy on Glue log groups. Encryption protects logs at rest, but the safest sensitive data is the data you no longer keep. Apply a retention period to
/aws-glue/*log groups so old logs expire automatically. - Audit which jobs reference which config. Run
aws glue get-jobsand confirm every job has aSecurityConfigurationset. A correctly encrypted config helps nobody if half your jobs ignore it. - Standardize on one or two named configs per account. Sprawl of one-off security configs is how the unencrypted ones slip in. Fewer, well-named, encrypted configs are easier to govern.
Encryption at rest for Glue logs is a low-effort, high-value control. It costs you a KMS key and a few minutes of setup, and in return it tightens access control on data that you probably never intended to expose in plaintext in the first place.

