Penetrify GitHub Action
AI-driven autonomous penetration testing in your CI/CD pipeline. Scan your application for real-world vulnerabilities and report findings directly in GitHub's Security tab — in minutes, not days.
Penetrify covers SQL injection, XSS, authentication flaws, broken access control, API security issues, and more. No agents to install. No configuration files required to get started.
Quick start
Add this step to any GitHub Actions workflow. Results appear in Security → Code scanning within minutes.
Minimal setup
Two inputs required: your API key and target URL.
# .github/workflows/security.yml - name: Run Penetrify Scan uses: penetrify/penetrify-action@v1 with: api-key: ${{ secrets.PENETRIFY_API_KEY }} target: 'https://staging.your-app.com'
- Sign up at app.penetrify.cloud and create an API key under Settings → API Keys.
- Add the key as a GitHub Secret: Settings → Secrets and variables → Actions → New secret. Name it
PENETRIFY_API_KEY. - Add the workflow step above to your pipeline.
- Push — findings appear in your repository's Security → Code scanning tab.
The action requires permissions: security-events: write on your job to upload SARIF results to GitHub. See the full example below.
How it works
The action integrates Penetrify's AI scanning engine into your workflow in four steps:
- Triggers a scan against your target URL via the Penetrify API using your API key.
- Polls for results until the scan completes or the configured
timeoutis reached. - Generates a SARIF report from the findings and uploads it to GitHub Code Scanning.
- Fails the build if any finding meets or exceeds your configured
severity-threshold.
Scans run entirely on Penetrify's infrastructure — your workflow runner only needs outbound HTTPS access to the Penetrify API. Nothing is installed on your application's servers.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
| api-key | ✅ Yes | — | Your Penetrify API key. Always store as a GitHub Secret — never hardcode. |
| target | ✅ Yes | — | Full URL of the application to scan. Must be reachable from Penetrify's scanners. |
| scan-type | ❌ No | full | Scan depth: full, quick, api, or web. Use quick on PRs for faster feedback. |
| severity-threshold | ❌ No | high | Fail the build when a finding at this severity or above is detected. Options: critical, high, medium, low. |
| wait-for-results | ❌ No | true | Wait for scan completion. Set to false for fire-and-forget — the action exits immediately after triggering the scan. |
| timeout | ❌ No | 1800 | Maximum seconds to wait for scan completion. Scans exceeding this are marked timeout. |
| upload-sarif | ❌ No | true | Upload SARIF results to GitHub Code Scanning. Requires security-events: write permission. |
| config-file | ❌ No | — | Path to a Penetrify JSON config file in your repository for advanced scan configuration. |
Outputs
Access outputs in subsequent steps via ${{ steps.<step-id>.outputs.<name> }}.
completed, failed, or timeout.- name: Run Penetrify Scan id: penetrify uses: penetrify/penetrify-action@v1 with: api-key: ${{ secrets.PENETRIFY_API_KEY }} target: 'https://staging.myapp.com' - name: Post scan summary run: | echo "Scan ID: ${{ steps.penetrify.outputs.scan-id }}" echo "Findings: ${{ steps.penetrify.outputs.findings-count }}" echo "Critical: ${{ steps.penetrify.outputs.critical-count }}" echo "Report: ${{ steps.penetrify.outputs.report-url }}"
Severity levels
The severity-threshold input controls when the action fails the build. Setting it to a level will fail on that level and above.
| Level | Fails build when… | Recommended for |
|---|---|---|
| critical | Only critical findings present | PR checks — keep the bar high to avoid blocking merges |
| high | High or critical findings present | Default — good balance for production deploys |
| medium | Medium, high, or critical findings present | Scheduled audits or compliance-sensitive applications |
| low | Any finding present | Maximum strictness — use with care |
Examples
Full scan triggered on every push to the main branch. Fails the build if high or critical vulnerabilities are found.
name: Security Scan on: push: branches: [main] jobs: scan: runs-on: ubuntu-latest permissions: security-events: write contents: read steps: - uses: actions/checkout@v4 - uses: penetrify/penetrify-action@v1 with: api-key: ${{ secrets.PENETRIFY_API_KEY }} target: 'https://staging.myapp.com' severity-threshold: 'high'
A lighter quick scan runs on every PR targeting main. Only fails on critical findings so development isn't unnecessarily blocked.
name: PR Security Check on: pull_request: branches: [main] jobs: quick-scan: runs-on: ubuntu-latest permissions: security-events: write contents: read steps: - uses: actions/checkout@v4 - uses: penetrify/penetrify-action@v1 with: api-key: ${{ secrets.PENETRIFY_API_KEY }} target: 'https://preview-${{ github.event.pull_request.number }}.myapp.com' scan-type: 'quick' severity-threshold: 'critical'
A full scan runs every Monday at 06:00 UTC against production. Extends the timeout to 60 minutes for deep scanning.
name: Weekly Security Audit on: schedule: - cron: '0 6 * * 1' jobs: audit: runs-on: ubuntu-latest permissions: security-events: write contents: read steps: - uses: actions/checkout@v4 - uses: penetrify/penetrify-action@v1 with: api-key: ${{ secrets.PENETRIFY_API_KEY }} target: 'https://app.mycompany.com' scan-type: 'full' severity-threshold: 'medium' timeout: '3600'
Triggers a scan without waiting for results. Useful in deployment pipelines where you don't want to block on scan time but still want a scan to run.
- uses: penetrify/penetrify-action@v1 with: api-key: ${{ secrets.PENETRIFY_API_KEY }} target: 'https://staging.myapp.com' wait-for-results: false
In fire-and-forget mode, upload-sarif is automatically disabled and the build will not fail on findings. Check your Penetrify dashboard for results.
GitHub Security integration
When upload-sarif is enabled (default), findings are uploaded in SARIF format and appear natively throughout GitHub:
| Feature | What you get |
|---|---|
| Security → Code scanning alerts | Browse, filter, and manage all findings. Dismiss false positives, add notes, track fix status. |
| Pull request annotations | New vulnerabilities introduced by a PR appear inline in the files changed view. |
| PR check status | The PR status check reflects the build pass/fail based on your severity-threshold. |
| Alert management | Assign findings to team members, link to issues, and track resolution over time. |
Required permission: Your workflow job must declare permissions: security-events: write for SARIF upload to succeed. Without it, the upload step will fail with a 403 error.
API key setup
- Sign up or log in at app.penetrify.cloud.
- Navigate to Settings → API Keys and create a new key. Give it a descriptive name like github-actions.
- Copy the key immediately — it won't be shown again.
- In your GitHub repository, go to Settings → Secrets and variables → Actions → New repository secret.
- Name the secret
PENETRIFY_API_KEYand paste your key as the value.
For organization-wide usage, add the secret at the organization level and share it across repositories via Settings → Secrets → Actions at the org level.
Troubleshooting
SARIF upload fails with 403
Add permissions: security-events: write to your job definition. See the basic example.
Scan times out
Increase the timeout input (default: 1800 seconds). For large applications with many endpoints, full scans can take 30–60 minutes. Alternatively, use scan-type: quick for faster results.
Target is not reachable
Penetrify's scanners connect to your target over the public internet. Ensure your staging environment is publicly accessible during the scan, or use a tunnel/VPN if your environment is private. IP allowlisting for Penetrify's scanner IPs is available on the Enterprise plan.
Build fails on false positives
Dismiss findings in the GitHub Security tab — dismissed findings do not count toward the threshold on subsequent scans. You can also raise the severity-threshold or use a config-file to exclude specific paths or checks.
Invalid API key error
Verify the secret name matches exactly: PENETRIFY_API_KEY. Check the key is still active in Settings → API Keys on penetrify.cloud. Keys can be rotated from the dashboard at any time.
Still stuck?
Open an issue on GitHub or email support@penetrify.cloud.