#!/usr/bin/env bash ############################################################################### # create-deploy-role.sh # # Creates / updates the GitHub Actions OIDC deploy role # `githubdeploy-proposal-system` in AWS account 011934824531 (seahaven-prod), # us-east-1, for the Sea-Haven-Industries/proposal-system repo (main branch). # # GATE — DO NOT EXECUTE until BOTH of the following have passed: # 1. GPT-4.1 cross-family review (IAM policy / trust-policy change), via: # python3 ~/Documents/repositories/seahaven/security-review/cross_review.py \ # "Review this IAM deploy-role trust+permissions for over-permission: " # (STATUS 2026-07-14: RUN — verdict APPROVE, no BLOCK.) # 2. /sh-security-review (deep agentic pass — IaC/IAM is a gated surface) # # This is an IAM/trust change: run BOTH gates and resolve every confirmed # critical/high before running. This script mutates AWS; the artifact-authoring # task did NOT run it. It is idempotent and safe to re-run. # # Resolved facts (Phase 0, read-only verification): # Account : 011934824531 (seahaven-prod) # Region : us-east-1 # Qualifier : hnb659fds (AWS CDK DEFAULT — no custom synthesizer needed) # OIDC prov : arn:aws:iam::011934824531:oidc-provider/token.actions.githubusercontent.com ############################################################################### set -euo pipefail PROFILE="prod" ROLE_NAME="githubdeploy-proposal-system" POLICY_NAME="proposal-system-deploy" ACCOUNT_ID="011934824531" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TRUST_POLICY="file://${SCRIPT_DIR}/trust-policy.json" PERMS_POLICY="file://${SCRIPT_DIR}/permissions-policy.json" echo "==> Verifying active account for profile '${PROFILE}'..." CALLER_ACCOUNT="$(aws --profile "${PROFILE}" sts get-caller-identity --query Account --output text)" if [[ "${CALLER_ACCOUNT}" != "${ACCOUNT_ID}" ]]; then echo "ERROR: profile '${PROFILE}' resolves to account ${CALLER_ACCOUNT}, expected ${ACCOUNT_ID}. Aborting." >&2 exit 1 fi echo "==> Ensuring role '${ROLE_NAME}' exists with the correct trust policy..." if aws --profile "${PROFILE}" iam get-role --role-name "${ROLE_NAME}" >/dev/null 2>&1; then echo " Role exists — updating assume-role (trust) policy." aws --profile "${PROFILE}" iam update-assume-role-policy \ --role-name "${ROLE_NAME}" \ --policy-document "${TRUST_POLICY}" else echo " Role absent — creating." aws --profile "${PROFILE}" iam create-role \ --role-name "${ROLE_NAME}" \ --assume-role-policy-document "${TRUST_POLICY}" \ --description "GitHub Actions OIDC deploy role for Sea-Haven-Industries/proposal-system (main)" \ --max-session-duration 3600 \ --tags Key=project,Value=proposal-system Key=managed-by,Value=create-deploy-role.sh fi echo "==> Putting inline permissions policy '${POLICY_NAME}' (create-or-replace)..." aws --profile "${PROFILE}" iam put-role-policy \ --role-name "${ROLE_NAME}" \ --policy-name "${POLICY_NAME}" \ --policy-document "${PERMS_POLICY}" ROLE_ARN="$(aws --profile "${PROFILE}" iam get-role --role-name "${ROLE_NAME}" \ --query Role.Arn --output text)" echo "==> Done. Deploy role ready:" echo " ${ROLE_ARN}" echo " Configure the GitHub Actions workflow to assume this ARN via aws-actions/configure-aws-credentials."