Experimental static analysis · GitHub Actions

Before an agent acts,
review its authority.

See where untrusted events meet AI agents, write permissions and secrets. Turn workflow configuration into a focused review.

Accuracy unmeasured. No sealed human-labeled evaluation. Findings are review hypotheses, not a production security gate. Read the limits.

REVIEW CHECKLISTSchematic
# Questions, not executable YAML
event: external comment
agent input: does it read the comment?
authority: which token can it use?
EventAgent input?Token authority?
NOT A SCAN RESULT

Verify the execution path

A trigger and write permission do not prove an agent runs, reads the comment or can write. Check required inputs and runtime gates.

Scan a real workflow below for findings.
A clearer view of the workflowEvent reachabilityEffective permissionsExplicit analysis limits

01 / FROM YAML TO REVIEW

Follow the path.
Keep the context.

Guard models supported configuration paths. It does not execute your agent or inspect its runtime behavior.

01

Read the workflow

Inspect detected AI-agent actions and CLI usage, triggers, permissions, environment references and local reusable workflows.

02

Surface possible risk

Connect supported untrusted event paths with agent usage, write authority, secret references and action pinning.

03

Make review inspectable

Use source locations, rule explanations and SARIF. Recognized analysis gaps produce diagnostics; unmodeled paths can still be missed.

02 / TRY ONE WORKFLOW

Run the scanner.
Inspect its limits.

Paste one GitHub Actions workflow or choose a YAML file. This browser-only trial does not upload your file or connect to GitHub. Do not paste actual credentials. Use the CLI or Action for repository-wide context.

Maximum 250,000 characters (250 KB for selected files) and 500 steps across all jobs. Only the supplied file is scanned: local reusable workflow bodies and repository config are unavailable. This is not a GitHub Actions schema validator. No result is proof of safety.

ACTUAL SCANNER OUTPUT

Preparing scanner

Preparing the browser scanner. If this message persists, refresh the page or use the CLI or GitHub Action.

Build provenance (not accuracy evidence)

Page build source: 09a071801799be2723e5204305e39831e5a6e4eb (clean checkout; publication not verified by this build). Scanner bundle SHA-256: fbbb977ae794c7f6e666a4ffaa5d3731616cebb5f64eb9b606da0856168b2c1e. The browser checks the content-addressed scanner and renderer scripts with Subresource Integrity; if an older script is unavailable, refresh the page. This does not measure scanner accuracy.

03 / A SMALL CHANGE, A DIFFERENT REVIEW

Authorization is context.
It is not content trust.

Compare three illustrative configurations. The reproduced case below is separate from these examples; this page does not scan your repository.

UNREVIEWED VERSION

Verify the gate before reducing risk.

A mutable tag or an unreviewed commit does not establish the Action’s authorization behavior. The scanner reports action pinning separately; inspect the deployed version before relying on its gate.

In every case

A maintainer can act on attacker-authored content. Read-only workflow permissions do not rule out separately minted tokens or secret exposure. Pinned Action security documentation ↗

04 / REPRODUCIBLE REGRESSION CASE

One workflow.
A checkable result.

This is a developer-authored synthetic fixture. Its expected results come from the checked-in corpus manifest, not independent human labels. It checks a known rule boundary; it does not measure precision or recall on real workflows.

PUBLIC SOURCE COMMIT · 5c045e0 · FIXTURE event-gated-prt

Only the PR-target event selects this agent job

name: event-gated-prt
on:
  push:
  pull_request_target:
permissions:
  contents: read
jobs:
  agent:
    if: github.event_name == 'pull_request_target'
    runs-on: ubuntu-latest
    steps:
      - uses: anthropics/claude-code-action@0123456789abcdef0123456789abcdef01234567
        with:
          prompt: ${{ github.event.pull_request.body }}

The 40-character Action ref is a synthetic placeholder for static analysis. It does not identify a verified vendor release; do not run this fixture as a workflow.

Expected versus observed

RuleExpectedObserved
agentci/pull-request-target-aicriticalcritical
agentci/untrusted-input-in-prompthighhigh

The pinned public manifest expects these two rule/severity pairs. The bundled browser scanner reproduces them with no diagnostics and analysis_complete: true. This is a regression check, not an independent accuracy result.

Why: the job condition excludes push and selects pull_request_target; its prompt includes a PR body. The fixture does not execute the Action or establish whether its runtime actor gate would admit a particular PR author. These are static findings, not a demonstrated exploit.

Reproduce from the pinned public commit
git clone https://github.com/David-Wu1119/agentci-guard.git
cd agentci-guard
git checkout 5c045e0469f412aecd0f9d5f32876bf10c7fc66b
node dist/cli.js scan corpus/adversarial/cases/event-gated-prt --json --fail-on none

05 / KNOW THE BOUNDARY

Useful signals.
Explicit limits.

Use Guard alongside source review and runtime controls. A supported clean scan is not proof of security.

Possible paths, not exploits

Severity reflects review priority over supported static semantics. It does not prove an attacker can execute a path.

Coverage has edges

Dynamic expressions, scripts, tool-driven fetches and remote reusable workflows can exceed the model. Even a complete scan can miss an unmodeled path.

Accuracy is unmeasured

The 152 fixed development snapshots let readers rerun scanner behavior; they do not establish accuracy. Sealed human-labeled evaluation and measured precision/recall are not established.

Version matters

The fixture and expected results are pinned to a public commit; this page's browser scanner is a separate build. Compare versions before treating a mismatch as a regression.

START WITH ONE WORKFLOW

Less guesswork.
A more focused review.

Try the scanner

Browser-only scan for one workflow. No account connection.