PrivacyScan User Manual
Website privacy, data-protection and security auditing for NDPA, GAID 2025 and GDPR.
1. Welcome & overview
PrivacyScan audits any public website for privacy, data-protection and security compliance in under a minute. It crawls sampled pages non-intrusively, evaluates cookie consent, privacy policy quality, HTTPS/TLS posture, security headers, third-party trackers, subject-rights surfaces and personally identifiable information (PII) exposure, then returns a scored dashboard with citations, evidence excerpts and remediation guidance.
Regulations covered
- Nigeria Data Protection Act 2023 (NDPA)
- Nigeria General Application and Implementation Directive 2025 (GAID)
- EU General Data Protection Regulation (GDPR)
- Advisory best-practice: WCAG 2.1 AA accessibility, HSTS preload eligibility, SPF / DMARC / CAA hardening.
Scan types
| Web scan | Live crawl of a URL. Respects robots.txt. Never bypasses authentication. |
| Static scan | Upload source code (single file or bundle text) for pattern-based checks — API keys, tokens, SDK misconfigurations. |
| Scheduled scan | Recurring web scan on a fixed cadence. Pro+ plans. |
| Regression suite | Admin-only run across a fixed corpus to track detector accuracy over time. |
2. Getting started
Create an account
- Open the landing page and click Start free — sign in.
- Choose Continue with Google, or enter an email + password (minimum 8 characters; the profile page enforces 12+ later).
- You are placed in a personal workspace automatically. You can create additional workspaces from the Workspace screen.
Enable two-factor authentication (recommended)
Open Profile → Two-factor authentication and choose Enable authenticator. Scan the QR code with Google Authenticator, 1Password or Authy, then enter the 6-digit code to activate. On future sign-ins, you will be prompted for the code after your password.
Choose your language
PrivacyScan ships with English, French and Spanish interface translations. Switch language under Profile → Language. Scan findings themselves are always emitted in English.
Workspace basics
A workspace groups scans, findings, teammates and billing. Every user has one default personal workspace. Owners can invite additional members and admins by email — see Section 12.
3. Running a scan
Start a web scan
- Navigate to /scan from the bottom nav.
- Paste a full URL (e.g. https://example.com). If you omit the scheme, https:// is added automatically.
- Press Scan. The engine resolves DNS, refuses private / loopback / link-local ranges, then begins the audit.
Live progress
The scan streams via Server-Sent Events (SSE). You will see live check names as they run, a rolling live Score Index, and a trend sparkline comparing against your last scan of the same hostname. If the stream stalls for more than 30 seconds, PrivacyScan automatically reconnects using full-jitter exponential backoff (2s → 30s, capped at 12 attempts).
Device profile
PrivacyScan detects the device you initiated the scan from (mobile, tablet or desktop) and mirrors that viewport + User-Agent server-side so the target site serves you the same layout a real user would receive. The device profile is stored with the scan and shown as a badge on the results screen.
Cancel or leave
Closing the tab does not abort the scan — results continue to accumulate server-side and appear under History when complete. Reopen /scan and it will resume streaming from the current position.
4. Reading the results
Score Index & grade
The Score Index is a 0–100 number with an accompanying letter grade A–F. It is computed from every check outcome using severity- and category-weighted deductions, with a serious-fail penalty of 2 points per category that contains a high or critical failure, capped at 8 points total; a warn credit of 80%; a gentle 18% curve lift to reward broad partial coverage; and a score floor of 20. Realistic well-maintained sites typically land between 70 and 95.
| A (90–100) | Excellent. Strong compliance posture across categories. |
| B (80–89) | Good. Minor gaps or advisory items only. |
| C (70–79) | Acceptable. Address highest-severity fails first. |
| D (55–69) | At risk. Multiple category failures. |
| F (< 55) | Failing. Immediate remediation required. |
Status codes
| Pass | Check verified compliant on evidence collected. |
| Warn | Partial credit — implementation present but weak, or advisory best-practice missed. |
| Fail | Non-compliant. Deduction applied per severity. |
| NV | Not verifiable via public scan — requires source or runtime access. |
Evidence
Every finding shows the exact affected URL and an evidence snippet — the raw HTML, header value, cookie name, DOM excerpt or policy text that triggered the result. Click a finding row to expand full evidence, remediation copy and regulator citations.
5. Scan checks reference
PrivacyScan runs more than 70 distinct checks across 12 categories. The full, searchable reference — including what passes, warns, or fails for every check — is published at /checks. The table below summarises the categories and how each contributes to the Score Index.
Categories & weights
| Transport / TLS (1.3×) | HTTPS, certificate, HSTS, mixed content, form security, SPF, DMARC, CAA, HSTS preload. |
| Security headers (1.2×) | CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, COOP, server disclosure. |
| Cookies (1.1×) | Inventory, security flags, third-party scoping, retention. |
| Third-party trackers (1.1×) | Known analytics/ad/session-replay/social SDKs and pre-consent loading. |
| Consent (1.5×) | Banner/CMP presence, reject-all parity, granular toggles, no pre-checked boxes, Consent Mode v2. |
| Policies (1.2×) | Privacy policy link, DPO contact, cookie policy content, policy freshness, required disclosures. |
| Data-subject rights (1.0×) | DSAR / delete-my-data surfaces and linkage to consent preferences. |
| PII exposure (1.5×) | Exposed API keys, tokens, JWTs, private keys, emails. |
| Accessibility (1.1×) | WCAG 2.1 AA sample: lang, title, alt text, form labels, headings, landmarks, zoom, skip links. |
| ADA Title III (1.0×) | Accessibility statement, feedback channel, captions, tabindex, aria-hidden, autoplay. |
| Consent Mode v2 (1.0×) | Google gtag default/update calls, ad_user_data, ad_personalization, ads_data_redaction. |
| Static analysis (0.7×) | Hardcoded secrets, insecure storage, disabled pinning, verbose logging, vulnerable dependencies — requires source/APK upload. |
Scoring formula
- Each check has a severity weight: info=1, low=3, medium=8, high=15, critical=25.
- Pass earns full weight; warn earns 80%; fail earns 0%; not-verifiable (NV) is ignored.
- Category score = earned weight / max weight within the category.
- Overall raw base = weighted average of category scores using the weights above.
- Base is lifted by 18% toward 100 without changing the 0 or 100 endpoints.
- A 2-point penalty is applied per category with a high or critical fail, capped at 8 points.
- Final score is rounded and clamped to a minimum of 20 and maximum of 100.
6. Findings deep dive
Categories
| Consent | CMP presence, reject-all parity, no pre-checked boxes, no non-essential cookies before consent, Google Consent Mode v2 signals. |
| Cookies | Full inventory with names, domains, expiry, HttpOnly / Secure / SameSite flags, purposes disclosed in the cookie policy. |
| DPO / Privacy policy | Contact details, lawful basis, retention, subject rights, transfers, complaint mechanism. |
| PII exposure | Emails, phone numbers, API keys, tokens, JWTs, private-key material found in HTML / JS bundles. |
| Security headers | HSTS, CSP, X-Frame-Options, Referrer-Policy, Permissions-Policy, X-Content-Type-Options. |
| TLS | Protocol version, cipher suite quality, certificate validity, mixed content. |
| Trackers | 24-vendor signature set — analytics, ads, fingerprinting, session replay. |
| Rights | DSAR / subject-request surface: opt-out form, contact email, self-service portal. |
| Accessibility | WCAG 2.1 AA sample: contrast, alt text, form labels, landmark structure. |
| Infrastructure | SPF, DMARC, CAA, HSTS preload eligibility, security.txt. |
Severity model
- High — regulator-cited requirement. Missing a DPO contact, no cookie banner, transmitted PII in cleartext.
- Medium — significant risk or partial compliance. Weak reject-all UX, missing subject-rights surface.
- Low — advisory best-practice. HSTS preload not eligible, missing security.txt.
Ignore / accept-risk
From any finding row, choose Ignore → provide a justification (min 12 characters). Ignored findings still appear but are excluded from Score Index recomputation and are visible to teammates for audit. Un-ignore from the same menu.
Assign remediation
Click Assign on a finding and pick a workspace member. They receive a notification and see the item on their Assigned to me screen. Assignments are re-evaluated on the next scan — if the underlying check flips to pass, the assignment auto-closes.
7. DPO & privacy policy checks
PrivacyScan fetches every candidate privacy / cookie policy page linked from the target and looks for the specific disclosures required by NDPA §35, GAID Article 27 and GDPR Articles 13–14.
What is inspected
- Data Protection Officer name, email or contact form URL.
- Lawful basis statement for each processing purpose.
- Retention periods (specific durations, not just 'as long as necessary').
- Data subject rights list with a working request mechanism.
- International transfer disclosures (recipients, countries, safeguards).
- Regulator complaint mechanism (NDPC / relevant DPA contact).
9. PII detection & filters
PrivacyScan scans every sampled response body for personal or sensitive tokens using a curated pattern set (emails, phone numbers, Nigerian NIN / BVN, US SSN, AWS / Google / Stripe API keys, JWTs, RSA and EC private keys, .env leaks).
False-positive filters
Common placeholders (example.com emails, all-nines phone numbers, xxxxx.xxxxx.xxxxx JWTs) are excluded by default. You can add or override filter patterns per workspace under /pii-filters.
- Type — email, phone, apikey, jwt, generic.
- Pattern — literal string or JavaScript regex (validated on save).
- Note — reason for the exclusion, shown in audit logs.
10. Static source scan
The Static screen (/static) accepts up to 500 KB of source per submission — a single file, a concatenated bundle, or an .env-style dump. It runs a curated pattern set for hard-coded secrets, misconfigured SDK calls, insecure storage APIs and known vulnerable library versions.
Supported checks
- Secret exposure: AWS keys, Stripe keys, Google service accounts, GitHub tokens, JWT secrets, database URIs.
- Insecure storage: localStorage / SharedPreferences with sensitive keys, plaintext credential caching.
- SDK misuse: Firebase debug flags in production, verbose logging shipped, disabled certificate pinning.
- Dependency signals: known-vulnerable version strings for popular libs.
11. History, search & tags
Every completed scan appears under /history. Use the search box to filter by hostname substring, tag, score band or scan type.
Tags
Add free-text tags to any scan from its detail page (e.g. 'client-abc', 'q3-audit'). Tags are private to your workspace.
Diff view
Open any scan and click Compare to previous. PrivacyScan shows: score delta, findings that flipped pass↔fail, new findings, resolved findings, and evidence changes. Diff URLs are shareable within the workspace.
13. Teams & workspaces
Roles
| Owner | Full control including billing, workspace deletion, member removal. |
| Admin | Invite / remove members, manage schedules, PII filters, regression suite. |
| Member | Run scans, view all findings, comment, assign. |
| Viewer | Read-only. Cannot run scans or modify findings. |
Invites
From /workspace, click Invite. Enter an email, choose a role, optionally include a message. PrivacyScan sends an invite email via Resend containing a single-use link valid for 7 days. Every invite (created, sent, accepted, revoked) is recorded to the audit trail under Workspace → Invite activity.
14. Collaboration
Threaded comments
Every finding has its own comment thread. @mention a teammate to notify them. Threads carry across scans of the same hostname when the same check ID recurs.
Assignments
Owners and admins can assign any fail- or warn-grade finding to a teammate. Assignments include a due date, optional note, and link back to the finding; they appear on the assignee's /assignments screen.
15. Scheduled scans
Pro+ plans can schedule a hostname to be re-scanned automatically. Choose a cadence: daily, weekly or monthly. Runs happen from a pg_cron job and consume monthly scan quota just like manual runs.
Regression alerts
When a scheduled scan drops the Score Index by 10+ points, or any check flips pass → fail, workspace admins receive an in-app notification linking directly to the offending scan.
16. Regression suite (admin)
The /regression screen (admin-only) runs a curated corpus of public sites to track detector accuracy over time. It records per-site score deltas, finding digests and pass→fail flips per run.
Managing the corpus
- Add or disable sites from the corpus table.
- Trigger a run — sites are scanned serially, max 8 per run to protect targets.
- Review history: per-site trend chart, delta scores, flipped checks.
The same threshold (10-point drop or any pass→fail flip) triggers admin notifications during a regression run.
17. Reporting & exports
PDF report
From any scan, click Export → PDF. The report contains: cover page with hostname / score / grade / signature, executive summary, full findings table grouped by category, evidence excerpts and remediation. Signed with the scan hash for later verification.
CSV export
Export → CSV emits one row per finding with check ID, status, severity, category, regulation citation, affected URL and evidence summary. Suitable for import into GRC tools.
Regulator-mapped filters
Filter the findings table by NDPA, GAID or GDPR to produce a framework-specific view before exporting.
High-resolution dashboard PNG
Export → PNG produces a 4320×5400 image of the scan detail view suitable for slides or printed reports.
18. Billing & plans
| Free | 3 scans / month, 1 workspace, no scheduling, single user. |
| Pro — ₦3,000/mo | 50 scans / month, scheduled scans, PDF/CSV export, single user. |
| Team — ₦12,000/mo | 250 scans / month, up to 10 seats, full collaboration, PII filters. |
| Business — ₦47,000/mo | Unlimited scans, unlimited seats, API access, regression suite, priority support. |
Billing is handled by Paddle. Manage subscription, invoices and cards from /billing. Downgrading takes effect at the end of the current billing period.
Quota semantics
Scan quota resets on the 1st of each calendar month at 00:00 UTC. Failed scans do not consume quota; cancelled scans do.
19. Account & security
Profile
- Display name — shown on comments, assignments and audit logs.
- Email address — must be reconfirmed if changed.
- Password change — enforced strength meter (12+ chars, mixed case, digits, symbols; blocks common passwords and email-derived strings).
MFA (TOTP)
See Section 2. Removing your factor requires the current password. Losing access to your authenticator means contacting support with proof of account ownership.
Account deletion
Profile → Delete account. Type DELETE to confirm. Removes your user record, all owned scans, findings, workspaces where you are the sole owner, and comments authored by you. Cannot be undone.
Data retention
Scans and findings are retained indefinitely while the account is active. Share-link view logs are purged after 90 days. Backups are encrypted at rest.
20. API & webhooks (Business)
Public endpoints
| GET /api/public/badge/{token}.svg | Live SVG badge with current score & grade. |
| GET /api/public/verify/{scanId} | Machine-readable verification of the report signature. |
| POST /api/public/csp-report | CSP report ingestion endpoint (attach as report-uri on your site). |
| POST /api/public/hooks/run-scheduled-scans | Cron trigger for scheduled scans (called by pg_cron). |
21. Privacy & compliance of PrivacyScan itself
- SSRF guard — every scan target is DNS-resolved server-side and rejected if it lands on a private, loopback or link-local range. Redirects are re-validated.
- Respects robots.txt — Disallow rules are honoured; a partial scan is preferred over an unauthorised one.
- No authentication bypass — PrivacyScan never submits credentials, cookies you did not provide, or bypasses login walls.
- Private history — scan history is scoped to your workspace via Row-Level Security. Public share links are opt-in per scan with TTL and revocation.
- Signed reports — every completed scan carries an HMAC-SHA256 signature verifiable at /verify.
22. Troubleshooting & FAQ
The SSE stream stalled
PrivacyScan reconnects automatically after a 30-second silence, up to 12 attempts with exponential backoff. If the scan never completes, reload /history — most scans finish server-side even without an open connection.
A scan failed with 'Invalid URL'
Check that the URL parses. Bare hostnames without a scheme are prefixed with https:// automatically. IP addresses in private ranges are blocked by design.
Invite email did not arrive
Ask the recipient to check spam. From /workspace → Invite activity, verify the invite was sent and copy the raw link. Invites are single-use and expire after 7 days.
I lost my authenticator
Contact support@privacyscan with proof of account ownership (billing email + a signed report you generated). Recovery is manual and can take up to 48 hours.
Share link says 'expired' or 'revoked'
Regenerate a fresh link with a longer TTL from the source scan's Share dialog.
Score dropped after a small change
Open the Compare view against the previous scan. The diff highlights exactly which checks flipped and why — usually a header removed, a cookie added before consent, or a policy page edited.
23. Glossary
| Score Index | 0–100 weighted compliance score. See Section 5 for the full formula and every check that contributes to it. |
| Grade | A–F letter grade derived from the Score Index. |
| NV | Not verifiable — a check that cannot be answered from public scanning alone. |
| CMP | Consent Management Platform — the cookie banner + preference store. |
| DSAR | Data Subject Access Request — a user asking to see / delete / port their data. |
| DPO | Data Protection Officer — statutory contact for privacy matters. |
| HSTS | HTTP Strict Transport Security header enforcing HTTPS. |
| HSTS preload | Baked-in browser list of HSTS-enforced hosts. Eligibility has strict criteria. |
| SPF / DMARC | DNS records that authenticate outbound email and prevent spoofing. |
| CAA | DNS record restricting which CAs may issue certificates for the domain. |
| Consent Mode v2 | Google's signalling protocol for pre/post-consent tag behaviour. |
| RLS | Row-Level Security — Postgres policies that enforce per-row access. |
24. Support & feedback
Email support@privacyscan for account issues, bug reports and detector feedback. Feature requests are logged in the public changelog at /changelog. When reporting an issue, include your scan ID (or the report signature) so we can reproduce the exact evidence you saw.