GitHub Actions security policy¶
KiCad MCP Pro treats workflow automation as a privileged production surface. Repository settings and committed policy checks therefore apply least privilege at two layers.
Repository settings baseline¶
The repository is configured with:
- read-only default
GITHUB_TOKENpermissions; - workflow pull-request approval disabled;
- only selected GitHub Actions allowed;
- immutable commit-SHA references required;
- GitHub-owned Actions allowed, with every other Action repository explicitly allowlisted.
The expected settings and third-party Action repositories are recorded in .github/actions-policy.json. Direct workflow dependencies and transitively invoked Action repositories are tracked separately so repository settings cover composite-Action dependencies without hiding unused direct dependencies.
Workflow permission rules¶
Every workflow declares contents: read at workflow scope. Write permissions are permitted only at job scope and must exactly match the matrix in .github/actions-policy.json.
Publishing jobs receive only the scopes required for their destination. Examples include id-token: write for trusted publishing, packages: write for the container registry, and contents: write only where a release or documentation deployment must update repository state.
A new write scope requires all of the following in the same pull request:
- a narrowly scoped job-level permission;
- an update to
.github/actions-policy.json; - a security rationale in the pull-request description;
- successful workflow policy and security checks.
Periodic RustSec advisory-database drift review¶
The read-only rustsec-weekly.yml workflow runs every Wednesday at
06:23 UTC and supports explicit manual dispatch. Unlike the path-aware
ci.yml RustSec job, it checks for new RustSec advisory DB findings even
when src-tauri/Cargo.lock has not changed. GitHub scheduled workflows
run the latest default-branch commit. The job has only contents: read, a
SHA-pinned credential-free checkout and a pinned cargo-audit 0.22.2, and
uses the same fail-closed validator and reviewed
.github/security/rustsec-baseline.json as existing CI. Unexpected new
warnings/vulnerabilities or the removal of a baseline entry fail; no
advisory is ignored, no lockfile is upgraded, and scanner or policy errors
cannot be silently treated as a successful scan. Raw JSON evidence is
removed after evaluation and is never uploaded as a public artifact.
The existing Linux GTK3-transitive RUSTSEC-2024-0429 and
RUSTSEC-2024-0370 warnings are still present and tracked by #779;
a green matching-baseline run is a drift check, not evidence of
mitigation or closure of Code Scanning Scorecard #53. The workflow is
neither a release gate nor a new required PR context; ordinary dependency
change PRs continue to use the existing mandatory CI policies. Weekly
results should trigger #779 upstream-dependency reassessment when the
reviewed RustSec findings change, without weakening the warnings baseline.
Action allowlist changes¶
A third-party Action may be added only when its repository is listed in .github/actions-policy.json and the workflow references a full 40-character commit SHA. Tags and branches are rejected even for allowlisted repositories. Composite Actions may invoke other Actions; those repositories must be recorded in the transitive allowlist and confirmed from the pinned parent Action source.
Prefer GitHub-owned Actions or existing allowlisted repositories. Review the Action source, release history, permissions, network behavior, and maintenance status before expanding the allowlist.
Protected paths¶
.github/CODEOWNERS explicitly covers workflows, the Actions policy, release metadata, package manifests, registry metadata, and the security policy. These rules make security-sensitive changes visible to the maintainer and are designed to support required CODEOWNER review when an independent maintainer is available.
Local verification¶
Run:
corepack pnpm run workflows:policy
corepack pnpm run workflows:lint
corepack pnpm run workflows:security
The policy check fails when a workflow gains an undeclared write scope, uses an unapproved Action repository, references a mutable Action tag, omits the read-only workflow baseline, or removes a protected CODEOWNERS rule.
Rollback¶
If a required workflow is blocked after a repository-policy change:
- identify the exact Action repository or missing job permission from the failed run;
- validate the proposed exception in a pull request;
- update the committed policy and repository setting together;
- retain SHA pinning and read-only defaults during rollback.
Do not restore unrestricted Actions or repository-wide write permissions as a temporary workaround.