GitHub Repo Setup

Use this skill when setting up or hardening a GitHub repository. It covers branch protection, security features, policy files, and CI supply-chain hardening — all automated via the GitHub REST API.

Prerequisites

  • GITHUB_TOKEN environment variable with admin scope on the target repo (or a fine-grained PAT with Administration, Contents, and Security permissions)
  • gh CLI available, or curl for direct API calls

Workflow

Execute these steps in order for any new or existing public repository.

Step 1 — Branch Protection on main

gh api repos/{owner}/{repo}/branches/main/protection \
  -X PUT \
  -H "Accept: application/vnd.github+json" \
  --input - <<'EOF'
{
  "required_status_checks": null,
  "enforce_admins": true,
  "required_pull_request_reviews": null,
  "restrictions": null,
  "required_linear_history": true,
  "allow_force_pushes": false,
  "allow_deletions": false
}
EOF

By default, PR reviews are not required (set to null). For repos with multiple contributors, enable reviews:

"required_pull_request_reviews": {
  "required_approving_review_count": 1,
  "dismiss_stale_reviews": true,
  "require_code_owner_reviews": true
}

Adjust required_approving_review_count and required_status_checks per repo needs.

If the repo has required CI checks, set:

"required_status_checks": {
  "strict": true,
  "contexts": ["build", "test"]
}

Step 2 — Enable Security Features

Vulnerability alerts (Dependabot alerts)

gh api repos/{owner}/{repo}/vulnerability-alerts -X PUT \
  -H "Accept: application/vnd.github+json"

Automated security fixes (Dependabot security updates)

gh api repos/{owner}/{repo}/automated-security-fixes -X PUT \
  -H "Accept: application/vnd.github+json"

Secret scanning

gh api repos/{owner}/{repo} -X PATCH \
  -H "Accept: application/vnd.github+json" \
  --input - <<'EOF'
{
  "security_and_analysis": {
    "secret_scanning": { "status": "enabled" },
    "secret_scanning_push_protection": { "status": "enabled" }
  }
}
EOF

Private vulnerability reporting

gh api repos/{owner}/{repo}/private-vulnerability-reporting -X PUT \
  -H "Accept: application/vnd.github+json"

Step 3 — Policy Files (via PR)

Create a PR adding these files. Use templates below, customized per repo.

SECURITY.md

# Security Policy
 
## Reporting a Vulnerability
 
Please report security vulnerabilities via
[private vulnerability reporting](https://github.com/{owner}/{repo}/security/advisories/new).
 
**Do not open public issues for security vulnerabilities.**
 
### What to expect
 
- Acknowledgment within 48 hours
- Status update within 7 days
- Fix timeline communicated within 14 days
 
## Security Practices
 
- All dependencies monitored by Dependabot
- Secret scanning with push protection enabled
- Container images signed and include SBOMs where applicable
- Branch protection enforced on `main`

.github/dependabot.yml

version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    commit-message:
      prefix: "ci"

Add additional ecosystems as needed (npm, pip, docker, etc.).

.github/CODEOWNERS

# Security-sensitive files require security team review
SECURITY.md @{org}/security
.github/ @{org}/security

Adjust team handles per organization structure.

Step 4 — CI Supply-Chain Hardening

Audit all workflow files in .github/workflows/ for:

  1. SHA pinning: Replace tag references (uses: actions/checkout@v4) with SHA-pinned versions (uses: actions/checkout@<full-sha>).

    To find the SHA for a tag:

    gh api repos/{action-owner}/{action-repo}/git/ref/tags/{tag} \
      --jq '.object.sha'
  2. Minimal permissions: Ensure each workflow sets explicit permissions rather than using the default write-all:

    permissions:
      contents: read
  3. No pull_request_target with checkout: Flag any workflow that uses pull_request_target and checks out PR code (supply-chain risk).

Step 5 — Verification

After applying all changes, verify the setup:

# Check branch protection
gh api repos/{owner}/{repo}/branches/main/protection \
  --jq '{enforce_admins: .enforce_admins.enabled, required_reviews: (.required_pull_request_reviews.required_approving_review_count // "none"), linear_history: .required_linear_history.enabled}'
 
# Check security features
gh api repos/{owner}/{repo} \
  --jq '.security_and_analysis | {secret_scanning: .secret_scanning.status, push_protection: .secret_scanning_push_protection.status}'
 
# Check vulnerability alerts
gh api repos/{owner}/{repo}/vulnerability-alerts \
  -I 2>&1 | head -1
# 204 = enabled
 
# Check private vulnerability reporting
gh api repos/{owner}/{repo}/private-vulnerability-reporting \
  -I 2>&1 | head -1
# 204 = enabled

Step 6 — Post Completion Checklist

Comment on the Paperclip issue with a summary:

## Repo Setup Complete: {owner}/{repo}
 
- [x] Branch protection on `main` (enforce admins, linear history, no force push/delete)
- [x] Secret scanning + push protection
- [x] Dependabot alerts + automated security fixes
- [x] Private vulnerability reporting
- [x] SECURITY.md
- [x] .github/dependabot.yml
- [x] .github/CODEOWNERS
- [ ] CI SHA pinning (list any remaining tag-only references)

Notes

  • Some features (secret scanning, push protection) require GitHub Advanced Security on private repos. They are free for public repos.
  • Organization-level security defaults may override repo-level settings. Check org settings if API calls return 403.
  • For repos in the cascadeguard org, use @cascadeguard/core as the CODEOWNERS team unless otherwise specified.