Skip to content

Harden public PR CI, secrets, action pinning, and dependency maintenance #104

Description

@jmcte

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

  • Untrusted PR code cannot access persistent self-hosted runner state or repository secrets.
  • Runner policy and threat assumptions are documented.
  • External actions are pinned to immutable SHAs.
  • Project credential/artifact leak fixtures are detected.
  • .gitignore covers expected local secret/data artifacts.
  • actionlint and dependency review/audit run in CI.
  • Python and Actions dependencies receive automated update PRs.
  • CI reports a documented lint/type/coverage baseline.
  • Existing CI Gate semantics 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:infraInfrastructure, CI, release, governance, scripts, or repo setup.area:securitySecurity, auth, secret, permission, or policy surface.bugSomething isn't workingpriority:P1Codex Connector P1; blocks execution until Athena and Ares validate.ready-for-agentIssue is approved for worker-lane execution.risk:securitySecurity-sensitive change.status:ready-for-agentIssue is approved for worker-lane execution.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions