Documentation
Everything you need to scan websites for GDPR, WCAG 2.2, security, and transparency compliance.
Getting Started
Quick scan (no install)
npx complytest scan https://your-site.com This downloads ComplyTest, launches a real browser, runs all 47 rules, and prints a compliance score with category breakdowns.
Install globally
npm install -g complytest First scan with HTML report
complytest scan https://your-site.com --format html,json -o reports This generates both an interactive HTML dashboard and a machine-readable JSON file in the reports/ directory.
CLI Commands
complytest scan <url>
Quick scan a single URL. The fastest way to check compliance.
| Option | Default | Description |
|---|---|---|
| -o, --output <dir> | reports | Output directory |
| --format <formats> | json | Report formats: html, json, csv, sarif |
| --timeout <ms> | 30000 | Page timeout in milliseconds |
| --viewport <preset> | desktop | Viewport: desktop (1366x900) or mobile (375x812) |
complytest run <config>
Full compliance audit from a configuration file. Supports baselines, SLOs, ownership routing, and evidence signing.
| Option | Description |
|---|---|
| -o, --output <dir> | Output directory (default: reports) |
| --format <formats> | Report formats: html, json, csv (default: html,json) |
| --baseline <file> | Apply baseline JSON of known issues |
| --write-baseline <file> | Write baseline from current failures |
| --quarantine <file> | Quarantine JSON for temporary ignores |
| --flaky-window <n> | Window of previous runs for flakiness checks |
| --slo <file> | SLO configuration for compliance guardrails |
| --owners <file> | Owner mapping for failure attribution |
| --jira | Enable Jira ticket creation for SLO breaches |
| --attest | Generate evidence manifest with attestation |
| --sigstore | Use cosign to sign/verify manifest |
| --jurisdictions <csv> | Comma-separated policy IDs (EU, US) |
complytest diff <runA> <runB>
Compare two audit runs to track regressions and improvements over time.
| Option | Description |
|---|---|
| -o, --output <file> | Output file for diff report |
| -d, --detailed | Show detailed diff with all changes |
complytest validate <config>
Validate a configuration file without running a scan. Checks JSON structure and required fields.
complytest digest
Generate a weekly compliance digest summarizing trends, top issues, and SLO breaches.
| Option | Description |
|---|---|
| --reports <dir> | Reports directory (default: reports) |
| --out <dir> | Output directory (default: reports) |
| --week <n> | Week offset: 0=current, 1=last week |
| --slack-webhook <url> | Slack webhook for posting digest |
complytest bulk-validate
Run bulk validation against multiple URLs with parallel browser instances.
| Option | Description |
|---|---|
| --urls <file> | Newline-delimited file of URLs to scan (required) |
| --concurrency <n> | Parallel browsers (default: 3) |
| --timeout <ms> | Per-URL timeout (default: 60000) |
| --output <dir> | Output directory (default: bulk-results) |
complytest verify-manifest <file>
Verify evidence manifest integrity and cryptographic signatures. Ensures audit trail has not been tampered with.
| Option | Description |
|---|---|
| --sign-secret <secret> | Secret for signature verification |
| --sigstore | Use cosign to verify bundle |
| --rekor <url> | Rekor transparency log URL |
Rules Reference
ComplyTest includes 47 built-in compliance rules. Each rule has an ID, category, severity level, rationale explaining why it matters, and a remediation hint.
Consent & Privacy (11 rules)
| Rule ID | Severity | Description |
|---|---|---|
| consent.reject_first_layer.present | critical | First-layer banner must offer equally prominent Accept and Reject |
| consent.cookies_before_consent | critical | No non-essential cookies before user consent |
| consent.third_party_cookies | critical | Third-party tracking cookies require explicit consent |
| consent.cookie_expiration | major | Non-essential cookies must not exceed 12-month expiration |
| consent.banner_language_clear | major | Consent banner text must use clear, plain language |
| consent.withdrawal_mechanism | major | Users must be able to withdraw consent easily (GDPR Art 7.3) |
| consent.cookie_descriptions | major | Cookie banner must provide clear descriptions of cookie purposes |
| consent.no_cookie_walls | critical | Sites must not make access conditional on accepting cookies |
| consent.visual_parity | major | Accept and Reject buttons must have equal visual prominence |
| consent.google_consent_mode | critical | Google Consent Mode v2 mandatory for Google services in EEA |
| consent.effectiveness | critical | After declining consent, no tracking requests should fire |
Accessibility (16 rules)
| Rule ID | Severity | Description |
|---|---|---|
| accessibility.focus_visible | major | Interactive elements must have visible focus indicator (WCAG 2.4.7) |
| accessibility.page_title | major | Each page must have a descriptive and unique title (WCAG 2.4.2) |
| accessibility.color_contrast | major | Text must have sufficient color contrast ratio (WCAG 1.4.3) |
| accessibility.alt_text | critical | All images must have alternative text (WCAG 1.1.1) |
| accessibility.form_labels | critical | Form inputs must have associated labels (WCAG 3.3.2) |
| accessibility.keyboard_navigation | major | All functionality must be keyboard accessible (WCAG 2.1.1) |
| accessibility.aria_valid | major | ARIA attributes must be used correctly (WCAG 4.1.2) |
| accessibility.skip_navigation | major | Pages should have skip navigation links (WCAG 2.4.1) |
| accessibility.heading_hierarchy | major | Headings must follow proper hierarchy (WCAG 1.3.1) |
| accessibility.responsive_text | major | Text must be resizable up to 200% without loss (WCAG 1.4.4) |
| accessibility.focus_not_obscured | major | Focused elements must not be hidden by sticky content (WCAG 2.4.11) |
| accessibility.target_size | major | Interactive targets must be at least 24x24px (WCAG 2.5.8) |
| accessibility.accessible_auth | major | Authentication must not rely on cognitive function tests (WCAG 3.3.8) |
| accessibility.consistent_help | major | Help mechanisms must appear in consistent location (WCAG 3.2.6) |
| accessibility.consent_banner_wcag | critical | Consent banners must be WCAG compliant: dialog role, focus trap, keyboard |
| accessibility.no_overlay_widgets | minor | Accessibility overlays are not valid compliance solutions |
Security (14 rules)
| Rule ID | Severity | Description |
|---|---|---|
| security.csp_present | major | Content Security Policy header should be present |
| security.x_frame_options | major | X-Frame-Options header protects against clickjacking |
| security.x_content_type_options | major | X-Content-Type-Options prevents MIME-sniffing attacks |
| security.hsts | critical | HSTS header ensures HTTPS-only connections |
| security.referrer_policy | major | Referrer-Policy header prevents information leakage |
| security.https_only | critical | Site must use HTTPS for all resources |
| security.secure_cookies | major | Cookies must have Secure flag on HTTPS sites |
| security.permissions_policy | minor | Permissions-Policy restricts browser features |
| security.csp_quality | major | CSP must be properly configured with sufficient directives |
| security.csp_no_unsafe_inline | major | CSP should not allow unsafe-inline in script-src |
| security.csp_no_unsafe_eval | major | CSP should not allow unsafe-eval for code injection prevention |
| security.coop | minor | Cross-Origin-Opener-Policy prevents cross-origin attacks |
| security.coep | minor | Cross-Origin-Embedder-Policy enables cross-origin isolation |
| security.sri | major | External scripts must use Subresource Integrity (PCI DSS 4.0) |
Transparency (6 rules)
| Rule ID | Severity | Description |
|---|---|---|
| transparency.ad_disclosure | minor | Advertising content should be clearly labeled |
| transparency.privacy_policy | critical | Site must have an accessible privacy policy (GDPR Art 13) |
| transparency.terms_of_service | major | Site should have terms of service (DSA Art 14) |
| transparency.data_controller | major | Privacy policy must identify the data controller (GDPR Art 13.1) |
| transparency.contact_info | major | Site must provide contact information (DSA Art 24) |
| transparency.complaint_mechanism | major | Platforms must provide complaint mechanisms (DSA Art 20) |
CI/CD Integration
ComplyTest exits with code 1 when rules fail, making it a natural fit for CI/CD pipelines. Add compliance checks to every pull request.
GitHub Actions
name: Compliance Check
on:
pull_request:
schedule:
- cron: '0 2 * * *' # Daily at 02:00 UTC
jobs:
compliance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm ci
- name: Run compliance scan
run: npx complytest scan https://staging.your-site.com \
--format html,json,sarif \
-o compliance-reports
- name: Upload SARIF to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: compliance-reports/scan-result.sarif
- name: Upload HTML report
if: always()
uses: actions/upload-artifact@v4
with:
name: compliance-report
path: compliance-reports/ SARIF integration
The SARIF output format integrates directly with GitHub's Security tab. Compliance violations appear as code scanning alerts alongside your regular security findings.
Exit codes
| Code | Meaning |
|---|---|
| 0 | All rules passed |
| 1 | One or more rules failed |
Enterprise Features
ComplyTest is the open-source scanner. For continuous monitoring with team routing, SLO enforcement, and legal-grade audit trails, see Complicer.
Automated daily scans
Continuous monitoring of production websites with trend tracking and regression detection.
Team routing
Auto-assign violations to Privacy, Accessibility, or Platform teams with Jira ticket creation.
SLO monitoring
Set compliance guardrails like "pre-consent cookies must not exceed 2" with breach alerts.
Cryptographic evidence
Sigstore signing creates tamper-proof audit trails that satisfy GDPR Article 30.