GitHub Action · v6 · 10 Sep 2026
Fail the PR when tenant B can read tenant A.
GuardAPI is a GET-only BOLA merge gate for multi-tenant APIs. It harvests a real object as user A, asks user B for the same object, and fails the GitHub job only if B’s 2xx body contains A’s id or unique markers.
Not an LLM OpenAPI grade. Not a public URL scanner. Not HSTS, CORS, or SSL probing.
bola / GuardAPI BOLA Gate
failed in 12s
GET /invoices/inv_a8f2 as TOKEN_B
HTTP 200
body contains id "inv_a8f2" owned by tenant A
verdict: fail
reason: proven cross-tenant leak {
"id": "inv_a8f2",
"tenant_id": "org_acme",
"amount_cents": 129900,
"memo": "Q3 retainer — Acme"
} Fail only if B’s 2xx body contains A’s id or unique markers. 401 / 403 / 404 without those fields pass. 200 without owner evidence is inconclusive and does not block merge.
What happens on the pull request
- 1. Parse OpenAPI. Pair
GET /collectionwithGET /collection/{id}. Nested paths that still have a parent param are skipped. Cap 40 targets. - 2. As tenant A (
TOKEN_A): list, harvest a real object id and unique markers. - 3. As tenant B (
TOKEN_B): GET that object. - 4. Verdict. Fail only on a proven leak. Deny without leaked fields = pass. 200 without owner evidence = inconclusive (does not block). Invalid tokens = error.
- 5. Evidence. Write SARIF. POST a redacted summary to GuardAPI. Tokens never leave GitHub Secrets.
Add four secrets and this step
- uses: GuardAPI/ghost-api@v6
with:
api-key: ${{ secrets.GUARD_API_KEY }}
openapi-path: ./openapi.json
base-url: ${{ secrets.STAGING_API_URL }}
token-a: ${{ secrets.TOKEN_USER_A }}
token-b: ${{ secrets.TOKEN_USER_B }} ghost-api is the historical GitHub repo name. The Action is GuardAPI v6.
Who this is for
Use it if
- You run a multi-tenant B2B SaaS with objects like
/invoices/{id} - You already have OpenAPI, HTTPS staging, and two test users
- You merge on GitHub pull requests
- You cannot buy Escape or Salt this year and you do not want another AI report
Skip it if
- You want a free homepage scanner
- You need GraphQL, BFLA, or MCP testing (not in v6)
- You want a full DAST or a SOC 2 certification (we are not certified)
- You will maintain your own authorization matrix — see OSS options
Trial
14 days, 1 repo, $0. Unlimited PR runs because compute is your GitHub minutes.
Team · $199/mo
3 repos. SARIF, fail on proven leak, dashboard evidence.
Scale · $499/mo
Unlimited repos, written evidence pack for access-control audits, priority onboarding. Not a SOC 2 Type II certification.
Questions
- Is this an AI scanner?
- No. v6 does not grade OpenAPI with a model. A finding is tenant B receiving tenant A’s object over the network.
- Does 200 always fail the PR?
- No. HTTP 200 without A’s id or unique markers is inconclusive and does not block merge. We would rather miss a leak than ship false red.
- Do my tokens leave GitHub?
- No. The engine runs on your runner. GuardAPI stores the verdict and redacted evidence only.
Longer walkthrough: How to fail a PR when tenant B can read tenant A.