Skip to content

Permissions for publishing

Let the deploy project write to your website bucket, and check that the pipeline can start both builds.

About 15 min · Verified 8 October 2026

0 of 4 steps done0%

Three different identities touch your website, and each needs a different permission. Mixing them up is the most common reason the first deploy fails.

IdentityNeedsWhere it is granted
Anyone on the internetRead files (s3:GetObject)The bucket policy (guide 1, chapter 8)
The shortlink-web-deploy project's roleList, write and delete objects in your bucketAn inline policy on that role (this chapter)
The pipeline's service roleStart both CodeBuild projectsThe pipeline role (checked here)

Find the role name#

Look up the deploy project's service role#

Your computerWhich role does the deploy project run as?
aws codebuild batch-get-projects --region ap-south-1 --names shortlink-web-deploy \
  --query 'projects[0].serviceRole' --output text

The last part of the ARN is the role name, normally codebuild-shortlink-web-deploy-service-role.

Let it write to the bucket#

Add the inline policy#

Open IAMRolescodebuild-shortlink-web-deploy-service-rolePermissionsAdd permissionsCreate inline policyJSON. Name it shortlink-web-deploy-website-sync.

Paste in the AWS consoleshortlink-web-deploy-website-sync
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::<WEB_BUCKET>"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::<WEB_BUCKET>/*"
    }
  ]
}

Replace <WEB_BUCKET> with your own value (or fill in the known ones once under My values at the top of the page).

Two statements are needed because ListBucket applies to the bucket ARN (…:bucket), while the object actions apply to the objects (…:bucket/*). aws s3 sync lists first to work out what changed, and --delete needs DeleteObject. Without the first statement you get a confusing AccessDenied on ListObjectsV2.

Check the role can also read the pipeline artifact#

The role that the wizard created for this project normally includes read access to the codepipeline-<region>-… bucket. Verify:

Your computerList the role's policies
aws iam list-attached-role-policies --role-name codebuild-shortlink-web-deploy-service-role --output table
aws iam list-role-policies --role-name codebuild-shortlink-web-deploy-service-role --output table
You should see
An attached policy named like CodeBuildBasePolicy-shortlink-web-deploy-<region> (logs and artifact bucket), and your inline shortlink-web-deploy-website-sync.
Deploy fails with AccessDenied on the artifact bucket

Add this inline policy to the same role, naming it shortlink-web-deploy-artifacts-read:

Paste in the AWS consoleshortlink-web-deploy-artifacts-read
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketLocation"],
      "Resource": ["arn:aws:s3:::<ARTIFACT_BUCKET>", "arn:aws:s3:::<ARTIFACT_BUCKET>/*"]
    }
  ]
}

Replace <ARTIFACT_BUCKET> with your own value (or fill in the known ones once under My values at the top of the page).

Find the bucket with aws codepipeline get-pipeline --name shortlink-web-prod --query pipeline.artifactStore.location --output text.

Let the pipeline start both builds#

Add an inline policy to the pipeline role#

The wizard grants codebuild:StartBuild for the project you created in it. When you added the second project in the editor the console may not have extended the policy. If the pipeline role cannot start a project, the action fails in CodePipeline before any CodeBuild log exists, which is confusing. Adding this is harmless if it is already allowed.

Find the role: aws codepipeline get-pipeline --region ap-south-1 --name shortlink-web-prod --query pipeline.roleArn --output text. Then IAMRoles(that role)PermissionsAdd permissionsCreate inline policyJSON, name shortlink-web-start-builds:

Paste in the AWS consoleshortlink-web-start-builds
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["codebuild:StartBuild", "codebuild:BatchGetBuilds"],
      "Resource": [
        "arn:aws:codebuild:ap-south-1:<AWS_ACCOUNT_ID>:project/shortlink-web-build",
        "arn:aws:codebuild:ap-south-1:<AWS_ACCOUNT_ID>:project/shortlink-web-deploy"
      ]
    }
  ]
}

Replace <AWS_ACCOUNT_ID> with your own value (or fill in the known ones once under My values at the top of the page).

What each failure means#

Error textIdentity to fix
AccessDenied on s3:ListBucket, PutObject or DeleteObject in the WebDeploy logcodebuild-shortlink-web-deploy-service-role
not authorized to perform: codebuild:StartBuild with no CodeBuild logThe pipeline service role
The site returns 403 after a successful deployThe bucket policy (public read), not the roles
AccessDenied listing a bucket you do not ownThe buildspec still points at someone else's bucket. Redo the previous chapter

Next: run the first release.

Found a mistake? Edit this page on GitHub.