sops icon indicating copy to clipboard operation
sops copied to clipboard

SOPS 3.11 unable to encrypt a file with encryption context on AWS KMS

Open shearn89 opened this issue 2 months ago • 8 comments

I have a KMS key set up with an alias, and a policy that requires an encryption context. Using 3.11.0, I'm unable to encrypt a fresh file:

❯ sops --verbose -i -e --encryption-context AppName:vantage values.encrypted.yaml
[AWSKMS]         INFO[0000] Encryption failed                             arn="arn:aws:kms:eu-west-2:123412341234:alias/shearn89-sandbox-myapp-sops"
Could not generate data key: [failed to encrypt new data key with master key "arn:aws:kms:eu-west-2:123412341234:alias/shearn89-sandbox-myapp-sops": failed to encrypt sops data key with AWS KMS: operation error KMS: Encrypt, https response error StatusCode: 400, RequestID: guid, api error AccessDeniedException: User: arn:aws:iam::123412341234:user/alex.shearn is not authorized to perform: kms:Encrypt on resource: arn:aws:kms:eu-west-2:123412341234:key/key-guid with an explicit deny in a resource-based policy]

If I remove the context statement, it works. If I downgrade to 3.10.2, it also works...

Policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Delegate access to IAM",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123412341234:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Explicitly require encryption context for enc/decrypt operations, overriding IAM",
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:Encrypt",
        "kms:Decrypt"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "kms:EncryptionContext:AppName": "myapp"
        }
      }
    }
  ]
}

shearn89 avatar Oct 13 '25 13:10 shearn89

This works for me:

export AWS_PROFILE=sso-demo
sops encrypt \
  --encrypted-regex '^(data|stringData)$' \
  --in-place \
  --kms arn:aws:kms:eu-west-2:<redacted>:key/<redacted> \
  --encryption-context foo:bar \
  secret.yaml

Result:

apiVersion: v1
kind: Secret
metadata:
    name: flux-github-app-demo-app
    namespace: flux-system
    labels:
        reconcile.fluxcd.io/watch: Enabled
type: Opaque
stringData:
    githubAppID: <redacted>
    githubAppInstallationID: <redacted>
    githubAppPrivateKey: <redacted>
sops:
    kms:
        - arn: arn:aws:kms:eu-west-2:<redacted>:key/<redacted>
          context:
            foo: bar
          created_at: "2025-10-21T13:07:05Z"
          enc: <redacted>
          aws_profile: ""
    lastmodified: "2025-10-21T13:07:06Z"
    mac: <redacted>
    encrypted_regex: ^(data|stringData)$
    version: 3.11.0

Decryption also works:

sops decrypt --in-place secret.yaml

Result:

apiVersion: v1
kind: Secret
metadata:
    name: flux-github-app-demo-app
    namespace: flux-system
    labels:
        reconcile.fluxcd.io/watch: Enabled
type: Opaque
stringData:
    githubAppID: <redacted>
    githubAppInstallationID: <redacted>
    githubAppPrivateKey: |
        <redacted>

matheuscscp avatar Oct 21 '25 13:10 matheuscscp

Would you mind sharing a redacted snippet of the KMS key policy applied to the key, I wonder if that's my problem?

shearn89 avatar Oct 21 '25 15:10 shearn89

Here you go:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Enable IAM User Permissions",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::<redacted>:root"
			},
			"Action": "kms:*",
			"Resource": "*"
		},
		{
			"Sid": "Allow kustomize-controller to decrypt using the key",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::<redacted>:role/flux-d2-kustomize-controller"
			},
			"Action": [
				"kms:Decrypt",
				"kms:DescribeKey"
			],
			"Resource": "*"
		}
	]
}

matheuscscp avatar Oct 21 '25 15:10 matheuscscp

This is more likely caused by a dependency upgrade (i.e. some behavior change in Amazon's SDK).

felixfontein avatar Oct 21 '25 16:10 felixfontein

Okay - work is busy this week but if I get time I’ll try and build from source so I can do a git bisect to find the issue…

shearn89 avatar Oct 21 '25 17:10 shearn89

Okay - ran a git bisect, and https://github.com/getsops/sops/commit/84c767353ad56976a6b1170d474895cd83ce24b7 is the first bad commit.

shearn89 avatar Oct 22 '25 09:10 shearn89

Introduced in #1939, @felixfontein.

shearn89 avatar Oct 22 '25 09:10 shearn89

Happy to help with testing any branch fixes, or setting up example keys/policies. The policy in the first post is what we use, and then we set --encryption-context AppName:myapp on first encryption.

shearn89 avatar Oct 22 '25 09:10 shearn89

Hi - any chance this can be investigated? The git bisect clearly shows where the bug was introduced, and I've included an example KMS policy to require the context being passed.

I will try and get time myself but I'm not familiar with the code base.

shearn89 avatar Dec 16 '25 09:12 shearn89

The policy linked here doesn't actually Deny if the context is missing, so it passes anyway. The policy in my original post does Deny, hence the failure.

shearn89 avatar Dec 16 '25 09:12 shearn89

Hi - any chance this can be investigated? The git bisect clearly shows where the bug was introduced, and I've included an example KMS policy to require the context being passed.

I had this on my list of things to look at, but there was too much going on in the last months and I forgot about it... Sorry. I'm glad you were able to create a PR to fix t.

felixfontein avatar Dec 16 '25 20:12 felixfontein