GuardAPI

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.

Example finding Illustrative fixture. Not a customer scan.

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. 1. Parse OpenAPI. Pair GET /collection with GET /collection/{id}. Nested paths that still have a parent param are skipped. Cap 40 targets.
  2. 2. As tenant A (TOKEN_A): list, harvest a real object id and unique markers.
  3. 3. As tenant B (TOKEN_B): GET that object.
  4. 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. 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.