Skip to content

fix: use canonical channel site S3 IAM actions - #46

Merged
xnoto merged 1 commit into
mainfrom
fix/channel-project-s3-iam-action-names
Sep 4, 2026
Merged

fix: use canonical channel site S3 IAM actions#46
xnoto merged 1 commit into
mainfrom
fix/channel-project-s3-iam-action-names

Conversation

@xnoto

@xnoto xnoto commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace eight API-shaped S3 action strings with their canonical IAM action names in the existing two-bucket-scoped ManageSiteBuckets statement.

After PR #45 applied, the consumer plan reached the accelerate read and AWS rejected s3:GetBucketAccelerateConfiguration; the required IAM action is s3:GetAccelerateConfiguration. The same API-to-IAM naming pattern affects CORS, encryption, lifecycle, and replication. This corrects the read actions and the already-required encryption/lifecycle write actions without widening bucket scope or adding capabilities.

Fixes # N/A — recovery prerequisite for channel-project PR #15.

Type of change

  • Bug fix
  • Feature / enhancement
  • Documentation
  • Infrastructure (OpenTofu root or module)
  • GitOps desired state (manifests, kustomize, charts, SOPS/KSOPS secrets)
  • Container image
  • CI / reusable workflow
  • Refactor / cleanup
  • Breaking change

Validation

  • Required pull-request checks pass — pending.
  • Generated or centrally distributed files were regenerated by their owning automation, not hand-edited — no generated files are affected.

No local OpenTofu, state, import, plan, or apply operation was run or claimed. The consumer plan evidence, current AWS provider source, and AWS API permission documentation were used to verify the API-to-IAM-action mapping.

Impact and rollout

Producer: tfroot-aws owns the channel-project infrastructure role and inline policy. Consumer: channel-project/tofu/aws assumes that role through the reusable OpenTofu workflow.

After merge and the environment-gated main apply, rerun the channel-project plan. It must complete its bucket refresh without access-denied errors and must not replace existing buckets. This change does not create/delete buckets, upload site assets, create CloudFront, issue certificates, or alter DNS.

Rollback before apply is closing/reverting this PR. If applied, reverting restores noncanonical action names and should not occur while the consumer root needs refresh/configuration access.

Safety and secrets

  • Contains no plaintext secrets, decrypted SOPS values, state files, kubeconfigs, tokens, or private endpoints
  • No local OpenTofu init/plan/apply/destroy/import/state operations were run or claimed — plans come from pull-request checks
  • Breaking or irreversible effects are described above with rollback notes

AI agent materially produced this change; reviewers should verify that every replacement action remains confined to the two project-owned bucket ARNs and corresponds to the existing OpenTofu resource read/update operations.

@xnoto
xnoto requested a review from a team as a code owner September 4, 2026 19:19
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

OpenTofu Test

OpenTofu test passed.

View the workflow run.

View run output
Terraform validate.......................................................Passed
Terraform validate with tflint...........................................Passed
Checkov..................................................................Passed
Terraform fmt............................................................Passed
Terraform docs...........................................................Passed
Detect hardcoded secrets.................................................Passed
check for case conflicts.................................................Passed
check for merge conflicts................................................Passed
check for broken symlinks............................(no files to check)Skipped
check vcs permalinks.....................................................Passed
detect destroyed symlinks................................................Passed
detect private key.......................................................Passed
fix end of files.........................................................Passed
mixed line ending........................................................Passed
trim trailing whitespace.................................................Passed
don't commit to branch..................................................Skipped
check for added large files..............................................Passed

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

OpenTofu Plan

OpenTofu plan passed.

View the workflow run.

View run output
OpenTofu will perform the following actions:

  # aws_iam_role_policy.github_actions_channel_project_site_infrastructure will be updated in-place
  ~ resource "aws_iam_role_policy" "github_actions_channel_project_site_infrastructure" {
        id     = "github-actions-channel-project-site-infrastructure:channel-project-site-infrastructure"
        name   = "channel-project-site-infrastructure"
      ~ policy = jsonencode(
          ~ {
              ~ Statement = [
                    # (3 unchanged elements hidden)
                    {
                        Action   = [
                            "s3:CreateBucket",
                        ]
                        Effect   = "Allow"
                        Resource = "*"
                        Sid      = "CreateSiteBuckets"
                    },
                  ~ {
                      ~ Action   = [
                            # (1 unchanged element hidden)
                            "s3:DeleteBucketPolicy",
                          - "s3:GetBucketAccelerateConfiguration",
                          + "s3:GetAccelerateConfiguration",
                            "s3:GetBucketAcl",
                          - "s3:GetBucketCors",
                          - "s3:GetBucketEncryption",
                          - "s3:GetBucketLifecycleConfiguration",
                          + "s3:GetBucketCORS",
                            "s3:GetBucketLocation",
                            # (4 unchanged elements hidden)
                            "s3:GetBucketPublicAccessBlock",
                          - "s3:GetBucketReplication",
                            "s3:GetBucketRequestPayment",
                            # (2 unchanged elements hidden)
                            "s3:GetBucketWebsite",
                          + "s3:GetEncryptionConfiguration",
                          + "s3:GetLifecycleConfiguration",
                          + "s3:GetReplicationConfiguration",
                            "s3:ListBucket",
                            "s3:PutBucketAcl",
                          - "s3:PutBucketEncryption",
                          - "s3:PutBucketLifecycleConfiguration",
                            "s3:PutBucketOwnershipControls",
                            # (3 unchanged elements hidden)
                            "s3:PutBucketVersioning",
                          + "s3:PutEncryptionConfiguration",
                          + "s3:PutLifecycleConfiguration",
                        ]
                        # (3 unchanged attributes hidden)
                    },
                    {
                        Action   = [
                            "cloudfront:CreateOriginAccessControl",
                            "cloudfront:DeleteOriginAccessControl",
                            "cloudfront:GetOriginAccessControl",
                            "cloudfront:GetOriginAccessControlConfig",
                            "cloudfront:ListOriginAccessControls",
                            "cloudfront:UpdateOriginAccessControl",
                        ]
                        Effect   = "Allow"
                        Resource = "*"
                        Sid      = "ManageSiteOriginAccessControl"
                    },
                    # (2 unchanged elements hidden)
                ]
                # (1 unchanged attribute hidden)
            }
        )
        # (1 unchanged attribute hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
OpenTofu will perform the following actions:

  # aws_iam_role_policy.github_actions_channel_project_site_infrastructure will be updated in-place
  ~ resource "aws_iam_role_policy" "github_actions_channel_project_site_infrastructure" {
        id     = "github-actions-channel-project-site-infrastructure:channel-project-site-infrastructure"
        name   = "channel-project-site-infrastructure"
      ~ policy = jsonencode(
          ~ {
              ~ Statement = [
                    # (3 unchanged elements hidden)
                    {
                        Action   = [
                            "s3:CreateBucket",
                        ]
                        Effect   = "Allow"
                        Resource = "*"
                        Sid      = "CreateSiteBuckets"
                    },
                  ~ {
                      ~ Action   = [
                            # (1 unchanged element hidden)
                            "s3:DeleteBucketPolicy",
                          - "s3:GetBucketAccelerateConfiguration",
                          + "s3:GetAccelerateConfiguration",
                            "s3:GetBucketAcl",
                          - "s3:GetBucketCors",
                          - "s3:GetBucketEncryption",
                          - "s3:GetBucketLifecycleConfiguration",
                          + "s3:GetBucketCORS",
                            "s3:GetBucketLocation",
                            # (4 unchanged elements hidden)
                            "s3:GetBucketPublicAccessBlock",
                          - "s3:GetBucketReplication",
                            "s3:GetBucketRequestPayment",
                            # (2 unchanged elements hidden)
                            "s3:GetBucketWebsite",
                          + "s3:GetEncryptionConfiguration",
                          + "s3:GetLifecycleConfiguration",
                          + "s3:GetReplicationConfiguration",
                            "s3:ListBucket",
                            "s3:PutBucketAcl",
                          - "s3:PutBucketEncryption",
                          - "s3:PutBucketLifecycleConfiguration",
                            "s3:PutBucketOwnershipControls",
                            # (3 unchanged elements hidden)
                            "s3:PutBucketVersioning",
                          + "s3:PutEncryptionConfiguration",
                          + "s3:PutLifecycleConfiguration",
                        ]
                        # (3 unchanged attributes hidden)
                    },
                    {
                        Action   = [
                            "cloudfront:CreateOriginAccessControl",
                            "cloudfront:DeleteOriginAccessControl",
                            "cloudfront:GetOriginAccessControl",
                            "cloudfront:GetOriginAccessControlConfig",
                            "cloudfront:ListOriginAccessControls",
                            "cloudfront:UpdateOriginAccessControl",
                        ]
                        Effect   = "Allow"
                        Resource = "*"
                        Sid      = "ManageSiteOriginAccessControl"
                    },
                    # (2 unchanged elements hidden)
                ]
                # (1 unchanged attribute hidden)
            }
        )
        # (1 unchanged attribute hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

@xnoto
xnoto merged commit 71c2597 into main Sep 4, 2026
4 checks passed
@xnoto
xnoto deleted the fix/channel-project-s3-iam-action-names branch September 4, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant