Skip to content

Apply gate: resolve team from GitHub API for team-based roles#95

Merged
Alexanderamiri merged 2 commits into
mainfrom
fix/construct-boundary-arn
Mar 18, 2026
Merged

Apply gate: resolve team from GitHub API for team-based roles#95
Alexanderamiri merged 2 commits into
mainfrom
fix/construct-boundary-arn

Conversation

@Alexanderamiri
Copy link
Copy Markdown
Member

Summary

The apply gate Lambda used the old per-app role pattern (javabin-ci-app-{repo}). Updated to resolve team from GitHub API (same as the CI broker) and assume javabin-ci-team-{team}.

Also includes the boundary ARN construction fix from PR #94.

Changes

  • shared/github.py: Extracted GitHub App auth + team resolution from ci_broker into shared module
  • ci_broker/handler.py: Uses shared.github.resolve_team() instead of inline copy
  • apply_gate/handler.py: Uses shared.github.resolve_team() to find team, assumes javabin-ci-team-{team}
  • lambdas/main.tf: Added SSM read for GitHub App creds to gate role. Switched ci_broker + apply_gate archives to source{} blocks to include shared module.
  • registry.py + platform-data/main.tf: Construct boundary ARN instead of data source

Test plan

  • Merge, wait for apply (deploys updated Lambdas)
  • Retrigger test app CI — apply gate should resolve team and assume correct role

The boundary policy is tagged team=javabin (org default), not shared.
Instead of looking it up via iam:GetPolicy (which the cross-team deny
blocks), construct the deterministic ARN from the account ID and project.

- Remove data source from platform-data module
- Use expr:arn:aws:iam::${env:AWS_ACCOUNT_ID}:policy/... in registry
- Revert boundary.tf tags override (org default_tags are correct)
The gate was using the old per-app role pattern (javabin-ci-app-{repo}).
Updated to resolve team via GitHub API and assume javabin-ci-team-{team},
matching the broker's team-based model.

- Extract GitHub App auth + team resolution to shared/github.py
- Update ci_broker and apply_gate to use shared module
- Add SSM read permission for GitHub App credentials to gate role
- Switch both Lambda archives to source{} blocks for shared inclusion
@Alexanderamiri Alexanderamiri requested a review from a team as a code owner March 18, 2026 00:31
@Alexanderamiri Alexanderamiri enabled auto-merge (squash) March 18, 2026 00:31
@github-actions
Copy link
Copy Markdown

Terraform Plan

🚧 Changes detected — Plan: 0 to add, 3 to change, 0 to destroy.

Plan output

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.lambdas.aws_iam_role_policy.apply_gate will be updated in-place
  ~ resource "aws_iam_role_policy" "apply_gate" {
        id     = "javabin-apply-gate:javabin-apply-gate"
        name   = "javabin-apply-gate"
      ~ policy = jsonencode(
          ~ {
              ~ Statement = [
                    # (2 unchanged elements hidden)
                    {
                        Action   = "sts:AssumeRole"
                        Effect   = "Allow"
                        Resource = "arn:aws:iam::553637109631:role/javabin-ci-team-*"
                        Sid      = "AssumeTeamRoles"
                    },
                  + {
                      + Action   = "ssm:GetParameter"
                      + Effect   = "Allow"
                      + Resource = [
                          + "arn:aws:ssm:eu-central-1:553637109631:parameter/javabin/platform/github-app-id",
                          + "arn:aws:ssm:eu-central-1:553637109631:parameter/javabin/platform/github-app-key",
                        ]
                      + Sid      = "ReadGitHubAppCredentials"
                    },
                ]
                # (1 unchanged attribute hidden)
            }
        )
        # (1 unchanged attribute hidden)
    }

  # module.lambdas.aws_lambda_function.apply_gate will be updated in-place
  ~ resource "aws_lambda_function" "apply_gate" {
        id                             = "javabin-apply-gate"
      ~ last_modified                  = "2026-03-17T19:19:44.182+0000" -> (known after apply)
      ~ source_code_hash               = "GwMg5ExuEgwD7SMSO92dnOtPp3Ebpe6n8e1IcSccpkE=" -> "UIWBB5JjUuxNGDEzzQ+vqN2HzkpT9TXXMugFBFyQtJA="
        tags                           = {}
        # (21 unchanged attributes hidden)

        # (4 unchanged blocks hidden)
    }

  # module.lambdas.aws_lambda_function.ci_broker will be updated in-place
  ~ resource "aws_lambda_function" "ci_broker" {
        id                             = "javabin-ci-broker"
      ~ last_modified                  = "2026-03-17T23:12:51.000+0000" -> (known after apply)
      ~ source_code_hash               = "oPOfwimvwsRJJLhtsQE0/AFhJGK4auzPN+Qj5PXZh+s=" -> "7RJbLLtcXuSIUkIYZbx+bcKW17c0IARtwitmYk5mCoU="
        tags                           = {}
        # (21 unchanged attributes hidden)

        # (4 unchanged blocks hidden)
    }

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

─────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"

LLM Review

Risk: 🟢 LOW

Routine Lambda function updates with minor IAM permission additions for GitHub App credential access.

  • [routine] Lambda function code updates for apply_gate and ci_broker with new source code hashes - standard deployment updates
  • [routine] IAM policy expansion for apply_gate role adding ssm:GetParameter permissions for GitHub App credentials (app-id and app-key) - scoped to specific parameters
  • 🔒 [security] New SSM parameter access permissions are appropriately scoped to specific GitHub App credential parameters in eu-central-1 region - follows least privilege principle
  • [routine] No resources being created or destroyed - only in-place updates to existing Lambda functions and IAM policies
  • [routine] No security group, network, or data store modifications - changes are isolated to compute and identity layers

@Alexanderamiri Alexanderamiri merged commit f543242 into main Mar 18, 2026
3 checks passed
@Alexanderamiri Alexanderamiri deleted the fix/construct-boundary-arn branch March 18, 2026 00:32
Alexanderamiri added a commit that referenced this pull request May 9, 2026
## Summary
The apply gate Lambda used the old per-app role pattern
(`javabin-ci-app-{repo}`). Updated to resolve team from GitHub API (same
as the CI broker) and assume `javabin-ci-team-{team}`.

Also includes the boundary ARN construction fix from PR #94.

### Changes
- **`shared/github.py`**: Extracted GitHub App auth + team resolution
from ci_broker into shared module
- **`ci_broker/handler.py`**: Uses `shared.github.resolve_team()`
instead of inline copy
- **`apply_gate/handler.py`**: Uses `shared.github.resolve_team()` to
find team, assumes `javabin-ci-team-{team}`
- **`lambdas/main.tf`**: Added SSM read for GitHub App creds to gate
role. Switched ci_broker + apply_gate archives to `source{}` blocks to
include shared module.
- **`registry.py`** + **`platform-data/main.tf`**: Construct boundary
ARN instead of data source

## Test plan
- [ ] Merge, wait for apply (deploys updated Lambdas)
- [ ] Retrigger test app CI — apply gate should resolve team and assume
correct role
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