Problem
This public repository checks out and executes PR-controlled shell/Python code on self-hosted runners labelled public. That is safe only if the runners are demonstrably ephemeral, isolated, credential-free, and network-constrained.
External Actions use mutable tags. The project-specific scanner/ignore rules do not comprehensively cover .env, MAILPLUS_TOKEN, SQLite databases, or generated export directories. Dependabot is disabled, and there is no actionlint, dependency review, vulnerability audit, lint, type, or coverage gate.
Relevant code
.github/workflows/pr-fast-ci.yml
.github/workflows/claude.yml
.github/workflows/extended-validation.yml
scripts/check-detect-secrets.sh
scripts/ci/check-ci-contract.sh
.gitignore
project.bootstrap.yaml:76-90
pyproject.toml:17-20
Scope
- Document and enforce the trust boundary for fork/PR code.
- Use GitHub-hosted runners for untrusted PR execution unless an equivalent ephemeral-isolated design is proven and tested.
- Keep credentials and privileged network access off untrusted lanes.
- Pin external actions by full commit SHA with version comments.
- Harden ignore and scanning rules for project credential names and generated artifacts.
- Add tests for
MAILPLUS_TOKEN, .env, *.db, WAL/SHM files, mailbox exports, and export directories.
- Add actionlint and dependency review/audit.
- Enable Dependabot or equivalent automation for Python and GitHub Actions.
- Add a pragmatic Ruff/type/coverage baseline without obscuring the behavior-focused gates.
Non-goals
- Do not expose runner infrastructure details or credentials in public logs.
- Do not weaken required checks to accommodate runner availability.
- Do not treat handcrafted regex scanning as complete DLP.
Acceptance criteria
Validation
Include workflow syntax/actionlint results, a fork-equivalent permissions check, scanner regression tests, and the exact required-check state observed on the PR.
Parent
Part of #98.
Problem
This public repository checks out and executes PR-controlled shell/Python code on self-hosted runners labelled
public. That is safe only if the runners are demonstrably ephemeral, isolated, credential-free, and network-constrained.External Actions use mutable tags. The project-specific scanner/ignore rules do not comprehensively cover
.env,MAILPLUS_TOKEN, SQLite databases, or generated export directories. Dependabot is disabled, and there is no actionlint, dependency review, vulnerability audit, lint, type, or coverage gate.Relevant code
.github/workflows/pr-fast-ci.yml.github/workflows/claude.yml.github/workflows/extended-validation.ymlscripts/check-detect-secrets.shscripts/ci/check-ci-contract.sh.gitignoreproject.bootstrap.yaml:76-90pyproject.toml:17-20Scope
MAILPLUS_TOKEN,.env,*.db, WAL/SHM files, mailbox exports, and export directories.Non-goals
Acceptance criteria
.gitignorecovers expected local secret/data artifacts.CI Gatesemantics remain clear and required.Validation
Include workflow syntax/actionlint results, a fork-equivalent permissions check, scanner regression tests, and the exact required-check state observed on the PR.
Parent
Part of #98.