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 個答案
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
已回答 5 個月前
  • 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

已回答 5 個月前
0

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

已回答 5 個月前

您尚未登入。 登入 去張貼答案。

一個好的回答可以清楚地回答問題並提供建設性的意見回饋,同時有助於提問者的專業成長。

回答問題指南