mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-09-30 20:33:14 +00:00
* chore(infra): retarget prod to seahaven-prod account + OIDC deploy-role artifacts Retarget the CDK prod env from mgmt (328440206208, now frozen for workloads) to the dedicated seahaven-prod workload account (011934824531). proposal-system is the org's first prod tenant. Hard-block env=staging (still targets frozen mgmt) in resolveConfig until it is retargeted to seahaven-dev (710827005802). Add a WARN-only out-of-pipeline deploy guard in bin/app.ts. Add infra/deploy-role/: OIDC trust policy (sub scoped to Sea-Haven-Industries/proposal-system:ref:refs/heads/main), least-privilege permissions policy (AssumeRole on the verified cdk-hnb659fds bootstrap roles, deterministic site bucket, account-scoped CloudFront invalidation), and an idempotent creation script. Verified against live prod: bootstrap qualifier hnb659fds v32, OIDC provider present. Passed GPT-4.1 cross-review (APPROVE) and workflow red-team (CLEAN). Role NOT yet created — gated on /sh-security-review + the deploy go-ahead. Docs: README + CLAUDE.md reflect the prod account and pipeline-only deploy. * chore(infra): region-bound deploy-role DescribeStacks to us-east-1 (sh-security-review IAM-L2) * feat(infra): Aurora prod backup retention 14d + window; prod-only CDK context Bump Aurora automated-backup (PITR) retention 7->14d and set a preferred backup window for the prod tenant. Dedicated AWS Backup vault + cross-account restore test is a tracked follow-up (no org central-backup design exists yet). Prune the stale mgmt-account AZ context; prod (011934824531) is the only deploy target.
71 lines
3.3 KiB
Bash
Executable file
71 lines
3.3 KiB
Bash
Executable file
#!/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: <artifacts>"
|
|
# (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."
|