Cloudfront OAC with KMS Key cross-account

2

Hello everyone,

I'm struggling with my CF distribution for a static website hosted in an S3 bucket.

I have two accounts, saying A and B. Account A contains:

  • The S3 bucket
  • The CF distribution

Account B contains:

  • The KMS key

I have followed the documentation here : https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

But I'm getting the following error when accessing website:

<Error>
<Code>AccessDenied</Code>
<Message>
User: arn:aws:sts::856369053181:assumed-role/OriginAccessControlRole/EdgeCredentialsProxy+EdgeHostAuthenticationClient-MRS52-P6 is not authorized to perform: kms:Decrypt on the resource associated with this ciphertext because the resource does not exist in this Region, no resource-based policies allow access, or a resource-based policy explicitly denies access
</Message>
<RequestId>JWRSJ6EC33SHND8A</RequestId>
<HostId>
WzjKcgu8DTTXe4rfZyfMWzDlFah8sVFS6T3DY8TvqrSIe8GhnFToSmAK2U+77sJFtDF8ad+xtqM=
</HostId>
</Error>

To details, my bucket is encrypted with SSE-KMS, bucket owner enforced, no public access. The CF distribution has an OAC in always sign mode (with override), and use the policy CachingOptimized, CORS-S3Origin and SecurityHeadersPolicy. It also has a CF function that is used for basic auth.

S3 bucket policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipalReadOnly",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<bucket name>/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::<ACCOUNT A ID>:distribution/<DISTRIBUTION ID>"
                }
            }
        }
    ]
}

CF function

function handler(event) {
    const authorizationHeader = event.request.headers.authorization;
    const preferredAuthorization = "Basic xxxxxxxx";
    if (authorizationHeader !== undefined && authorizationHeader.value === preferredAuthorization) {
        return event.request;
    }
    return {
        statusCode: 401,
        statusDescription: "Unauthorized",
        headers: {
            "www-authenticate": { value: 'Basic realm="Connect"' },
        },
    };
}

KMS policy

 {
            "Sid": "AllowCloudFrontServicePrincipalSSE-KMS for home account",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com",
                "AWS": "arn:aws:iam::<ACCOUNT A ID>:root"
            },
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:GenerateDataKey*"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::<ACCOUNT A ID>:distribution/<DISTRIBUTION ID>"
                }
            }
        }
3 Answers
0

Hello Guillaume,

You forgot to censor your account id in the errormessage.

Looking at the arn inside your errormessage and the arn inside your kms-key-policy => they are different.

Can you try to add that arn you get in the errormessage into the kms key policy and try again?

Thanks in advance

Heiko

profile picture
HeikoMR
answered 4 months ago
  • Hello,

    Thank you for your answer. I didn't censor the account id because it is not mine, it is probably something on AWS side used by CloudFront

    Sometimes I have another error (without changing anything).

    <Error>
    <Code>AccessDenied</Code>
    <Message>
    User: arn:aws:sts::856369053181:assumed-role/OriginAccessControlRole/OriginAccessSession is not authorized to perform: kms:Decrypt on the resource associated with this ciphertext because the resource does not exist in this Region, no resource-based policies allow access, or a resource-based policy explicitly denies access
    </Message>
    <RequestId>41NJFKHDCCXWS3EJ</RequestId>
    <HostId>
    nPA10pJGuaKdquJ3iGLsGdwCjBFw7LN8ylbSG8KN6iPFO1YzLPIXgt++Jqn61UUlsrP58uZn7PY=
    </HostId>
    </Error>
    

    Still not my account.

  • Hello Heiko, I'm having the same issue and tried adding an AWS principal with the ARN of the blocked sts session but it still does not solve the problem.

  • Guillaume did you ever figure it out?

0

I have tried to do the same thing but using the account where the key is and I have the same problem so I probably forget something but I don't know what

Maybe I can share my terraform code

answered 4 months ago
0

My terraform code is available here https://github.com/guillomep/tf-static-website/

answered 4 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions