Back to blog
AWSBest PracticesCloud SecurityOperations & ComplianceStorage

Glue Security Config S3 Encryption Disabled: Why It Matters and How to Fix It

Learn why disabled S3 encryption in AWS Glue security configurations exposes ETL data, and how to fix it with CLI, Terraform, and CI/CD policy gates.

TL;DR

This check flags AWS Glue security configurations that leave S3 encryption disabled for job data, meaning intermediate ETL output and temporary files can land in S3 unencrypted. Fix it by creating a security configuration with S3 encryption enabled (SSE-S3 or SSE-KMS) and attaching it to your Glue jobs.

AWS Glue moves a lot of data around. Between the source store, the temporary scratch space, and the destination, your ETL jobs write intermediate files to Amazon S3 constantly. A Glue security configuration controls how that data is protected at rest. When the S3 encryption option in that configuration is turned off, Glue writes job data to S3 without enforcing encryption, which can expose sensitive records sitting in temporary directories and shuffle files.

This check, glue_s3encryption, looks at your Glue security configurations and reports any that do not enable S3 encryption for job data.


What this check detects

A Glue security configuration is a reusable object that defines encryption settings for three things:

  • S3 encryption for data written to S3 by your jobs, crawlers, and development endpoints
  • CloudWatch logs encryption for the logs those jobs produce
  • Job bookmark encryption for the state Glue uses to track processed data

This check specifically inspects the S3 encryption block. If S3Encryption.S3EncryptionMode is set to DISABLED (or the security configuration has no S3 encryption defined at all), the check fails. A passing configuration uses either SSE-S3 or SSE-KMS.

Note: A Glue security configuration only takes effect when it is attached to a job, crawler, or development endpoint. You can have a perfectly encrypted security configuration that protects nothing because no job references it. This check focuses on the configuration itself, but keep the attachment step in mind during remediation.


Why it matters

It is easy to assume that because your source and destination buckets are encrypted, the whole pipeline is covered. That assumption misses the middle of the journey. During a Glue job run, the service writes shuffle data, spill files, and temporary outputs to S3. That scratch data often contains the same sensitive fields as your production records: customer PII, payment data, health records, anything your ETL touches.

If S3 encryption is disabled in the security configuration, Glue does not force server-side encryption on those writes. The objects rely entirely on whatever bucket-level default the temporary bucket happens to have. In practice, Glue temporary buckets are frequently created quickly and left with loose settings.

The concrete risks:

  • Unencrypted data at rest. Temporary objects holding sensitive data sit in S3 with no encryption enforced by Glue.
  • Compliance gaps. PCI DSS, HIPAA, and many internal controls require encryption at rest for sensitive data across the entire processing path, not just the endpoints.
  • Weaker audit and access control. Using SSE-KMS adds a CloudTrail record for every decrypt operation and lets you restrict who can read the data through key policies. Disabled encryption gives you none of that.
  • Blast radius if a bucket is exposed. A misconfigured bucket policy on a temporary Glue bucket combined with unencrypted data is a clean path to a leak.

Warning: Enabling encryption on a security configuration does not retroactively encrypt files that previous job runs already wrote. If you have been running ETL on sensitive data without encryption, treat the existing temporary objects as exposed and clean them up.


How to fix it

You cannot edit a Glue security configuration in place. They are immutable once created, so the fix is to create a new one with S3 encryption enabled, then point your jobs at it.

Step 1: Decide on an encryption mode

You have two options:

  • SSE-S3 uses S3-managed keys. Simple, no key management, no extra cost.
  • SSE-KMS uses a KMS key you control. Gives you per-operation audit logging and fine-grained access control through key policies. Recommended for sensitive workloads.

Step 2: Create the security configuration with SSE-KMS

Using the CLI, create a configuration that turns on S3 encryption with a KMS key:

aws glue create-security-configuration \
  --name "etl-encrypted-config" \
  --encryption-configuration '{
    "S3Encryption": [
      {
        "S3EncryptionMode": "SSE-KMS",
        "KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/abcd1234-5678-90ab-cdef-EXAMPLE11111"
      }
    ],
    "CloudWatchEncryption": {
      "CloudWatchEncryptionMode": "SSE-KMS",
      "KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/abcd1234-5678-90ab-cdef-EXAMPLE11111"
    },
    "JobBookmarksEncryption": {
      "JobBookmarksEncryptionMode": "CSE-KMS",
      "KmsKeyArn": "arn:aws:kms:us-east-1:111122223333:key/abcd1234-5678-90ab-cdef-EXAMPLE11111"
    }
  }'

If you prefer SSE-S3 (no KMS key needed), the S3 block is simpler:

{
  "S3Encryption": [
    {
      "S3EncryptionMode": "SSE-S3"
    }
  ]
}

Step 3: Grant Glue access to the KMS key

If you went with SSE-KMS, the Glue job's IAM role needs permission to use the key, and the key policy must allow the role. Add these actions to the role:

{
  "Effect": "Allow",
  "Action": [
    "kms:Decrypt",
    "kms:Encrypt",
    "kms:GenerateDataKey",
    "kms:DescribeKey"
  ],
  "Resource": "arn:aws:kms:us-east-1:111122223333:key/abcd1234-5678-90ab-cdef-EXAMPLE11111"
}

Step 4: Attach the configuration to your jobs

Update each job to reference the new security configuration:

aws glue update-job \
  --job-name "daily-customer-etl" \
  --job-update '{
    "Role": "arn:aws:iam::111122223333:role/GlueETLRole",
    "Command": {
      "Name": "glueetl",
      "ScriptLocation": "s3://my-scripts/daily-customer-etl.py",
      "PythonVersion": "3"
    },
    "SecurityConfiguration": "etl-encrypted-config"
  }'

Warning: update-job replaces the job definition with the values you supply. Pull the current definition first with aws glue get-job --job-name daily-customer-etl and merge in the SecurityConfiguration field so you do not drop existing settings like worker type, timeout, or default arguments.

Step 5: Clean up the old configuration

Once nothing references the old configuration, delete it so it does not get reused.

Danger: Confirm that no job, crawler, or development endpoint still references the configuration before deleting it. Deleting one that is in use will cause those runs to fail. Check with aws glue get-jobs and filter on the SecurityConfiguration field first.

aws glue delete-security-configuration --name "old-plaintext-config"

Fixing it with infrastructure as code

If you manage Glue through Terraform, define the security configuration with encryption on and reference it from your jobs. This makes the encrypted state the default for everything you deploy.

resource "aws_glue_security_configuration" "etl" {
  name = "etl-encrypted-config"

  encryption_configuration {
    s3_encryption {
      s3_encryption_mode = "SSE-KMS"
      kms_key_arn        = aws_kms_key.glue.arn
    }

    cloudwatch_encryption {
      cloudwatch_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" "customer_etl" {
  name                   = "daily-customer-etl"
  role_arn               = aws_iam_role.glue.arn
  security_configuration = aws_glue_security_configuration.etl.name

  command {
    script_location = "s3://my-scripts/daily-customer-etl.py"
    python_version  = "3"
  }
}

Tip: Define one shared encrypted security configuration per environment and reference it from every Glue job module. A single source of truth means a new job cannot be created without encryption, because the module always wires it in.


How to prevent it from happening again

Remediation handles today. Prevention keeps the next job from shipping without encryption.

Gate it in CI/CD

Run policy checks against your IaC before it merges. With a tool like Checkov or OPA/Conftest, you can fail any plan that creates a Glue job without a security configuration, or a configuration with S3 encryption disabled.

A simple Conftest rule against a Terraform plan:

package main

deny[msg] {
  resource := input.resource_changes[_]
  resource.type == "aws_glue_security_configuration"
  s3 := resource.change.after.encryption_configuration[_].s3_encryption[_]
  s3.s3_encryption_mode == "DISABLED"
  msg := sprintf("Glue security config '%s' has S3 encryption disabled", [resource.address])
}

Enforce with an SCP or detective control

Service Control Policies cannot fully express "Glue jobs must use an encrypted security configuration," but you can pair AWS Config with a custom rule, or use a continuous scanner like Lensix, to flag any Glue security configuration that drifts to DISABLED. Run the check on a schedule so a manually created configuration gets caught quickly.

Tip: Bucket-level default encryption on your Glue temporary bucket is a useful backstop. Even if a job somehow runs without an encrypted security configuration, a bucket default of SSE-KMS means new objects still land encrypted. Use it as defense in depth, not a replacement for the security configuration.


Best practices

  • Prefer SSE-KMS for sensitive workloads. The audit trail and access control you get from a customer-managed key are worth the small added complexity.
  • Encrypt all three blocks, not just S3. CloudWatch logs and job bookmarks can both contain sensitive fragments. Turn on encryption for the whole security configuration while you are in there.
  • Use a dedicated KMS key for Glue. A separate key keeps key policies focused and makes it easy to grant exactly the right Glue roles access without overexposing a shared key.
  • Standardize on a single configuration per environment. One named, encrypted configuration referenced everywhere beats a sprawl of one-off configs with inconsistent settings.
  • Clean up temporary buckets. Add lifecycle rules that expire objects in Glue scratch buckets after a short window. Less stale data means less to leak.
  • Scan continuously. A passing check today does not stay passing. Someone will create a new job next quarter. Keep glue_s3encryption running on a schedule so drift surfaces fast.

Encrypting Glue job data is a small change with a real payoff. It closes the gap between your encrypted endpoints, protects the sensitive data that lives briefly in temporary S3 paths, and keeps your ETL pipeline aligned with the compliance controls you already apply everywhere else.