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 Antworten
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
beantwortet vor 5 Monaten
  • 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

beantwortet vor 5 Monaten
0

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

beantwortet vor 5 Monaten

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen