ActionScope
Map the AWS blast radius of your GitHub Actions workflows. One command. No AWS credentials required. Instant plain-English results.
📖 Full documentation: https://r12habh.github.io/ActionScope/ · 🛡️ Compromised Actions Database: https://r12habh.github.io/ActionScope/compromised-actions-database/
Your GitHub Actions workflows hold AWS credentials. Do you know what they can do?
ActionScope reads your .github/workflows/ files, Terraform IAM resources,
and JSON IAM policies, then tells you in plain English what your CI/CD
pipeline can do in AWS if it is compromised.
It also detects:
- 🚨 Known-compromised actions (
actions-cool,tj-actions,trivy-action) - 🔓 OIDC trust policy misconfigurations (wildcards, missing claims, unsafe set operators)
- 💉 Script injection (PR titles, issue bodies in
run:blocks) - 🎭 Artifact poisoning (
workflow_run+ untrusted artifact execution) - 🤖 AI agent prompt injection surfaces (Claude Code, Copilot in CI)
- 📌 Unpinned actions with SHA resolution
- 🔁 Reusable workflow inspection (local recursion and authenticated external fetches)
- 🔗 Correlated exposure paths (risky action → AWS role → reachable IAM)
The workflow only says it assumes a role. ActionScope joins it to the IAM behind it and shows what that role can actually do if CI is compromised — here: pass any IAM role (privilege escalation), wipe S3, and terminate EC2. Reproduce this scan yourself »
Try it on your repo in 30 seconds
pip install actionscope
cd /path/to/your/repo-with-github-actions
actionscope scan .
That's it. No AWS credentials needed, no telemetry, no sign-up. Static
analysis runs in under a second on a typical repo. If you have nothing
relevant, you get Observed Risk: ℹ️ INFO. If an AWS role cannot be matched
to a policy, ActionScope reports Coverage: PARTIAL instead of treating the
unknown permissions as safe.
Want a guided first-scan walkthrough? See Your First Scan — 5 minutes from install to understanding the output.
Common flags
actionscope scan . --aws-verify # fetch live IAM policies (read-only)
actionscope scan . --resolve-pins # suggest full-SHA pins for unpinned actions
actionscope scan . --github-token "$GITHUB_TOKEN" # inspect external reusable workflows
actionscope update-db # refresh compromised-action advisories
actionscope scan . --offline # guarantee no scan-time API calls
actionscope scan . --fail-on high # legacy: gate on aggregate observed risk
actionscope scan . --fail-on high --min-confidence high
actionscope scan . --fail-on high --new-only --min-confidence high
actionscope scan . --output-format sarif --output-file results.sarif
actionscope scan . --save-state # save state for PR delta comparison
actionscope config init # create a repository risk policy
For CI, start in report-only mode. Once a default-branch baseline exists,
block only new, high-confidence findings. See
Confidence-Aware CI Gating.
Use .actionscope.yml for reviewed hard blocks,
time-bounded suppressions, custom IAM escalation paths, and repository-specific
risk calibration.
Example Output
ActionScope — Blast Radius Report
Path: /my-repo | Workflows: 2
Observed Risk: 🔴 CRITICAL
Coverage: COMPLETE
Gate: REPORT ONLY
⛔ KNOWN COMPROMISED ACTIONS (1 found)
──────────────────────────────────────────────────────────────
⛔ CRITICAL: actions-cool/issues-helper@v3 (issue-triage.yml)
Compromised 2026-05-18 — mutable tags may run credential-stealing code
Fix: Remove this action or pin to a verified pre-compromise SHA
Correlated Exposure Paths (1 found)
──────────────────────────────────────────────────────────────
🔴 CRITICAL: mutable action → AWS credentials
Workflow: deploy.yml → deploy
Action: third-party/deploy-helper@v1
Credential: arn:aws:iam::123456789012:role/github-deploy-role
Reachable IAM: iam:PassRole, ec2:TerminateInstances, s3:PutObject
─────────────────────────────────────────────────────────────
deploy.yml → deploy → Configure AWS credentials
AWS Role: arn:aws:iam::123456789012:role/github-deploy-role
Auth: OIDC ✓
┌─────────────────────────────┬────────────────────┬──────────┐
│ iam:PassRole │ Permissions mgmt │ 🔴 CRIT │
│ ec2:TerminateInstances │ Write │ 🟠 HIGH │
│ s3:GetObject │ Read │ 🟢 LOW │
└─────────────────────────────┴────────────────────┴──────────┘
🔴 Privilege Escalation Path: iam:PassRole on * — can escalate to any role
Use as a GitHub Action
name: ActionScope Security Scan
on: [push, pull_request]
permissions:
contents: read
security-events: write # for SARIF upload
pull-requests: write # for PR comments
jobs:
actionscope:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: r12habh/ActionScope@v0
with:
fail-on: high # block new, high-confidence HIGH/CRITICAL findings
new-only: true # only newly gate-eligible findings
min-confidence: high # avoid blocking on heuristic matches
save-state: true # save trusted default-branch baselines
comment-pr: true # post findings as a PR comment
upload-sarif: true # show findings in the Security tab
The first run has no baseline, so a new-only gate is reported as
NOT EVALUATED and the trusted default-branch run seeds the cache. The
Marketplace Action is report-only unless fail-on is explicitly set.
What Makes ActionScope Different
ActionScope answers a question no other tool answers:
"This workflow assumes this IAM role. If the workflow is compromised, what can an attacker actually do in your AWS account?"
| Capability | actionlint | zizmor | Scorecard | ActionScope |
|---|---|---|---|---|
| Workflow syntax validation | ✅ | Partial | ❌ | Partial |
| Security pattern detection | ❌ | ✅ | ✅ | ✅ |
| GITHUB_TOKEN permission review | ❌ | ✅ | ✅ | ✅ |
| Unpinned action detection | ❌ | ✅ | ✅ | ✅ |
| Known-compromised action detection | ❌ | ❌ | ❌ | ✅ |
| AWS credential source detection | ❌ | ❌ | ❌ | ✅ |
| Workflow → IAM role correlation | ❌ | ❌ | ❌ | ✅ |
| Action → AWS exposure-path correlation | ❌ | ❌ | ❌ | ✅ |
| Live AWS IAM policy verification | ❌ | ❌ | ❌ | ✅ |
| Blast radius in plain English | ❌ | ❌ | ❌ | ✅ |
| OIDC trust policy analysis | ❌ | ❌ | ❌ | ✅ |
| Script injection detection | ❌ | Partial | ❌ | ✅ |
| Reusable workflow inspection | ❌ | Partial | ❌ | ✅ |
| SARIF / GitHub Security tab | ❌ | ✅ | ✅ | ✅ |
How It Works
ActionScope performs static analysis only by default. It never sends your
code to an external service and does not require AWS credentials unless you
explicitly enable live AWS verification. When a GitHub token is supplied, it
can fetch referenced external reusable workflow YAML from GitHub for analysis.
Use --offline to disable every scan-time GitHub and AWS API call even when
credentials are present in the environment.
.github/workflows/*.yml
terraform/**/*.tf → ActionScope → Blast Radius Report
policies/**/*.json + PR Comment
+ SARIF → GitHub Security Tab
- Find
aws-actions/configure-aws-credentialsin workflows - Follow local reusable workflows and optionally inspect external calls
- Extract role ARNs and credential patterns
- Match roles to IAM policies in Terraform or JSON files
- Classify IAM actions using the
policy-sentryaction database - Correlate risky actions with AWS credentials in the same job
- Detect privilege escalation paths
- Check for known-compromised actions in the bundled or local cached database
- Output a plain-English blast radius report
Live AWS Verification (--aws-verify)
pip install actionscope[aws]
actionscope scan . --aws-verify
Requires read-only IAM permissions:
iam:GetRole, iam:ListAttachedRolePolicies, iam:GetPolicy,
iam:GetPolicyVersion, iam:ListRolePolicies, iam:GetRolePolicy.
See docs/aws-verify-permissions.md for the minimal required policy.
Security Detectors
🚨 Known-Compromised Actions
Checks workflows against a curated database of GitHub Actions with documented
supply chain compromises. The bundled copy is updated with each release;
actionscope update-db can refresh a 24-hour local cache between releases.
actionscope update-db
actionscope scan . --offline # uses local data only, including a stale cache
Current entries: actions-cool/issues-helper (2026-05-18),
actions-cool/maintain-one-comment (2026-05-18),
tj-actions/changed-files (2025-03-19), and
aquasecurity/trivy-action (2026-03-19).
🔓 OIDC Trust Policy Analysis
Detects wildcard subjects, missing sub/aud conditions, unsafe
ForAllValues use, and insufficient branch/environment scoping in GitHub
OIDC trust policies.
💉 Script Injection Detection
Finds direct interpolation of attacker-controlled GitHub context values
(github.event.pull_request.title, github.event.issue.body, etc.) into
run: shell blocks: the "Pwn Request" attack class.
🎭 Artifact Poisoning Detection
Identifies workflow_run workflows that download and execute artifacts from
potentially untrusted fork PR workflows with secret access.
🤖 AI Agent Prompt Injection Surface
Detects Claude Code, GitHub Copilot Agent, Gemini CLI and similar AI coding agents configured with write permissions in untrusted PR contexts.
📌 Action Pinning + SHA Resolution
Detects unpinned actions and resolves tags to current SHAs via the GitHub API. Distinguishes full SHAs (safe) from short SHAs (still mutable) and tags.
🔁 Reusable Workflow Inspection
Detects job-level uses: calls, reports mutable reusable-workflow refs, and
recursively inspects local workflows. Supply --github-token (or
GITHUB_TOKEN) to fetch external reusable workflow YAML through GitHub's API;
without a token, ActionScope reports the delegated workflow as uninspected
instead of treating it as clean. Traversal is cycle-safe and follows GitHub's
10-level and 50-workflow limits.
Reusable workflow inspection guide
🔗 Correlated Exposure Paths
Connects mutable or known-compromised actions to AWS credentials configured in the same workflow job. When IAM policy context is available, the path includes the highest-risk permissions that action could reach; otherwise it explicitly marks the blast radius as unknown.
Correlated exposure paths guide
⚡ IAM Privilege Escalation Paths
Detects documented escalation paths including PassRole, CreatePolicyVersion, AttachRolePolicy, CreateAccessKey, Lambda+PassRole, EC2+PassRole, CloudFormation+PassRole, and more.
Research
ActionScope is backed by an empirical study of 493 public GitHub repositories and 3,981 GitHub Actions workflow files using AWS.
| Finding | Result |
|---|---|
| Using static AWS keys (not OIDC) | 58.2% of repos |
| Using unpinned external actions | 95.5% of repos |
pull_request_target + write permissions |
8.1% of repos |
| Exposing role ARNs directly in workflows | 44.0% of repos |
→ Full research findings | Scanner and anonymized dataset
Output Formats
actionscope scan . --output-format terminal # default: colored Rich output
actionscope scan . --output-format json # for CI integration
actionscope scan . --output-format markdown # for PR comments
actionscope scan . --output-format sarif # for GitHub Security tab
FAQ
How do I detect compromised GitHub Actions like tj-actions or actions-cool?
ActionScope ships a curated database of known-compromised actions (tj-actions,
actions-cool/issues-helper, actions-cool/maintain-one-comment, trivy-action)
and scans every uses: reference in your workflows against it. Run
actionscope scan . and any compromised reference appears as a CRITICAL
finding with the advisory URL.
What can my GitHub Actions workflow do in my AWS account?
ActionScope extracts every aws-actions/configure-aws-credentials step from
your workflows, follows the role ARN, and correlates it with Terraform or JSON
IAM policy files in the same repo. The output is a plain-English blast-radius
report — every IAM action the workflow can perform, classified by risk. Add
--aws-verify to fetch the live policies from AWS using read-only IAM calls.
How do I scan a GitHub Actions workflow for security issues without AWS credentials?
actionscope scan . runs as pure static analysis by default. It needs no AWS
credentials and no GitHub token. A token is optional for --resolve-pins and
for inspecting external reusable workflows; local workflow analysis never
needs one.
How do I find script injection or pull_request_target risks?
ActionScope detects direct injection of attacker-controlled GitHub event
fields (PR titles, issue bodies, branch names) into run: blocks, and flags
pull_request_target jobs that combine untrusted event data with
write-capable GITHUB_TOKEN permissions — the pattern behind the April 2026
prt-scan attack.
How do I get GitHub Code Scanning alerts for my workflows?
Run actionscope scan . --output-format sarif --output-file results.sarif
and upload results.sarif to the GitHub Security tab via the
github/codeql-action/upload-sarif action. ActionScope emits SARIF rules
AS001–AS016 covering AWS exposure, OIDC trust, unpinned actions,
compromised actions, script injection, environment hardening, and correlated
action-to-AWS exposure paths.
How do I pin GitHub Actions to a full commit SHA?
actionscope scan . --resolve-pins uses the GitHub API to look up the
current full-SHA tip for every mutable uses: owner/repo@vX reference in
your workflows and prints a suggested pinned version with the tag preserved
as a comment.
What's the difference between ActionScope and actionlint, zizmor, or Checkov?
actionlint validates workflow YAML syntax. zizmor and Scorecard detect workflow security patterns. Checkov scans IAM policies independently. ActionScope is the only tool that crosses the boundary — it ties a specific workflow to a specific IAM role to a specific blast radius.
Does ActionScope require AWS credentials?
Only if you opt in to --aws-verify, which makes read-only IAM API calls to
fetch live attached policies. See
docs/aws-verify-permissions.md for the
exact permission set required.
Documentation
📖 Full docs site: https://r12habh.github.io/ActionScope/
- First Scan Tutorial — install → first scan → reading the output, in 5 minutes
- FAQ — empty scans,
policy_source: not_found,--aws-verifysafety, DB refresh cadence, tool comparisons - Compromised Actions Database — every action ActionScope flags, with permalinks
- CLI reference
- OIDC trust policy analysis
- Reusable workflow inspection
- Correlated exposure paths
- Known-compromised actions detector
- SARIF and GitHub Security tab
- AWS verification permissions
- Release runbook
Contributing
See CONTRIBUTING.md for setup instructions.
New to the codebase? Start with a good first issue.
The most impactful contributions right now:
- Add IAM actions to the risk database
- Add compromised action entries when a new supply-chain attack happens
- Add test fixtures from real-world workflows, anonymized
- Improve error messages when policies are missing
Built By
Rishabh Singh.
ActionScope performs static analysis by default. It does not transmit your code or credentials to any external service.
Metadata
Release files for actionscope 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| actionscope-0.5.0.tar.gz | 358.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| actionscope-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 486.1 kB
Release files / actionscope-0.5.0.tar.gz
| Download URL | actionscope-0.5.0.tar.gz |
|---|---|
| Size | 358.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
85f5ce9e8a3eeae3d6f531060e71bd0ed78280fb36cb22fe9a949269509afae2
|
|
BLAKE2b-256 checksum How to use checksums |
97912125154b2a419249b1835cabbdff25316e59446f8e08f6052ae6a64759e6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logRelease files / actionscope-0.5.0-py3-none-any.whl
| Download URL | actionscope-0.5.0-py3-none-any.whl |
|---|---|
| Size | 128.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
93b34c1820598e7acf0636765933c73826b1734cd75330915bc15d8fe3a76b9b
|
|
BLAKE2b-256 checksum How to use checksums |
9412652c01624e7e298cf63ae26119641ff50b7cb34b20e73bf457d93658da56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency log