.github/.github/workflows/compliance-audit.yaml
Adam Moussa 3a258918e2 chore(ci): bump actions/checkout v6 -> v7 across reusable workflows
actions/checkout v7.0.0 (2026-06-18) is internally an ESM rebuild plus
one behavioral change: it blocks checking out a fork PR head ref under
pull_request_target / workflow_run (PR #2454). No Sea Haven workflow uses
those triggers, so there is no reachable behavior change. The Node 24
runtime requirement already landed at v6, so v6 -> v7 carries no new
runner requirement. All runners here are GitHub-hosted (ubuntu, macos).

Covers all 16 checkout pins across 12 reusable/standalone workflows plus
the dependency-review workflow-template scaffold. Consumers on @main pick
this up automatically on merge.
2026-06-25 11:43:10 -04:00

138 lines
6.1 KiB
YAML

# DEPRECATED (2026-06-10): The weekly org-wide compliance audit has been retired.
# The workflow is disabled in the Actions tab (state: disabled_manually) and the
# scheduled trigger has been removed so it cannot run automatically. Repo
# compliance is now handled via the Claude Code App on pull requests and the
# engineering handbook directly. Left in place (manual-dispatch only) for
# historical reference; safe to delete in a future cleanup.
name: Compliance Audit (DEPRECATED)
on:
# schedule removed on deprecation — no longer runs weekly.
workflow_dispatch:
permissions:
id-token: write
contents: read
issues: write
jobs:
get-repos:
runs-on: ubuntu-latest
outputs:
repos: ${{ steps.list.outputs.repos }}
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.CLAUDE_CI_APP_ID }}
private-key: ${{ secrets.CLAUDE_CI_APP_PRIVATE_KEY }}
owner: Sea-Haven-Industries
- name: List org repos
id: list
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
EXCLUDE="shoc-frontend-new shoc-backend"
repos=$(gh repo list Sea-Haven-Industries \
--no-archived \
--json name \
--jq "[.[].name | select(. as \$n | \"$EXCLUDE\" | split(\" \") | index(\$n) | not)] | @json" \
--limit 100)
echo "repos=$repos" >> "$GITHUB_OUTPUT"
audit:
needs: get-repos
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
max-parallel: 3
matrix:
repo: ${{ fromJson(needs.get-repos.outputs.repos) }}
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.CLAUDE_CI_APP_ID }}
private-key: ${{ secrets.CLAUDE_CI_APP_PRIVATE_KEY }}
owner: Sea-Haven-Industries
repositories: ${{ matrix.repo }},engineering-handbook
- name: Checkout repo
uses: actions/checkout@v7
with:
repository: Sea-Haven-Industries/${{ matrix.repo }}
token: ${{ steps.app-token.outputs.token }}
- name: Checkout engineering handbook
uses: actions/checkout@v7
with:
repository: Sea-Haven-Industries/engineering-handbook
token: ${{ steps.app-token.outputs.token }}
path: .engineering-handbook
- name: Run compliance audit
id: audit
uses: anthropics/claude-code-action@2fee15510437d71399d9139ed60433470484a8fb # v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Audit this repository for Sea Haven Industries compliance.
The engineering handbook in `.engineering-handbook/` is the authoritative source for all conventions. Read every markdown file in that directory to understand the full set of standards, then audit this repo against them.
Focus on these categories:
- **Naming:** kebab-case for all resource names in IaC templates, stack name matches repo name
- **Secrets:** no secrets in Lambda env vars or SSM, secrets belong in Secrets Manager with `stack-name/secret-name` naming
- **Lambda defaults:** Python 3.12+ or Node 22.x, arm64, explicit 60-day log retention in IaC
- **CI/CD:** pipeline exists with CI on PR and CD on push to main, using reusable workflows from `.github` repo
- **Git/GitHub:** branch protection on main, PR-based workflow, repo has a description
- **SAM layout:** template.yaml at root, samconfig.toml gitignored with .example committed, src/ directory structure
- **Project hygiene:** README describes architecture, .gitignore covers .env/.aws-sam/__pycache__, CloudFormation outputs include ARNs and URLs
Return structured output with:
- `has_violations`: true only when one or more actual compliance violations are found.
- `report`: a concise markdown report with pass/fail per applicable item.
Only flag actual violations — skip items that don't apply to this repo (e.g., skip Lambda checks if no Lambdas exist).
Do not create or modify files, issues, pull requests, or comments.
claude_args: |
--json-schema '{"type":"object","properties":{"has_violations":{"type":"boolean","description":"True when one or more actual compliance violations are found."},"report":{"type":"string","description":"Concise markdown report with pass/fail per applicable compliance item."}},"required":["has_violations","report"],"additionalProperties":false}'
- name: Create issue if violations found
if: ${{ fromJSON(steps.audit.outputs.structured_output).has_violations == true }}
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
AUDIT_RESULT: ${{ steps.audit.outputs.structured_output }}
run: |
gh label create compliance \
--repo "Sea-Haven-Industries/${{ matrix.repo }}" \
--description "Weekly compliance audit" \
--color "D93F0B" 2>/dev/null || true
existing=$(gh issue list \
--repo "Sea-Haven-Industries/${{ matrix.repo }}" \
--label "compliance" \
--state open \
--json number \
--jq 'length')
if [ "$existing" -eq 0 ]; then
report=$(jq -r '.report' <<< "$AUDIT_RESULT")
body_file=$(mktemp)
{
echo "The weekly compliance audit found violations in this repo."
echo
echo "## Audit report"
echo
printf '%s\n' "$report"
echo
echo "Check the [latest audit run](https://github.com/Sea-Haven-Industries/.github/actions/workflows/compliance-audit.yaml) for details."
} > "$body_file"
gh issue create \
--repo "Sea-Haven-Industries/${{ matrix.repo }}" \
--title "Compliance audit: violations found" \
--body-file "$body_file" \
--label "compliance"
fi