Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,34 @@ jobs:
steps:
- uses: actions/checkout@v6

- name: Resolve team from GitHub
id: team
env:
GH_TOKEN: ${{ github.token }}
run: |
TEAM=$(gh api "/repos/${{ github.repository }}/teams" \
--jq '[.[] | select(.slug != "platform-owners")] | .[0].slug // empty' 2>/dev/null || true)
if [ -z "$TEAM" ]; then echo "ERROR: repo not in a team"; exit 1; fi
echo "team=$TEAM" >> "$GITHUB_OUTPUT"
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.PLATFORM_APP_ID }}
private-key: ${{ secrets.PLATFORM_APP_PRIVATE_KEY }}
owner: javaBin

- name: Configure AWS credentials via OIDC
- name: Checkout platform scripts
uses: actions/checkout@v6
with:
repository: javaBin/platform
token: ${{ steps.app-token.outputs.token }}
path: .platform
sparse-checkout: scripts

- name: Assume broker role via OIDC
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/javabin-ci-deploy-${{ steps.team.outputs.team }}
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/javabin-ci-app-broker
aws-region: ${{ inputs.aws_region }}

- name: Get deploy credentials from broker
id: broker
env:
PROJECT: javabin
run: sh .platform/scripts/invoke-ci-broker.sh deploy

- name: Login to ECR
id: ecr
uses: aws-actions/amazon-ecr-login@v2
Expand Down
20 changes: 8 additions & 12 deletions .github/workflows/ecs-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,18 @@ jobs:
sparse-checkout: scripts
path: .platform

- name: Resolve team from GitHub
id: team
env:
GH_TOKEN: ${{ github.token }}
run: |
TEAM=$(gh api "/repos/${{ github.repository }}/teams" \
--jq '[.[] | select(.slug != "platform-owners")] | .[0].slug // empty' 2>/dev/null || true)
if [ -z "$TEAM" ]; then echo "ERROR: repo not in a team"; exit 1; fi
echo "team=$TEAM" >> "$GITHUB_OUTPUT"

- name: Configure AWS credentials via OIDC
- name: Assume broker role via OIDC
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/javabin-ci-deploy-${{ steps.team.outputs.team }}
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/javabin-ci-app-broker
aws-region: ${{ inputs.aws_region }}

- name: Get deploy credentials from broker
id: broker
env:
PROJECT: javabin
run: sh .platform/scripts/invoke-ci-broker.sh deploy

- name: Deploy to ECS
env:
SERVICE: ${{ inputs.service_name || github.event.repository.name }}
Expand Down
25 changes: 8 additions & 17 deletions .github/workflows/tf-plan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,18 @@ jobs:
terraform_version: "1.7"
terraform_wrapper: false

- name: Resolve team from GitHub
id: team
env:
GH_TOKEN: ${{ github.token }}
run: |
TEAM=$(gh api "/repos/${{ github.repository }}/teams" \
--jq '[.[] | select(.slug != "platform-owners")] | .[0].slug // empty' 2>/dev/null || true)
if [ -z "$TEAM" ]; then
echo "ERROR: repo does not belong to any GitHub team"
echo "Add it at https://github.com/orgs/javaBin/teams"
exit 1
fi
echo "Resolved team: $TEAM"
echo "team=$TEAM" >> "$GITHUB_OUTPUT"

- name: Configure AWS credentials via OIDC
- name: Assume broker role via OIDC
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/javabin-ci-team-${{ steps.team.outputs.team }}
role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/javabin-ci-app-broker
aws-region: ${{ inputs.aws_region }}

- name: Get team credentials from broker
id: broker
env:
PROJECT: javabin
run: sh .platform/scripts/invoke-ci-broker.sh plan

- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v2
Expand Down
2 changes: 1 addition & 1 deletion scripts/ensure-tf-boilerplate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ if [ ! -f "$TF_ROOT/backend.tf" ]; then
terraform {
backend "s3" {
bucket = "${PROJECT}-terraform-state-${ACCOUNT_ID}"
key = "apps/${REPO_NAME}/terraform.tfstate"
key = "apps/${TEAM}/${REPO_NAME}/terraform.tfstate"
region = "${REGION}"
dynamodb_table = "${PROJECT}-terraform-app-locks"
encrypt = true
Expand Down
2 changes: 1 addition & 1 deletion scripts/expand-modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ def main():
os.path.join(tf_root, "backend.tf"),
BACKEND_TEMPLATE.format(
project=PROJECT, account_id=account_id,
service=service, region=region,
service=service, team=app_team, region=region,
),
)
write_file(
Expand Down
3 changes: 1 addition & 2 deletions scripts/extract-review-risk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,5 @@ echo "risk_level=${RISK}" >> "$GITHUB_OUTPUT"
echo "LLM review risk: ${RISK}"

if [ "$RISK" = "FAILED" ]; then
echo "LLM review failed — blocking pipeline."
exit 1
echo "WARNING: LLM review failed — treated as HIGH risk (override available)."
fi
49 changes: 49 additions & 0 deletions scripts/invoke-ci-broker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/sh
# Invoke the CI broker Lambda to get team-scoped credentials.
#
# Usage: invoke-ci-broker.sh <action>
# action: "plan" or "deploy"
#
# Env: GITHUB_REPOSITORY (org/repo)
# Output: Exports AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
# Sets team={slug} in GITHUB_OUTPUT

set -e

ACTION="${1:?Usage: invoke-ci-broker.sh <plan|deploy>}"
REPO="${GITHUB_REPOSITORY##*/}"

echo "Requesting ${ACTION} credentials for ${REPO}..."

RESPONSE=$(aws lambda invoke \
--function-name "${PROJECT:-javabin}-ci-broker" \
--payload "$(printf '{"repo":"%s","action":"%s"}' "$REPO" "$ACTION")" \
--cli-binary-format raw-in-base64-out \
/tmp/broker-response.json 2>&1)

RESULT=$(cat /tmp/broker-response.json)
APPROVED=$(echo "$RESULT" | jq -r '.approved // false')

if [ "$APPROVED" != "true" ]; then
ERROR=$(echo "$RESULT" | jq -r '.error // "Unknown error"')
echo "ERROR: CI broker rejected request: $ERROR"
exit 1
fi

TEAM=$(echo "$RESULT" | jq -r '.team')
echo "Team: $TEAM"
echo "team=${TEAM}" >> "${GITHUB_OUTPUT:-/dev/null}"

# Export credentials for subsequent steps
{
echo "AWS_ACCESS_KEY_ID=$(echo "$RESULT" | jq -r '.credentials.AccessKeyId')"
echo "AWS_SECRET_ACCESS_KEY=$(echo "$RESULT" | jq -r '.credentials.SecretAccessKey')"
echo "AWS_SESSION_TOKEN=$(echo "$RESULT" | jq -r '.credentials.SessionToken')"
} >> "${GITHUB_ENV:-/dev/null}"

# Mask credentials in logs
echo "::add-mask::$(echo "$RESULT" | jq -r '.credentials.AccessKeyId')"
echo "::add-mask::$(echo "$RESULT" | jq -r '.credentials.SecretAccessKey')"
echo "::add-mask::$(echo "$RESULT" | jq -r '.credentials.SessionToken')"

echo "Credentials issued for team=${TEAM} action=${ACTION}"
2 changes: 1 addition & 1 deletion scripts/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@
terraform {{
backend "s3" {{
bucket = "{project}-terraform-state-{account_id}"
key = "apps/{service}/terraform.tfstate"
key = "apps/{team}/{service}/terraform.tfstate"
region = "{region}"
dynamodb_table = "{project}-terraform-app-locks"
encrypt = true
Expand Down
Loading