You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨账号CodeBuild同步至SSE-KMS加密S3时遇AccessDenied错误

问题描述

使用场景

通过部署在us-west-2区域、包含CodeCommit和CodeBuild阶段的AWS CodePipeline,将Beta账号CodeCommit仓库的文件同步至us-east-1区域的Prod账号S3存储桶,buildspec.yml文件中包含复制/同步文件的命令。

错误信息

上传失败:jam/bie/core_pipeline/folding.json 至 s3://temp-bucket-aev/temp/folding.json,调用PutObject操作时发生(AccessDenied)错误:权限拒绝。

现象

  • 将存储桶加密类型改为SSE-S3(亚马逊S3托管密钥服务端加密)时,错误消失;
  • 切换为SSE-KMS(AWS密钥管理服务密钥服务端加密)时,错误重现。

账号配置详情

A. Beta账号:xxxxxxxxx

A.1 IAM角色:cicdBuildRole

A.1.1 IAM策略:s3crossaccountaccess_temp

{"Version": "2012-10-17","Statement": [{"Sid": "AllowCrossAccountAccess","Effect": "Allow","Action": "s3:PutObject","Resource": "arn:aws:s3:::temp-bucket-aev/*","Condition": {"StringEquals": {"aws:SourceAccount": "<prod_account_number>"}}}]}

A.1.2 IAM策略:cross_account_access_for_code_build

{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": "sts:AssumeRole","Resource": "arn:aws:iam::<prod_account_number>:role/cicdCrossAccountRole"}]}

A.1.3 IAM托管策略

  • AmazonS3FullAccess
  • AWSCodeCommitReadOnly
  • AWSCodeBuildReadOnlyAccess

A.1.4 信任关系

{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "codebuild.amazonaws.com"},"Action": "sts:AssumeRole"}]}

A.2 角色:codePipelineServiceRole

IAM策略:CodePipelineRolePolicy

{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject*","s3:GetBucket*","s3:List*","s3:DeleteObject*","s3:PutObject","s3:PutObjectLegalHold","s3:PutObjectRetention","s3:PutObjectTagging","s3:PutObjectVersionTagging","s3:Abort*"],"Resource": ["arn:aws:s3:::artifact-beta-cicd-us-west-2","arn:aws:s3:::artifact-beta-cicd-us-west-2/*"],"Effect": "Allow"},{"Action": "sts:AssumeRole","Resource": "arn:aws:iam::<prod_account_number>:role/pipeline-beta-CIC-CodePipelineSourceCodeCo-1R53MXYY2ECRC","Effect": "Allow"},{"Action": "sts:AssumeRole","Resource": "arn:aws:iam::<prod_account_number>:role/pipeline-beta-CIC-CodePipelineBuildCodeBui-73K6MQ3LCRG7","Effect": "Allow"}]}

信任关系

{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "codepipeline.amazonaws.com"},"Action": "sts:AssumeRole"}]}

A.3 buildspec.yml

version: 0.2

env:
  variables:

phases:
  build:
    commands:
      - echo "Sync files from the CodeCommit repo to the S3 bucket."

  post_build:
    commands:
      - echo "Syncing changed files from CodeCommit repo to S3 bucket in the Beta account..."

      # Copy files from CodeCommit repo to S3 bucket in the Prod account
      - echo "Syncing files from CodeCommit repo to S3 bucket in the Prod account..."
      - aws s3 sync jam/bie/core_pipeline/ s3://temp-bucket-aev/temp/ --region us-east-1

artifacts:
  files:
    - '**/*'

B. Prod账号:yyyyyyyyyy

S3存储桶:arn:aws:s3:::temp-bucket-aev

IAM角色:cicdCrossAccountRole

IAM策略:temp_policy_code_pipeline

{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": ["codecommit:List*","codecommit:Get*","codecommit:GitPull","codebuild:StartBuild","s3:PutObject","s3:GetObject","s3:ListBucket"],"Resource": ["arn:aws:codecommit:us-west-2:<beta-account-number>:CodeRepo","arn:aws:s3:::temp-bucket-aev/*"]}]}

存储桶策略:temp-bucket-aev

{"Version": "2012-10-17","Statement": [{"Sid": "AllowCrossAccountAccess","Effect": "Allow","Principal": {"AWS": "arn:aws:iam::<beta-account-number>:role/cicdBuildRole"},"Action": ["s3:PutObject","s3:GetObject","s3:ListBucket"],"Resource": ["arn:aws:s3:::temp-bucket-aev/*","arn:aws:s3:::temp-bucket-aev"]}]}

加密类型

采用AWS密钥管理服务密钥进行服务端加密(SSE-KMS)

KMS密钥策略(ARN:arn:aws:kms:us-east-1:<prod_account_number>:key/zzz-zzzz-000-2222-ttttttt)

{"Version": "2012-10-17","Id": "key-policy","Statement": [{"Sid": "AllowRootAndCICDAccess","Effect": "Allow","Principal": {"AWS": ["arn:aws:iam::<prod_account_number>:role/cicdCrossAccountRole","arn:aws:iam::<prod_account_number>:root"]},"Action": ["kms:Decrypt","kms:Encrypt","kms:ReEncrypt*","kms:GenerateDataKey*","kms:DescribeKey"],"Resource": "*"},{"Sid": "AllowRootAccess","Effect": "Allow","Principal": {"AWS": "arn:aws:iam::<prod_account_number>:root"},"Action": "kms:*","Resource": "*"},{"Sid": "AllowCloudWatchLogsAccess","Effect": "Allow","Principal": {"Service": "logs.us-east-1.amazonaws.com"},"Action": ["kms:Encrypt*","kms:Decrypt*","kms:ReEncrypt*","kms:GenerateDataKey*","kms:Describe*"],"Resource": "*","Condition": {"StringEquals": {"kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:us-east-1:*:*"}}}]}

已尝试操作

修改KMS密钥策略并尝试多种策略组合,但问题仍未解决。


解决方案

问题核心是KMS密钥权限缺失:当前KMS密钥策略仅授权了Prod账号的cicdCrossAccountRole,但实际执行s3 sync的是Beta账号的cicdBuildRole,该角色未被允许使用目标KMS密钥。

修复步骤

  1. 更新Prod账号的KMS密钥策略
    在AllowRootAndCICDAccess语句的Principal列表中加入Beta账号的cicdBuildRole ARN:
{"Sid": "AllowRootAndCICDAccess","Effect": "Allow","Principal": {"AWS": [
    "arn:aws:iam::<prod_account_number>:role/cicdCrossAccountRole",
    "arn:aws:iam::<prod_account_number>:root",
    "arn:aws:iam::<beta-account-number>:role/cicdBuildRole" // 添加该行
]},"Action": ["kms:Decrypt","kms:Encrypt","kms:ReEncrypt*","kms:GenerateDataKey*","kms:DescribeKey"],"Resource": "*"}
  1. 补充Beta账号角色的KMS权限
    在Beta账号cicdBuildRole的IAM策略中添加KMS操作权限:
{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": ["kms:GenerateDataKey*","kms:Encrypt"],"Resource": "arn:aws:kms:us-east-1:<prod_account_number>:key/zzz-zzzz-000-2222-ttttttt"}]}

原理说明

当S3使用SSE-KMS加密时,执行PutObject操作的身份不仅需要S3的PutObject权限,还需要对应KMS密钥的GenerateDataKey和Encrypt权限——因为S3会调用KMS生成数据密钥来加密对象。之前Beta账号的角色缺少这部分权限,导致权限拒绝错误。

内容的提问来源于stack exchange,提问作者datacookie93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:52:01