Catch ADA & EAA risk on every pull request.
The Action runs a full WCAG 2.2 AA audit inside your own runner — your app is built and rendered in a real browser, no public URL, no crawler, nothing leaves your CI. New violations get posted directly on the PR, with plain-English fixes telling you which file, line and attribute to change.
Six steps, four minutes.
Create an API key from the API keys page in your ScanAccess dashboard. Keys are prefixed sa_live_ (production) or sa_test_ (sandbox).
Store the key as SCAN_ACCESS_API_KEY in your repository's GitHub Secrets (Settings → Secrets and variables → Actions). Keys are shown once at creation.
Make sure your project has a build step (npm run build) that outputs a static bundle, and that npx serve can serve it on a local port.
Keep the rendering engine pinned to the version shown in the snippet — using another version triggers a runtime error.
Copy this workflow into .github/workflows/a11y.yml. Set your app routes under routes: (one per line). Adjust fail-on if needed (never|minor|moderate|serious|critical|any — default: critical).
Open a pull request. The Action runs, posts findings as a PR check, and uploads a SARIF file to the Security tab of your repository.
Copy-paste as is.
name: Accessibility audit
on:
pull_request:
permissions:
contents: read
pull-requests: write
security-events: write
jobs:
a11y:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npm ci
- run: npm run build
- run: npx serve -l 4173 ./dist &
- uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-chromium-1.60.0
- run: npx playwright@1.60.0 install --with-deps chromium
- uses: ghostdog-dev/scan-access-action@v2
id: a11y
with:
api-key: ${{ secrets.SCAN_ACCESS_API_KEY }}
app-url: http://localhost:4173
routes: |
/
/pricing
/about
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.a11y.outputs.sarif-file }}Important notes
Pin Playwright to 1.60.0
Do not change the Playwright version. The Action bundles a Chromium binary compiled for 1.60.0. Any mismatch causes an “Executable doesn't exist” error that will fail your workflow silently until the cache is cleared.
Self-host fonts and CSS
Playwright runs in a sandboxed runner. External CDN resources (Google Fonts, Tailwind CDN) may be blocked or timeout. Bundle or inline all assets in your build output before serving.
Required permissions
The workflow needs contents: read, pull-requests: write (to post the PR check), and security-events: write (to upload the SARIF file). Without these, the Action will fail with a 403 on the SARIF upload step.
Don't override the browser cache path
Setting PLAYWRIGHT_BROWSERS_PATH overrides the default cache location and breaks the cache/restore step. Use the cache path ~/.cache/ms-playwright as shown in the snippet.
Ship fast without shipping a lawsuit.
Shopify theme / Remix app
Block contrast and alt-text regressions before they reach merchants — and see which third-party app (Klaviyo, Yotpo, Privy) introduced each one.
Next.js / Astro / Vite SaaS
Runs on every preview deploy. Your app is built and rendered inside the runner — no public URL needed. Every route audited against WCAG 2.2 AA before merge.
Digital agency (multi-client)
One workflow per client repo, all keyed to one agency account. The Agency plan covers 1,000 CI scans/month across up to 50 monitored sites — white-label reports included.
Common setup questions.
How do I get an API key?
SCAN_ACCESS_API_KEY in your repo's GitHub Secrets. Keys use a sa_live_ prefix for production and sa_test_ for sandbox.Does it need a public URL or egress access?
Why does the rendering engine version have to match the snippet?
What are the scan limits?
Can it fail my build?
fail-on input accepts never | minor | moderate | serious | critical | any. Default is critical. Use never for advisory mode and act on findings in a downstream job via the action outputs.Why does my app show broken fonts or styles?
Is the result the same as a manual scan?
Does this make my site ADA or EAA compliant?
Ship accessible PRs — and prove it.
Create an API key and add the workflow. Scanner starts at $29/mo for 40 scans / month.