coder/coder-skill-scanner is a periodic, GitHub-Actions-as-SaaS security
scanner for agent skills declared in the Coder registry.
This file is the contributor and agent guide for working in this repo.
Read README.md first for the architecture. The short version:
config.yamlis the only user-facing surface. Catalogue source, scanner pins, verdict thresholds, publish destinations.schema/report.schema.jsonis the contract the registry site reads against. Bumping it is a coordinated, versioned change.scripts/will hold the enumerate, scan, combine, and publish steps (added in follow-up PRs)..github/workflows/scan.yamlis the scheduled scanner (also follow-up).
- Doing it right is better than doing it fast.
- Tedious, systematic work is often the correct solution. Do not abandon an approach because it is repetitive; abandon it only if it is technically wrong.
- Honesty is a core value. Push back on bad ideas with reasoning.
- Pin every action and external CLI by commit SHA.
- Bash scripts MUST be ShellCheck-clean against
.shellcheckrcand prettier-clean againstprettier-plugin-sh. - No emdash (U+2014), no endash (U+2013), no
--punctuation in code, comments, strings, or markdown. Use commas, semicolons, or periods. - Commit format:
type(scope): message. Scopes are real paths (e.g.,fix(scripts/scan-clamav.sh): ...). - PR titles follow the same format.
- Default branch is
main. - Direct pushes to
mainare reserved for the initial bootstrap and for thepublish-release/publish-pagesActions jobs. Everything else lands via PR. - The scanner workflow's only elevated permission is
contents: writefor the release publisher andpages: write+id-token: writefor the Pages deployer. Audit changes to those jobs carefully.
make lintruns ShellCheck andprettier --checkoverscripts/(target added with the scripts in PR 2).make schemavalidatesschema/report.schema.jsonagainst the metaschema and against fixture reports intestdata/.make self-testruns the full pipeline againsttestdata/fixture-*(target added in PR 2). No network calls; uses local upstream fixtures.
schema/report.schema.json is v1.0.0. Backward-compatible additions
bump the minor. Anything that changes the shape of an existing field
or removes a field is a major and ships as a parallel
latest-v2.json with a coordinated coder/registry-server proxy
cutover. Never break the v1 URL.
When the scheduled scan fails, JasonEtco/create-an-issue opens or
updates a single rolling tracker labelled scanner-down. Do not close
that issue unless the underlying problem is fixed; closing without a
fix means the next run will reopen.
Material decisions and tradeoffs get written down in
.github/decisions/<NNN>-<topic>.md (directory added when the first
decision lands). For this bootstrap:
- VirusTotal Public API is excluded (commercial-use restriction). ClamAV fills the malware-signature slot. See README and Plan v2.
- SkillSpector runs in
--no-llmstatic mode for the periodic scan. LLM mode is opt-in for ad-hoc analysis. - Publishing uses GitHub Releases (canonical) + GitHub Pages via
actions/deploy-pages(public read path). No hand-committed gh-pages branch.
- Block any registry deploy. The catalogue ships independently. The scanner publishes findings the site can show; it never gates.
- Scan private repos. Catalogue source repos must be public.
- Upload files to any third-party scanner. ClamAV runs locally on the runner; SkillSpector runs locally on the runner. No files leave the runner unless the scanner explicitly opts in.
These files may be gitignored, read manually if not auto-loaded.
@AGENTS.local.md