---
allowed-tools: Bash(gh api *) Bash(gh repo *) Bash(gh auth *) Read
argument-hint: '[--owner <name>] [--enable-dependabot] [--json]'
context: fork
description: 'OpenSSF-aligned security posture audit across all repos in a GitHub account: default workflow token permissions, allowed-actions policy, branch protection, secret scanning + push protection, and Dependabot alerts. Reports WARN (fixable gaps) vs INFO (opinionated hardening). Read-only by default; the only optional mutation is enabling Dependabot alerts. Use when you ask: "repo security audit", "OpenSSF audit", "are Dependabot alerts on?", "GitHub hardening check", "repo セキュリティ監査", "Actions セキュリティ横断". DO NOT USE FOR: writing code, changing branch protection automatically, or the PR-approval toggle (use gh-pr-perm-audit for that).'
effort: medium
license: MIT
model: claude-sonnet-4-6
name: gh-repo-security-audit
---
# GitHub Repo Security Posture Audit (OpenSSF-aligned)

Audit every repo in an account against OpenSSF Scorecard-style checks and report a clear posture.
**Read-only by default.** The single optional mutation is enabling Dependabot alerts (a pure
security gain). Everything else is reported as a human-gated recommendation. See
`references/openssf-checks.md` for per-check rationale + sources.

## Setup Check
Run `gh auth status` — if not authenticated, output `⚠️ gh CLI not authenticated. Run: gh auth login` and stop.

## Step 1: Resolve scope
- `--owner <name>` or default `OWNER=$(gh api user --jq .login)`.
- Repos: `gh repo list "$OWNER" --no-archived --limit 200 --json name --jq '.[].name'`.

## Step 2: Per-repo checks (GET-only)
For each repo, gather in as few calls as possible:
```bash
# one snapshot of the repo object: visibility, default branch, secret scanning
gh api "repos/$OWNER/$REPO" \
  --jq '[.visibility, .default_branch, (.security_and_analysis.secret_scanning.status // "n/a")] | @tsv'
gh api "repos/$OWNER/$REPO/actions/permissions/workflow" --jq '.default_workflow_permissions'   # read|write
gh api "repos/$OWNER/$REPO/actions/permissions"          --jq '.allowed_actions // "all"'         # all|local_only|selected
gh api "repos/$OWNER/$REPO/branches/$DEFAULT_BRANCH/protection" >/dev/null 2>&1 && echo yes || echo none
gh api "repos/$OWNER/$REPO/vulnerability-alerts"          >/dev/null 2>&1 && echo on  || echo off
```

## Step 3: Severity model
- **WARN** (fixable gap):
  - Dependabot alerts `off`
  - `default_workflow_permissions` = `write` (least-privilege violation; should be `read`)
  - a **public** repo with secret scanning not `enabled`
- **INFO** (opinionated hardening — not a defect):
  - no branch protection on the default branch
  - `allowed_actions` = `all`

## Step 4: Report
```markdown
# Repo Security Audit — <owner> — <DATE>

> Generated by github-flow-kit/gh-repo-security-audit (OpenSSF-aligned)

| Repo | vis | def perms | allowed | branch prot | secret scan | Dependabot |
|---|---|---|---|---|---|---|
| <repo> | public | read | all | none | enabled | on |

## ⚠️ WARN (fixable): <N>
- <repo>: Dependabot alerts OFF
## ℹ️ INFO (hardening): <N>
- <repo>: no branch protection / allowed_actions=all
```

## Step 5: Remediation
**Safe, optional mutation — enable Dependabot alerts** (only with `--enable-dependabot`; pure gain, reversible):
```bash
gh api -X PUT repos/<owner>/<repo>/vulnerability-alerts     # enable  (DELETE to undo)
```
**Human-gated (never auto-applied) — print commands, let the user decide:**
- Token-Permissions: keep default `read`; declare per-workflow `permissions:` blocks in YAML.
- Branch protection (esp. public + bot-PR repos): require reviews from someone other than the actor.
- `allowed_actions` → `selected` + verified creators (stage rollout; third-party actions may break).
- SHA-pin actions (`uses: owner/action@<40-hex-sha>`): add `dependabot.yml` github-actions ecosystem,
  or use `ratchet`/`pin-github-action`.
- Review any `pull_request_target` / `workflow_run` workflows for untrusted PR-head checkout and
  `${{ github.event.* }}` injection into `run:`.

## Summary Output
```
✅ Repo Security Audit — <N> repos

  ⚠️ WARN (fixable) : <n>   (mostly Dependabot OFF — fix with --enable-dependabot)
  ℹ️ INFO (hardening): <n>
  ✅ secure          : <n>

📋 Next: --enable-dependabot for the safe fix; branch protection / allowed_actions / SHA-pin stay manual.

⭐ Found this useful? Star → https://github.com/thinkyou0714/github-flow-kit
```

## Error Handling
| Code | Condition | Exit |
|---|---|---|
| RS-001 | gh not authenticated | 2 |
| RS-002 | owner has no repos | 0 |
| RS-003 | per-repo API error (no admin / archived) | skip that repo |
| RS-004 | API rate limited | stop, show reset time |
