Skip to content

rogerchappel/actionpin

Repository files navigation

ActionPin πŸ“Œ

ActionPin is a tiny local-first GitHub Actions workflow checker. It looks for the stuff that quietly turns CI into supply-chain confetti: unpinned actions, broad token permissions, secret-looking literals, risky pull_request_target, and shell steps that fetch the internet straight into bash.

It is boring on purpose: deterministic, offline, no telemetry, no GitHub API required.

Install

npm install
npm run build
node dist/src/cli.js rules

When published, the CLI is exposed as actionpin.

Quickstart

actionpin scan .github/workflows --out actionpin-report.md
actionpin scan fixtures/bad-workflows --format json --fail-on medium
actionpin rules

For local development in this repo:

npm run build
node dist/src/cli.js scan fixtures/bad-workflows --format json --fail-on high

Demo recipe

Run the included fixture scan to see the Markdown evidence format without touching your own workflows:

npm install
npm run build
node dist/src/cli.js scan fixtures/bad-workflows --format markdown --fail-on critical > /tmp/actionpin-demo.md
sed -n '1,80p' /tmp/actionpin-demo.md

The demo fixture includes intentionally risky examples: unpinned third-party actions, broad workflow permissions, a pull_request_target trigger, curl-to- shell, insecure curl flags, and a secret-looking literal. Use the generated Markdown report as a PR comment draft or release evidence artifact.

For a fixture-backed script that produces both JSON and Markdown reports, run:

npm run build
bash demo/run-workflow-scan.sh

The script scans the included bad and good workflow fixtures, checks that the bad fixture fails the high-risk gate, and verifies stable rule IDs in the JSON report.

Promotion drafts for this workflow live in docs/promo/social-hooks.md and docs/promo/release-note.md. For short rule-ID oriented launch drafts, see docs/promo/rule-id-social-pack.md.

See the workflow risk tutorial for a review-ready walkthrough. Use the PR review checklist when you want to turn ActionPin rule IDs into reviewer questions.

For a focused pull_request_target gate with JSON and Markdown artifacts:

bash demo/run-pr-target-gate.sh

See docs/tutorials/pr-target-gate.md and docs/promo/pr-target-gate-social-hooks.md.

For a side-by-side fixture comparison across risky, warning-only, and passing workflow examples:

bash demo/run-fixture-comparison.sh

See docs/tutorials/fixture-comparison.md.

For a focused permissions review artifact generated from the bad workflow fixture:

bash demo/run-permissions-review.sh

See docs/tutorials/permissions-review.md and docs/promo/permissions-review-video-brief.md.

Rules

  • actions.unpinned β€” third-party uses: references must be pinned to a full 40-character commit SHA.
  • permissions.missing β€” top-level permissions: should be explicit.
  • permissions.broad β€” write-all, read-all, and broad top-level write permissions are risky.
  • secrets.plaintext β€” secret-looking literal values should not live in workflow YAML.
  • events.pull_request_target β€” privileged PR workflows need careful review.
  • shell.curl-bash β€” piping remote content into bash/sh is flagged.
  • shell.insecure-flags β€” patterns like set +e, curl -k, and wget --no-check-certificate are flagged.

Configuration

Create actionpin.config.json or pass --config:

{
  "failOn": "medium",
  "format": "markdown",
  "ignoreRules": ["events.pull_request_target"]
}

Inline allow comments are supported for narrow exceptions:

# actionpin allow: actions.unpinned
- uses: actions/labeler@v5

Use them sparingly and leave a human-readable comment nearby.

Safety model

ActionPin only reads workflow paths you ask it to scan, refuses paths outside the repo root, writes only when --out is provided, and never performs network calls while scanning. Reports include stable file/line/snippet evidence and remediation text.

CI usage

- run: npm ci
- run: npm run build
- run: node dist/src/cli.js scan .github/workflows --fail-on high

Use Markdown output for PR artifacts and JSON output for bots or release evidence.

Demo Recipes

Verification

Run the local quality gates before opening a pull request:

npm run lint
npm test
npm run smoke

npm run lint is an alias for the repository static check so contributors can use the common npm workflow without guessing the project-specific command.

Limitations

ActionPin is not a full YAML interpreter or shell static analyzer. It intentionally catches common, review-worthy patterns without trying to prove a workflow is safe. It does not resolve action metadata, verify SHAs, or inspect remote repositories.

Development

npm test
npm run check
npm run build
npm run smoke
npm run package:smoke
npm run release:check
bash scripts/validate.sh

Package contents

The npm package allowlist includes the compiled runtime plus the public support documents needed for release review: README.md, LICENSE, SECURITY.md, CHANGELOG.md, CONTRIBUTING.md, and CODE_OF_CONDUCT.md.

Run npm run package:smoke before publishing to confirm the tarball still contains the expected files.

See docs/PRD.md and docs/TASKS.md for the MVP contract.

Release readiness

Before opening a release PR, run the package checks that exercise the build, tests, smoke path, and pack manifest:

npm run check
npm test
npm run smoke
npm run package:smoke
npm run release:check

The package metadata points at the public GitHub repository so npm and generated provenance link back to the source.

About

Local-first GitHub Actions workflow risk checker.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors