Pwnkemon

GitHub Action

The Pwnkemon Scan GitHub Action runs a full code scan on every pull request, posts findings as a PR comment, and fails the build when something serious is found. It is published at github.com/Pwnkemon/pwnkemon-scan.

How it's different

The Action is deliberately not a wrapper that runs scanners on your GitHub runner. It triggers a scan in an isolated, ephemeral container on Pwnkemon's infrastructure and waits for the result. That has three concrete consequences:

Quick start

  1. Install the Pwnkemon GitHub App on the repos you want to scan. (If you haven't already, do it via Targets in the dashboard.)
  2. Mint a GitHub Action token at /dashboard/tokens → “GitHub Action tokens” → Create. These tokens are narrowly scoped: they can launch scans and read results, and nothing else — they cannot mint other tokens, touch billing, or change your account. See API tokens for the full scope model.
  3. Add it as a repo secret named PWNKEMON_API_TOKEN (Settings → Secrets and variables → Actions → New repository secret).
  4. Drop the workflow file into your repo at .github/workflows/pwnkemon.yml:
name: Pwnkemon Security Scan
on:
  pull_request:
  workflow_dispatch: {}

permissions:
  contents: read
  pull-requests: write

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: Pwnkemon/pwnkemon-scan@v1
        with:
          api-token: ${{ secrets.PWNKEMON_API_TOKEN }}

That's it. Open a PR; the Action posts a findings table as a PR comment, edits it in place on subsequent commits, and fails the build if anything at high severity or above lands.

Inputs

NameDefaultDescription
api-tokenRequired. Pwnkemon API token (pt_action_* kind). Store in repo secrets.
tierstandardScan depth. quick (1 credit, fastest); standard (full LLM triage); deep (10 credits, exhaustive). Allowed tiers depend on your plan — see Pricing.
fail-onhighSeverity floor that fails the workflow run. One of: critical, high, medium, low, none. Default high means criticals + highs fail the build; lower-severity findings report but don't block.
comment-prtruePost (or update in-place) a comment on the PR with the findings table. Requires pull-requests: write in the workflow permissions block.
comment-on-cleantrueWhen the scan finds nothing, still post a “no findings” confirmation comment. Set to false to stay silent on clean runs.
wait-for-completiontrueBlock the workflow until the scan finishes. Set to false to launch async and let the workflow continue immediately (useful when you don't want scans to gate deploys).
timeout-minutes30Max wait time before the Action gives up on a running scan.
github-token${{ github.token }}Token used for the PR comment. Defaults to the workflow's own — only override for cross-repo / app setups.

Outputs

NameDescription
scan-idPwnkemon scan UUID — pass to other steps for cross-reference.
report-urlDirect link to the full report in the Pwnkemon dashboard.
finding-countTotal number of confirmed (post-triage) findings.
statusFinal scan status: completed, failed, cancelled, timeout, or queued (when wait-for-completion: false).

Common configurations

Block deploys only on criticals

- uses: Pwnkemon/pwnkemon-scan@v1
  with:
    api-token: ${{ secrets.PWNKEMON_API_TOKEN }}
    fail-on: critical

Async on push to main, blocking on PRs

on:
  push:
    branches: [main]
  pull_request:
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: Pwnkemon/pwnkemon-scan@v1
        with:
          api-token: ${{ secrets.PWNKEMON_API_TOKEN }}
          wait-for-completion: ${{ github.event_name == 'pull_request' }}

Deep scan on releases, standard everywhere else

- uses: Pwnkemon/pwnkemon-scan@v1
  with:
    api-token: ${{ secrets.PWNKEMON_API_TOKEN }}
    tier: ${{ github.event_name == 'release' && 'deep' || 'standard' }}

What gets scanned

Every commit you trigger the Action on is scanned at that exact commit, not whatever the branch has advanced to by the time the scan starts. We clone the branch, then git checkout the SHA from your CI context — so a scan posted to PR #42 always reflects the code in PR #42, even if main races ahead.

The scan itself runs the same pipeline as a dashboard-launched code scan: see Code scans for the full scanner list, triage behaviour, and reachability classification.

Security model

The token (pt_action_*) is restricted server-side to:

Nothing else. A leaked Action token cannot mint other tokens, read your billing, change your plan, delete data, or impersonate you in the dashboard. It can spend your credits launching scans (you can rate-limit + revoke), and it can read findings on scans the token itself launched. That's the blast radius.

On the scanner side, every PR scan runs in a fresh docker run --rm container that holds no long-lived secrets, sees only the cloned repo + a short-lived GitHub installation token for the clone, and is destroyed on exit. See Security & privacy for the full execution-isolation model.

Troubleshooting

Source

The Action's source is open at github.com/Pwnkemon/pwnkemon-scan — MIT licensed. ~250 lines of TypeScript. Most of what it does is in this page; the rest is bookkeeping. Security teams who require review-before-adoption can read the bundle that runs in their CI directly.