skills/do-cybersecurity-review/SKILL.md
Run a security audit of the project's existing codebase and write a findings report to docs/security-audit.md. Covers secrets exposure, dependency vulnerabilities, authentication and authorisation patterns, input validation, transport security, and common OWASP risks. Run as part of do-init or on demand.
npx skillsauth add thermiteau/maverick do-cybersecurity-reviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Audit a codebase for security risks. Operates in two modes:
do-init at adoption time and on demand. Produces docs/security-audit.md. Flips cybersecurity_reviewed milestone.do-issue-solo and do-issue-guided as a mandatory pre-push gate before opening a PR. Returns a structured findings list to the orchestrator; does not flip the milestone (it's per-PR work, not a one-time milestone).Refer to mav-bp-application-security for the standards each finding should be measured against. The skill surfaces risks; it does not modify code.
Run this first. If it exits non-zero, halt and report the stderr output to the user verbatim. Do not proceed.
uv run maverick preflight do-cybersecurity-review
The check verifies the project is initialised and uv is on PATH.
If `` specifies a mode (full-audit or update), use it. If update is selected the caller must also pass a diff (via stdin or a file path); halt and ask for one if missing.
If no mode is specified, default to full-audit.
Identify language, framework, and runtime so subsequent checks know what to look for. Use the same detectors as do-maverick-alignment: package.json, pyproject.toml, Dockerfile, etc.
For each category below, search the codebase and assign one of:
Scan tracked files for committed credentials, tokens, private keys, and connection strings. Patterns to check (extend per stack):
AKIA[0-9A-Z]{16} (AWS access key id), aws_secret_access_key\s*=-----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY-----ghp_, gho_, ghs_, github_pat_ (GitHub tokens)xox[baprs]- (Slack tokens), sk- followed by 20+ alphanumerics (OpenAI/Anthropic-style)password\s*=\s*['"][^'"]+['"], api[_-]?key\s*=\s*['"][^'"]+['"]Also check .env* files (any tracked) and history (git log --all --full-history -- .env).
| What | Where to look |
| --- | --- |
| Lock file present | package-lock.json, pnpm-lock.yaml, yarn.lock, uv.lock, poetry.lock, Cargo.lock, go.sum |
| Vulnerability scanning configured | npm audit in CI, pip-audit, safety, cargo audit, trivy, Dependabot, Renovate |
| Pinned versions | Direct deps pinned to a specific version or range |
| No supply-chain red flags | typosquats, abandoned packages, unfamiliar registries |
open() / fs.readFile)?shell=True with untrusted input, no eval)?* for credentialed endpoints?.dockerignore keeping .env, secrets, and .git out of layers?Create docs/security-audit.md (create docs/ if it doesn't exist). Use this structure:
# Security Audit
**Generated:** <ISO timestamp>
**Stack detected:** <e.g., Node.js + Express, Python + Django>
## Summary
<1-2 sentences. Highest-severity finding. Headline risk.>
| Category | Status |
| --- | --- |
| Secret exposure | PASS / WARN / FAIL / N/A |
| Dependency hygiene | ... |
| Authentication / authorisation | ... |
| Input validation / output encoding | ... |
| Transport, headers, CORS | ... |
| Data at rest | ... |
| Logging, monitoring, rate limiting | ... |
| Container / infrastructure | ... |
## Details
### <Category> — <STATUS>
<Evidence: file paths, snippets, dependency names. Be concrete.>
<If WARN/FAIL: a one-paragraph recommendation with a concrete next step.>
<repeat per category>
## Recommendations (prioritised)
1. **<Severity: high/medium/low>** — <action>. <File or area>. <Why it matters>.
2. ...
Use one-line citations (path/to/file:42) so a human (or a follow-up agent) can jump straight to evidence.
After writing the report, print:
Once the report is written, record that the cybersecurity review has run on this project:
uv run maverick integration set cybersecurity_reviewed true
This commits the milestone into .maverick/config.json so other Maverick skills (and maverick integration get) can see it.
Diff-scoped review used as a mandatory pre-push gate by do-issue-solo and do-issue-guided. Reviews only the changed code and the code that could be impacted by it — not the whole codebase. Returns findings to the orchestrator as a structured outcome.
This mode does not flip the cybersecurity_reviewed milestone — it runs on every PR, not once per project lifetime.
Caller passes the diff via stdin or as a file path. Parse it to get:
package.json, pyproject.toml, Cargo.toml, lock files), env / config files, IaC, or CI workflows — those carry security weight beyond the line countIf no diff was provided, halt and ask the caller for one. Do not silently fall back to a full-audit scan.
A change to a function, type, schema, or config can introduce security risk in code that wasn't itself edited. For each changed entity, identify the impact set:
| Change kind | Impact set to audit | | --- | --- | | Function signature / body | All callers (use grep / IDE-equivalent symbol search) | | Exported type / schema | All importers; also serialisation / persistence sites | | Auth / authz primitive (middleware, decorator, role) | Every route or handler protected by it | | Public API surface (route, endpoint, GraphQL resolver) | Clients of that API; rate-limits and input validation around it | | Config or env variable | Every reader of that config; consider whether the new value needs to be a secret | | Dependency added or upgraded | The added/upgraded package itself: licence, known CVEs, transitive deps | | Dockerfile / IaC | The deployed surface that uses it |
The impact set is bounded — do not transitively trace until the entire codebase is included. Stop at one or two hops; if the impact is wider than that, surface it as a finding ("this change has wide reach; recommend a fuller review") rather than try to audit everything.
Apply the same eight categories from Full Audit Mode (Secret exposure, Dependency hygiene, Authentication / authorisation, Input validation / output encoding, Transport / headers / CORS, Data at rest, Logging / monitoring / rate-limit, Container / IaC) — but only against the changed lines and the impact set, not the whole repo.
Most categories will be N/A on any given diff. That is fine. Returning "N/A" with a one-line justification is informative; returning empty findings without saying which categories were considered is not.
The orchestrator wires this output into the PR description or a comment. Format:
{
"verdict": "PASS" | "FINDINGS" | "BLOCKING",
"summary": "<one sentence: what was reviewed and the headline result>",
"categories_considered": ["secret-exposure", "auth", ...],
"findings": [
{
"severity": "critical|high|medium|low",
"category": "<one of the eight>",
"location": "<path/to/file:line>",
"description": "<concrete what + why>",
"recommendation": "<concrete next step>"
}
]
}
Verdict semantics:
low severity items but none are actionable.medium / high items. The PR may proceed; findings are surfaced to the human reviewer in the PR body.critical finding (e.g., a secret committed to the diff, an auth bypass introduced). The orchestrator must halt the push and surface this to the user. Do not return BLOCKING lightly — the bar is "this PR cannot land safely as-is".Update mode produces transient findings, not a snapshot of the whole codebase. Writing to the audit doc would either overwrite valid full-audit content or accumulate noise. Findings stay in the structured output; the orchestrator decides where they end up.
do-issue-solo after the user prioritises them.When invoked from do-issue-solo Phase 7 (or any other
caller) in update mode, do-cybersecurity-review is a
subroutine of the calling workflow — not a terminal action.
Returning the structured verdict is a hand-back to the caller's next
numbered step, not a phase-complete signal (#106).
When you return from this skill, do not post a closing summary, do not stop. The calling workflow still owns, in order:
skill-dispatch interval that wrapped this invocation
(uv run maverick report end skill-dispatch … --outcome <success|failure|blocked>).
The outcome maps from the verdict: PASS → success,
FINDINGS → success (with the findings folded into the PR body
draft), BLOCKING → blocked.BLOCKING, folding findings
into the PR body draft on FINDINGS, or recording
Security review: no concerns. on PASS.If you find yourself drafting a final summary after returning here,
that is the signal: scroll back to the calling workflow and resume
from the step immediately after the
/do-cybersecurity-review dispatch.
development
--- name: do-test description: Write or update tests for a code change. Operates in two modes: `unit` (module-scoped, fast, deterministic) and `integration` (crosses module / service / database boundaries). Intended to be invoked once per testable change from inside a do-issue-* or do-epic phase. Mode is required. argument-hint: mode: unit or integration user-invocable: true disable-model-invocation: false --- **Depends on:** mav-bp-unit-testing, mav-bp-integration-testing, mav-local-verificati
development
Implement a focused code change. Use this skill as the wrapper for any implementation work so the Maverick workflow report captures what was done and so the agent applies the project's coding standards before editing. Intended to be invoked once per task from inside a do-issue-* or do-epic phase, not standalone.
testing
How to stack a PR on top of an unmerged sibling branch, and how to retarget it to the repo's default branch once the sibling merges. Prevents orphan-merge incidents when a dependent story is ready before its parent.
development
Claim, lease, heartbeat, and release protocols for when multiple Claude Code instances may act on the same issue or epic concurrently. GitHub labels and marker comments are the coordination surface; local state is a cache.