Skip to content

Allow CI to read the exact processed DataOps stack template #135

Closed

Description

@alexeygrigorev

Allow CI to read the exact processed DataOps stack template

Status: complete — source integrated and exact processed-template permission effective
Tags: bug, human, infra, testing, P1
Depends on: #129 source and completed/effective #130 repair
Blocks: #136 staged Sponsor CRM GSI migration, #114, #128, and #134
Evidence: #114 On-Call gate, attempt 2

Outcome

Permit the GitHub Actions deployment role to retrieve the last successful processed template for exactly the dataops-v1 CloudFormation stack. This is the minimum shared-infrastructure prerequisite for a source-controlled, resumable GSI migrator.

Change only the shared DataTalksClub/aws-infra source of truth and focused tests. Agent work must not apply AWS or modify DataOps application code.

Exact policy decision

Add one narrowly isolated statement to the existing dataops-v1-deploy inline policy on GitHubActionsDeployRole:

Action: cloudformation:GetTemplate
Resource: arn:${AWS::Partition}:cloudformation:${FullDocsRegion}:${AWS::AccountId}:stack/${FullDocsStackName}/*

With the supported parameters this resolves only to the dataops-v1 stack in eu-west-1 and the current account. Do not place GetTemplate in the existing multi-resource CloudFormationDataOpsStack statement, because that statement also contains the Serverless transform ARN. Do not add it to wildcard CloudFormationRead.

No other action, resource, role, trust relationship, attachment, or policy changes.

Acceptance Criteria

  • Fetch current DataTalksClub/aws-infra origin/main and work in a clean isolated worktree containing accepted Repair DataOps OIDC SES configuration-set tag-on-create permission #129/Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 source; preserve any dirty sibling checkout.
  • Add exactly one cloudformation:GetTemplate action in a dedicated statement within the existing dataops-v1-deploy inline policy attached only to GitHubActionsDeployRole.
  • Scope that statement to exactly arn:${AWS::Partition}:cloudformation:${FullDocsRegion}:${AWS::AccountId}:stack/${FullDocsStackName}/*; no Resource: "*", transform ARN, stack-name wildcard beyond CloudFormation's stack-ID suffix, other stack, region, or account.
  • Do not add GetTemplate to CloudFormationDataOpsStack or CloudFormationRead; do not add another managed policy, attachment, role, trust change, condition relaxation, or CloudFormation/IAM action.
  • Exact IAM simulation proves cloudformation:GetTemplate allowed for the live dataops-v1 stack ARN and denied for another stack, another region/account, the Serverless transform, *, and an unlisted CloudFormation action.
  • Parsed and mutation tests reject wildcard/alternate resources, placement in either broader statement, an extra action/resource/role/attachment, and trust drift. Existing Add transactional approval and durable execution recovery #124/Repair DataOps OIDC SES configuration-set tag-on-create permission #129/Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 policies and tests remain exact.
  • Recompute inline-policy size/quota, policy/resource counts, base/final path inventory, resolved policy hash/size, template/test hashes, and git diff --check. Run all sandbox/dataops tests and SAM lint/validation.
  • An independent IAM/security reviewer accepts the exact action/resource, negative simulation, placement, quota, preservation, HUMAN change-set plan, and rollback.
  • Commit/integrate the focused shared-source change with Refs DataTalksClub/dataops#135; no AWS apply during agent work and do not close the issue.
  • [HUMAN] A credentialed operator reviews a CAPABILITY_NAMED_IAM change set for dataops-github-actions. It must show only an in-place update to the existing deploy role's inline policy document; no role replacement, trust/attachment change, managed-policy change, or unrelated resource.
  • [HUMAN] Apply the reviewed shared-stack change, require terminal success, verify live policy fingerprint and exact allow/deny simulation, and preserve effective Repair DataOps OIDC SES configuration-set tag-on-create permission #129/Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 permissions. Only then may the GSI migrator prerequisite proceed.

Accepted frozen candidate

Required verification

Minimum source checks:

uv run --with pytest python -m pytest sandbox/dataops/tests -q
sam validate --lint --template-file sandbox/dataops/template.github-actions.yaml
git diff --check <accepted-base>...HEAD

The handoff must include accepted base/final commits, changed paths, diff/stat, source/resolved hashes, exact simulation output, quota results, full test output, and independent security verdict.

Rollback

Use CloudFormation only. If the shared-stack update is unacceptable, deploy the exact prior accepted template with CAPABILITY_NAMED_IAM, verify terminal success and prior live fingerprint, and confirm #129/#130 remain effective. Never patch the role directly.

Out of scope

GSI orchestration, DynamoDB mutation, application/SAM/workflow changes, new CloudFormation powers, stack-wide read access, manual IAM edits, app deployment, queue cleanup, or provider/Telegram work.

Activity

  1. added
    bugSomething is broken
    humanCode done or issue blocked on human verification
    infraDeployment and infrastructure
    P1Important
    on Jul 31, 2026
  2. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    PM GROOMED — exact processed-template read prerequisite is agent-ready

    The accepted design adds only cloudformation:GetTemplate for the exact dataops-v1 stack ARN. It uses a dedicated statement in the existing deploy-role inline policy so the permission cannot inherit the Serverless transform ARN or wildcard read resource from neighboring statements.

    Implementation is source/test only. Exact allow/deny simulation, mutation tests, quota/fingerprints, independent IAM/security review, and a HUMAN named-IAM in-place policy update are mandatory. #136 cannot run until the live apply is verified.

  3. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    SWE IMPLEMENTED — exact GetTemplate candidate ready for independent review

    Implemented the agent-verifiable #135 source/test slice without committing, pushing, applying AWS, or changing the dirty primary checkout.

    Candidate

    • Clean worktree: /home/alexey/git/aws-infra/.tmp/worktrees/issue-135-gettemplate
    • Branch: issue-135-gettemplate
    • Accepted/fetched base: bf1efbfb42efc613951bb8f8f7cbfd5a14194241 (origin/main)
    • Candidate tree: 4ba94812ed8b62b301db95171d9761063bcdc015
    • Binary diff SHA-256: f9d27f9746c4af52ab183c17b449628b258774660aff3d15740b16ac1228b53e
    • Changed paths only:
      • sandbox/dataops/template.github-actions.yaml (+5/-0)
      • sandbox/dataops/tests/test_template_github_actions.py (+457/-4; three quota assertions plus import spacing are the only deletions)

    The template adds one dedicated CloudFormationDataOpsGetTemplate Allow statement containing exactly cloudformation:GetTemplate on:

    arn:${AWS::Partition}:cloudformation:${FullDocsRegion}:${AWS::AccountId}:stack/${FullDocsStackName}/*

    It is absent from CloudFormationDataOpsStack, CloudFormationRead, the Serverless transform resource, every managed policy, and wildcard resources.

    Exact simulation and preservation

    AWS IAM simulate-custom-policy (read-only) evaluated the resolved candidate:

    • allowed: GetTemplate on the live dataops-v1 stack ARN only
    • implicitDeny: GetTemplate on another stack, another region, another account, the Serverless transform, and *
    • implicitDeny: unlisted cloudformation:DeleteStack across all six resources
    • total: 1 allowed / 11 implicitDeny

    Tests include parsed exactness, local allow/deny simulation, mutations for missing/renamed/conditioned statements, wildcard/alternate resources, broader-statement placement, duplicate/extra action/resource, extra role/attachment, trust drift, inventory, quota, and source/resolved fingerprints.

    Resolved document size/hash:

    • inline dataops-v1-deploy: 9519 / 796064dfa565d0315091505c03aa7f255ee50cc0a2a8bf06ab91ca3c7c5bd129
    • Sponsor compute: 3706 / 3aaec33e0624faaafa3a7e6d5381415c80481dea5b7a6f51f1365663ce4b3a61
    • Sponsor service: 1093 / 30aaa91aa6e00e19e7a04b35c4194075d4e881123e1727093a9001fa4f5dd952
    • dispatcher: 1512 / 991f8670747081dabd407d4fe8e101c1b9c4d7620722274b65b9325bdfefea04
    • observability: 5369 / 435213eed7933be4ae303aae1b14ef72f09a42a4a6cf2c1f6fa99706455b827f
    • OIDC trust: 386 / a4fb561e9b54a2418b750fdc84e0c7ddd7856305fd791d615d40aa85174e68bf

    Quota/inventory: inline headroom 721 bytes of 10240; 5 resources; 1 inline policy; 4 deploy-role managed attachments with 6 steady-state slots free. The old 768-byte assertion necessarily became a 640-byte floor because this exact statement leaves 721 bytes.

    Source SHA-256:

    • template: 9b6aa4c0ac610677ac0b329ceb39de0fd46d0adc6de5d1edb17b2439741db67b
    • tests: a91f8a912f249d0b5d2ca51f7f5f8c84cfbe51d3eabdd12699f74a49a9cdd4ea

    Verification

    • uv run --with pytest python -m pytest sandbox/dataops/tests -q — 63 passed, 134 subtests passed
    • sam validate --lint --template-file sandbox/dataops/template.github-actions.yaml — valid SAM template
    • uvx ruff check --select E4,E7,E9,F,I ... — passed
    • python -m py_compile ... — passed
    • git diff --check — passed

    Ready for independent IAM/security review, Tester, and PM acceptance. HUMAN change-set/apply remains intentionally untouched.

  4. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    SWE REPLACEMENT CANDIDATE — rebased onto accepted #130 source

    The earlier bf1efbfb candidate is superseded. I fetched the advanced aws-infra origin/main and rebuilt #135 in a new clean worktree from accepted #130 commit 81953cd57aef6c3df2652b6a13379a2768801359.

    Replacement candidate

    • Worktree: /home/alexey/git/aws-infra/.tmp/worktrees/issue-135-gettemplate-v2
    • Branch: issue-135-gettemplate-v2
    • Accepted base: 81953cd57aef6c3df2652b6a13379a2768801359
    • Base tree: a68e9149ed102c538ac21f040ab29afc663243f1
    • Candidate tree: 8f427d4ee39398c25e0fbef0025373a38601fc58
    • Binary diff SHA-256: 4e61a0758aed6b56a277b7ca6b54b0865bd99b675ef8a4e1ae3d8bcb59764072
    • Changed paths only:
      • sandbox/dataops/template.github-actions.yaml (+5/-0)
      • sandbox/dataops/tests/test_template_github_actions.py (+393/-3; the three deletions are the prior inline-quota threshold assertions replaced for the exact new size)

    The accepted #130 generated dispatcher role boundary remains byte-for-byte:

    arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${FullDocsStackName}-ConversationalResultDispatcherFunctionRo-*

    Its resolved managed-policy fingerprint remains 1510 / d705db32ea1786480f149d63916723b22232dad078f0e7710c0984fb31daf313. The candidate diff contains no modification to that resource or its #130 preservation/simulation tests.

    The only template change is the dedicated CloudFormationDataOpsGetTemplate statement with exactly cloudformation:GetTemplate on:

    arn:${AWS::Partition}:cloudformation:${FullDocsRegion}:${AWS::AccountId}:stack/${FullDocsStackName}/*

    Simulation, quota, and fingerprints

    A fresh read-only AWS IAM simulate-custom-policy run on this replacement resolved document returned exactly 1 allowed and 11 implicitDeny decisions:

    • allow: GetTemplate on the live dataops-v1 stack ARN
    • deny: GetTemplate on another stack, region, account, Serverless transform, and *
    • deny: unlisted cloudformation:DeleteStack across all six resources

    Resolved size/hash:

    • inline dataops-v1-deploy: 9519 / 796064dfa565d0315091505c03aa7f255ee50cc0a2a8bf06ab91ca3c7c5bd129
    • Sponsor compute: 3706 / 3aaec33e0624faaafa3a7e6d5381415c80481dea5b7a6f51f1365663ce4b3a61
    • Sponsor service: 1093 / 30aaa91aa6e00e19e7a04b35c4194075d4e881123e1727093a9001fa4f5dd952
    • Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 dispatcher: 1510 / d705db32ea1786480f149d63916723b22232dad078f0e7710c0984fb31daf313
    • observability: 5369 / 435213eed7933be4ae303aae1b14ef72f09a42a4a6cf2c1f6fa99706455b827f
    • OIDC trust: 386 / a4fb561e9b54a2418b750fdc84e0c7ddd7856305fd791d615d40aa85174e68bf

    Inline quota headroom is 721 bytes of 10240. Inventory remains 5 resources, one inline policy, and four managed attachments with six steady-state attachment slots free.

    Source SHA-256:

    • template: 28df035bdb829b816bdeb97d66f19f915f7725f6da7cad91b30fc4cba192c4f4
    • tests: f7ca3c4540649842e134be4766d31f2c59ce54ea4b3d7a678184c78b46c9dbc2

    Fresh verification

    • uv run --with pytest python -m pytest sandbox/dataops/tests -q — 65 passed, 156 subtests passed
    • sam validate --lint --template-file sandbox/dataops/template.github-actions.yaml — valid SAM template
    • git diff --check — passed
    • focused Python compile and error/undefined-name lint — passed
    • AWS IAM simulator — 1 allowed / 11 implicitDeny

    No commit, push, CloudFormation apply, IAM edit, or application deploy was performed. This replacement candidate is ready for independent security review, Tester, and PM acceptance.

  5. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    ARCHITECT / IAM SECURITY REVIEW — PASS (replacement candidate)

    I independently reviewed the uncommitted replacement candidate in /home/alexey/git/aws-infra/.tmp/worktrees/issue-135-gettemplate-v2 against accepted base 81953cd57aef6c3df2652b6a13379a2768801359.

    Accepted candidate identity

    • base / current origin/main: 81953cd57aef6c3df2652b6a13379a2768801359
    • changed paths: exactly two
      • sandbox/dataops/template.github-actions.yaml (+5/-0)
      • sandbox/dataops/tests/test_template_github_actions.py (+393/-3)
    • binary diff SHA-256: 4e61a0758aed6b56a277b7ca6b54b0865bd99b675ef8a4e1ae3d8bcb59764072
    • template SHA-256: 28df035bdb829b816bdeb97d66f19f915f7725f6da7cad91b30fc4cba192c4f4
    • test SHA-256: f7ca3c4540649842e134be4766d31f2c59ce54ea4b3d7a678184c78b46c9dbc2
    • git diff --check: pass

    Security verdict

    PASS. The only template delta is one dedicated CloudFormationDataOpsGetTemplate statement in the existing dataops-v1-deploy inline policy. It grants exactly:

    • action: cloudformation:GetTemplate
    • resource: arn:${AWS::Partition}:cloudformation:${FullDocsRegion}:${AWS::AccountId}:stack/${FullDocsStackName}/*

    GetTemplate occurs once only. It is not added to CloudFormationDataOpsStack, CloudFormationRead, a managed policy, the Serverless transform ARN, or Resource: "*". No other CloudFormation/IAM action, role, resource, condition, attachment, trust relationship, deletion/replacement policy, or parameter changed.

    A fresh AWS IAM SimulateCustomPolicy run against the resolved candidate produced exactly 1 allowed and 11 implicitDeny decisions. The sole allow was GetTemplate on the eu-west-1 current-account dataops-v1 stack ARN. GetTemplate was denied for another stack, region, account, the Serverless transform, and *; DeleteStack was denied for all six resources. Each resource was simulated separately because the AWS API rejects a request that combines * with individual resource ARNs.

    Resolved fingerprints independently reproduced:

    • inline dataops-v1-deploy: 9519 / 796064dfa565d0315091505c03aa7f255ee50cc0a2a8bf06ab91ca3c7c5bd129
    • Sponsor compute: 3706 / 3aaec33e0624faaafa3a7e6d5381415c80481dea5b7a6f51f1365663ce4b3a61
    • Sponsor service: 1093 / 30aaa91aa6e00e19e7a04b35c4194075d4e881123e1727093a9001fa4f5dd952
    • Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 dispatcher: 1510 / d705db32ea1786480f149d63916723b22232dad078f0e7710c0984fb31daf313
    • observability: 5369 / 435213eed7933be4ae303aae1b14ef72f09a42a4a6cf2c1f6fa99706455b827f
    • OIDC trust: 386 / a4fb561e9b54a2418b750fdc84e0c7ddd7856305fd791d615d40aa85174e68bf

    The #130 dispatcher boundary remains exact at arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${FullDocsStackName}-ConversationalResultDispatcherFunctionRo-*; the candidate does not alter that resource or its preservation/simulation tests.

    Quota and inventory remain acceptable: inline aggregate 9519/10240 (721 bytes free), one inline policy, five CloudFormation resources, and four managed policies attached only to GitHubActionsDeployRole (six steady-state attachment slots free). The exact-fingerprint test compensates for the necessarily reduced generic headroom floor.

    Verification

    • uv run --with pytest python -m pytest sandbox/dataops/tests -q — 65 passed, 156 subtests passed
    • sam validate --lint --template-file sandbox/dataops/template.github-actions.yaml — valid SAM template
    • focused compile — pass
    • candidate-specific parsed exactness, mutation, preservation, quota, source-hash, and local allow/deny tests — pass

    The HUMAN gate is correctly constrained: a CAPABILITY_NAMED_IAM change set must show only an in-place update to the existing role's inline policy document, with no replacement, trust/attachment/managed-policy/unrelated change. Rollback must deploy the exact prior accepted CloudFormation template and verify #129/#130 remain effective. No AWS apply, IAM edit, commit, push, or application deployment was performed in this review.

  6. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    TEST PASS — replacement candidate

    I independently verified the uncommitted replacement candidate in /home/alexey/git/aws-infra/.tmp/worktrees/issue-135-gettemplate-v2 after the Architect/IAM PASS.

    Locked candidate

    • accepted base / local origin/main: 81953cd57aef6c3df2652b6a13379a2768801359
    • changed paths: exactly two, with no untracked paths
      • sandbox/dataops/template.github-actions.yaml (+5/-0)
      • sandbox/dataops/tests/test_template_github_actions.py (+393/-3)
    • binary diff SHA-256: 4e61a0758aed6b56a277b7ca6b54b0865bd99b675ef8a4e1ae3d8bcb59764072
    • template SHA-256: 28df035bdb829b816bdeb97d66f19f915f7725f6da7cad91b30fc4cba192c4f4
    • test SHA-256: f7ca3c4540649842e134be4766d31f2c59ce54ea4b3d7a678184c78b46c9dbc2
    • final identity recheck matched the same base, paths, counts, hashes, and diff; the worktree retained only those two intended modifications

    The template diff is exactly one dedicated CloudFormationDataOpsGetTemplate statement in the existing deploy-role inline policy: one cloudformation:GetTemplate action on arn:${AWS::Partition}:cloudformation:${FullDocsRegion}:${AWS::AccountId}:stack/${FullDocsStackName}/*. It does not occur in CloudFormationDataOpsStack, CloudFormationRead, any managed policy, the Serverless transform resource, or a wildcard resource. No other template line changed.

    Commands and results

    • uv run --with pytest python -m pytest sandbox/dataops/tests -q — exit 0; 65 passed, 156 subtests passed
    • uv run --with pytest python -m pytest sandbox/dataops/tests/test_template_github_actions.py::CloudFormationGetTemplatePolicyTest -vv — exit 0; 8 passed, 19 subtests passed
    • uv run --with pytest python -m pytest sandbox/dataops/tests/test_template_github_actions.py::ConversationalResultDispatcherDeployPolicyTest -vv — exit 0; 15 passed, 52 subtests passed
    • sam validate --lint --template-file sandbox/dataops/template.github-actions.yaml — exit 0; valid SAM template
    • uvx ruff check --select E4,E7,E9,F sandbox/dataops/tests/test_template_github_actions.py — exit 0
    • python -m py_compile sandbox/dataops/tests/test_template_github_actions.py — exit 0
    • git diff --check 81953cd57aef6c3df2652b6a13379a2768801359 — exit 0

    An extra ruff --select I diagnostic reports the accepted repository's pre-existing import-order finding; running the same check against the base file reproduces it exactly. It is not introduced by this candidate and is outside the issue's required error/undefined-name lint gate.

    Exact live AWS simulation

    Using the candidate's resolved inline policy and the exact current-account dataops-v1 StackId from read-only DescribeStacks, I invoked iam:SimulateCustomPolicy separately for each action/resource pair:

    • live stack: GetTemplate=allowed, DeleteStack=implicitDeny
    • other stack: GetTemplate=implicitDeny, DeleteStack=implicitDeny
    • other region: GetTemplate=implicitDeny, DeleteStack=implicitDeny
    • other account: GetTemplate=implicitDeny, DeleteStack=implicitDeny
    • Serverless transform: GetTemplate=implicitDeny, DeleteStack=implicitDeny
    • wildcard *: GetTemplate=implicitDeny, DeleteStack=implicitDeny

    Totals: 1 allowed / 11 implicitDeny. No AWS mutation or apply was performed.

    Preservation and quota evidence

    Independent resolved fingerprints:

    • inline dataops-v1-deploy: 9519 / 796064dfa565d0315091505c03aa7f255ee50cc0a2a8bf06ab91ca3c7c5bd129
    • Sponsor compute: 3706 / 3aaec33e0624faaafa3a7e6d5381415c80481dea5b7a6f51f1365663ce4b3a61
    • Sponsor service: 1093 / 30aaa91aa6e00e19e7a04b35c4194075d4e881123e1727093a9001fa4f5dd952
    • Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 dispatcher: 1510 / d705db32ea1786480f149d63916723b22232dad078f0e7710c0984fb31daf313
    • observability: 5369 / 435213eed7933be4ae303aae1b14ef72f09a42a4a6cf2c1f6fa99706455b827f
    • OIDC trust: 386 / a4fb561e9b54a2418b750fdc84e0c7ddd7856305fd791d615d40aa85174e68bf

    Inventory remains five resources, one inline policy, and four managed policies attached only to GitHubActionsDeployRole. Inline headroom is 721/10240 bytes; managed-policy attachment headroom is six slots. The accepted #130 generated dispatcher-role boundary occurs exactly once and its full 15-test mutation/simulation suite passes.

    All agent-verifiable acceptance criteria pass. The independent security gate is satisfied by Architect PASS in comment 5137895600. Commit/integration remains correctly pending Tester + PM acceptance, and both named-IAM change-set/apply criteria remain HUMAN-only. No code edit, commit, push, issue-body edit, AWS apply, IAM edit, or application deployment was performed by Tester. No screenshots are applicable to this infrastructure-only change.

  7. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    PM ACCEPTANCE — frozen #135 source candidate accepted; commit and HUMAN apply remain pending

    I accept the exact uncommitted replacement candidate after the independent Architect/IAM PASS and Tester PASS:

    • Architect/IAM PASS: Allow CI to read the exact processed DataOps stack template #135 (comment)
    • Tester PASS: Allow CI to read the exact processed DataOps stack template #135 (comment)
    • accepted base/HEAD: 81953cd57aef6c3df2652b6a13379a2768801359;
    • changed paths: only sandbox/dataops/template.github-actions.yaml and sandbox/dataops/tests/test_template_github_actions.py;
    • NUL-framed path inventory: b63cbe94eec4befda34dd7adc3c41997a71da67f1a5a547df16fd8231fb3dbdf;
    • binary diff: 4e61a0758aed6b56a277b7ca6b54b0865bd99b675ef8a4e1ae3d8bcb59764072;
    • template: 28df035bdb829b816bdeb97d66f19f915f7725f6da7cad91b30fc4cba192c4f4;
    • focused tests: f7ca3c4540649842e134be4766d31f2c59ce54ea4b3d7a678184c78b46c9dbc2;
    • resolved inline policy: 9,519 compact bytes, SHA-256 796064dfa565d0315091505c03aa7f255ee50cc0a2a8bf06ab91ca3c7c5bd129.

    My PM re-lock reproduced the same base, two-path inventory, diff and file hashes, clean whitespace check, 65 passing tests plus 156 subtests, and valid SAM lint.

    The only template delta is one dedicated CloudFormationDataOpsGetTemplate statement in the existing deploy-role inline policy. It grants exactly cloudformation:GetTemplate on the exact dataops-v1 stack ARN family. It appears once and is absent from the broader stack/transform and wildcard-read statements. The AWS simulation produces exactly one allow and 11 implicit denies. Trust, attachments, managed policies, other actions/resources, #129, and effective #130 remain unchanged. The 9,519-byte inline policy remains below IAM's 10,240-byte limit with 721 bytes free.

    Exact recommended commit

    Subject:

    Allow CI to read the processed DataOps stack template
    

    Body:

    Grant cloudformation:GetTemplate only for the exact DataOps stack ARN
    through a dedicated statement in the existing deploy-role inline policy.
    
    Keep the broader CloudFormation statements, Serverless transform,
    trust, attachments, and accepted #129/#130 boundaries unchanged.
    
    Refs DataTalksClub/dataops#135
    

    Before committing, the Integrator must re-lock the exact hashes above and confirm no third path or candidate drift. Commit and integrate that exact candidate into DataTalksClub/aws-infra/main. Source integration alone changes no AWS permission. Any drift returns to review.

    Required HUMAN named-IAM apply sequence

    1. Confirm dataops-github-actions is terminal UPDATE_COMPLETE; record the merged Allow CI to read the exact processed DataOps stack template #135 commit, current stack/template identity, live role inline-policy fingerprint, trust, attachments, and effective Repair DataOps OIDC SES configuration-set tag-on-create permission #129/Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 fingerprints.
    2. From the exact merged source, create a fresh CAPABILITY_NAMED_IAM change set for dataops-github-actions.
    3. Do not execute until the change set shows exactly one in-place Modify of GitHubActionsDeployRole, Replacement: False, limited to its existing inline Policies document. It must show no role-name/trust/session/tag/attachment change, no managed-policy or other resource change, and no replacement/add/delete.
    4. Execute that reviewed change set and wait for shared-stack UPDATE_COMPLETE. A failed update must reach an explained terminal rollback state; never patch the role or inline policy directly.
    5. Read back dataops-v1-deploy and canonically require 9,519 bytes/796064dfa565…, exactly one dedicated GetTemplate statement, and the exact stack ARN. Re-run the exact matrix: one allow for GetTemplate on the live stack and 11 implicit denies for alternate resources and DeleteStack.
    6. Verify unchanged trust, four managed-policy attachments, Repair DataOps OIDC SES configuration-set tag-on-create permission #129 policies, Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130's 1,510-byte/d705db32… dispatcher policy, stack drift/inventory, and no pending change set.
    7. Stop after the shared permission is effective. Migrate Sponsor CRM GSIs in a protected stage-only workflow #136 owns the protected CI predeploy migrator and final normal SAM deployment; do not run a manual application deploy or UpdateTable under Allow CI to read the exact processed DataOps stack template #135.

    The first eight agent-verifiable criteria are checked. Commit/integration and both HUMAN criteria remain unchecked. Keep #135 open with human until effective apply evidence is attached.

  8. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    HUMAN AWS gate — applied and verified

    Applied the accepted #135 shared-infrastructure source from exact DataTalksClub/aws-infra commit 93a6eb6c6b6927b30bcbd501f08140ad680c3e3d through CloudFormation only.

    Preflight and reviewed change set

    • clean isolated source worktree at the exact merged commit;
    • accepted source fingerprints re-locked: template 28df035b…c4f4, focused tests f7ca3c45…dbc2;
    • dataops-github-actions was terminal UPDATE_COMPLETE and the application stack was terminal before the gate;
    • fresh CAPABILITY_NAMED_IAM change set issue-135-gettemplate-20260731T010025Z reported exactly one change:
      • Modify GitHubActionsDeployRole (AWS::IAM::Role);
      • Replacement: False;
      • only property target Policies, RequiresRecreation: Never;
    • no add/delete, trust, attachment, managed-policy, replacement, or unrelated-resource change appeared.

    The reviewed change set was executed. The shared stack reached terminal UPDATE_COMPLETE.

    Live verification

    • live dataops-v1-deploy: 9,519 canonical bytes, SHA-256 796064dfa565d0315091505c03aa7f255ee50cc0a2a8bf06ab91ca3c7c5bd129;
    • exactly one dedicated CloudFormationDataOpsGetTemplate statement;
    • action is exactly cloudformation:GetTemplate and the resource is exactly the current-account, eu-west-1, dataops-v1 stack ARN family (only CloudFormation's stack-ID suffix is wildcarded);
    • official IAM simulation: 1 allowed / 11 implicitDeny:
      • allowed only GetTemplate on the live dataops-v1 stack;
      • denied GetTemplate on another stack, region, account, Serverless transform, and *;
      • denied DeleteStack for all six tested resources.

    Preservation checks:

    The application stack remains in its prior terminal state. I did not deploy the application, rerun a workflow, modify a queue/table, patch IAM directly, or perform any #136 migration action. #135's shared permission prerequisite is now effective.

  9. alexeygrigorev commented on Jul 31, 2026

    @alexeygrigorev
    MemberAuthor

    PM LIVE ACCEPTANCE — #135 complete and effective

    I accept the HUMAN source/apply evidence in:
    #135 (comment)

    The final gates are satisfied:

    • the exact accepted candidate was committed/integrated as 93a6eb6c6b6927b30bcbd501f08140ad680c3e3d with the PM-prescribed subject/body and Refs DataTalksClub/dataops#135;
    • accepted template/test fingerprints re-locked before apply;
    • the reviewed CAPABILITY_NAMED_IAM change set contained exactly one Modify of GitHubActionsDeployRole, Replacement: False, limited to Policies with RequiresRecreation: Never;
    • no add/delete, trust, attachment, managed-policy, replacement, or unrelated-resource change occurred;
    • dataops-github-actions reached terminal UPDATE_COMPLETE;
    • live dataops-v1-deploy is exactly 9,519 canonical bytes/796064dfa565d0315091505c03aa7f255ee50cc0a2a8bf06ab91ca3c7c5bd129;
    • exactly one dedicated cloudformation:GetTemplate statement targets only the accepted current-account/eu-west-1/dataops-v1 stack ARN family;
    • official simulation reproduced exactly one allow and 11 implicit denies;
    • trust, four managed-policy attachments, Repair DataOps OIDC SES configuration-set tag-on-create permission #129 policies, Repair dispatcher generated-role IAM prefix for CloudFormation rollback #130 dispatcher policy, observability, resource inventory, and drift remained exact;
    • there are no pending change sets, and the application stack remains terminal;
    • no direct IAM patch, application deploy, workflow rerun, queue/table mutation, or Migrate Sponsor CRM GSIs in a protected stage-only workflow #136 migration action occurred.

    All #135 acceptance criteria are complete. Closing #135 authorizes no manual application or DynamoDB mutation. It only establishes the effective read prerequisite for #136's separately reviewed, protected CI migration.

  10. removed
    humanCode done or issue blocked on human verification
    on Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1ImportantbugSomething is brokeninfraDeployment and infrastructuretestingTests and QA

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions