Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ jobs:
- name: Install dependencies
run: pip install -e ".[dev]"

- name: Dependency audit (pip-audit)
run: |
python -m pip install pip-audit
pip-audit --strict || pip-audit

- name: Lint
run: ruff check .

Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/claude-security-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: AI Security Review

on:
pull_request:

permissions:
pull-requests: write
contents: read

jobs:
ai-review:
runs-on: ubuntu-latest
steps:
# Gate the job on the secret being set so forks / fresh clones don't
# red-fail. The `secrets` context can't be used directly in `if:`, so we
# route through a step output. When CLAUDE_API_KEY is unset, the job
# emits a notice and skips the actual analysis steps.
- name: Check CLAUDE_API_KEY presence
id: gate
env:
API_KEY: ${{ secrets.CLAUDE_API_KEY }}
run: |
set -euo pipefail
if [ -z "${API_KEY:-}" ]; then
echo "::notice::CLAUDE_API_KEY secret is not set — skipping AI security review. Set the secret in repo settings to enable."
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi

- uses: actions/checkout@v6
if: steps.gate.outputs.skip == 'false'
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 2

# Pinned to a specific commit SHA. Bumped via Dependabot (group: actions).
- name: AI security review
if: steps.gate.outputs.skip == 'false'
uses: anthropics/claude-code-security-review@0c6a49f1fa56a1d472575da86a94dbc1edb78eda
with:
comment-pr: true
claude-api-key: ${{ secrets.CLAUDE_API_KEY }}
39 changes: 39 additions & 0 deletions claude-security-guidance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Security guidance

This file is read by Anthropic's Claude Code Security Guidance Plugin
(released 2026-05-26) as an **in-session guard** while Claude writes code.
It complements — does not replace — the post-PR `claude-code-security-review`
GitHub Action and the repo-level `audit_security` check.

> Generated by `@starter-series/create seed-security-guidance` on 2026-06-03.
> Edit freely — the plugin re-reads this file on every session.

## Universal rules

These apply to every file in this repo regardless of starter type.

- Never log secrets, API keys, OAuth tokens, or session cookies — redact before any logging call.
- Never use `eval`, `Function()`, dynamic `import()` of untrusted strings, or string-concatenated SQL/shell.
- Validate all external input (HTTP body, env var, CLI arg, file content) with a schema validator (Zod / Pydantic) before processing.
- Prefer `path.join` / `path.resolve` over string concatenation for paths. Reject inputs that resolve outside the working directory.
- Never commit `.env*` files. They must be in `.gitignore` and `.env.example` is the canonical placeholder source.
- HTTP fetches must have an explicit timeout (5–30 s) and AbortController; no unbounded waits.
- Use OIDC trusted publishing for npm / PyPI / GHCR. Reject any long-lived registry token in CI workflows.

## Project-specific section

Add your own org / project rules below. Examples to consider:

- Auth/session handling rules
- Logging/redaction rules
- External-service allowlist
- Database access patterns
- CI/CD secret naming conventions

## How this file gets used

1. **Anthropic Claude Code Security Guidance Plugin** (in-session): scans this file at session start and applies the rules as a pre-tool-call guard.
2. **`audit_security` MCP tool**: detects the file's presence and reports the `claude-security-guidance` check as PRESENT.
3. **PR review (`claude-code-security-review` Action)**: applies the same rules to PR diffs as a post-write check.

If you change a rule, ship the change in a normal PR — the `claude-code-security-review` Action will re-evaluate older PRs in flight against the new rule set.
Loading