SECURITY
Security Overview
Security Overview
Version: 1.0
Last updated: April 2026
Contact: security@gatewaychecker.co.uk
Summary
Gatewaychecker is a UK-based SaaS platform purpose-built for processing commercially sensitive building safety documentation under BSA Gateway 2. All primary customer data — projects, submissions, findings, and user accounts — is stored and processed entirely within the European Union. Authentication is passwordless by design; every query to the database is scoped to the authenticated organisation through row-level security policies enforced at the PostgreSQL layer. Document text submitted for AI analysis is transmitted transiently to Anthropic's API and is neither retained nor used for model training under Anthropic's enterprise API commitment.
Hosting and Infrastructure
| Component | Provider | Region | Compliance |
|---|---|---|---|
| Application hosting | Vercel | EU (Frankfurt, iad1) | SOC 2, ISO 27001 |
| Database (PostgreSQL) | Supabase | AWS eu-west-1 (Ireland) | SOC 2 Type II, ISO 27001 |
| Object storage | Supabase Storage | AWS eu-west-1 (Ireland) | SOC 2 Type II |
| Vector search (pgVector) | Supabase | AWS eu-west-1 (Ireland) | SOC 2 Type II |
| Authentication | Supabase Auth | AWS eu-west-1 (Ireland) | SOC 2 Type II |
| Background processing | Supabase Edge Functions | AWS eu-west-1 (Ireland) | SOC 2 Type II |
| AI model routing | OpenRouter | US (transit only; no storage) | DPA in place |
| AI inference | Anthropic Claude Sonnet | US (API; no-training commitment) | No-training API terms |
| Payment processing | Stripe | EU + US | PCI-DSS Level 1 |
| Transactional email | Resend | EU | GDPR-compliant |
| Optional: Microsoft 365 integration | Microsoft Graph API | EU | Microsoft DPA |
All primary customer data is processed within the EU. API calls to Anthropic transmit document text transiently for AI inference; Anthropic does not retain or use submitted data for model training under its API terms of service. OpenRouter acts solely as a routing layer and retains no customer data.
Encryption
At rest
All data stored in Supabase (PostgreSQL and Supabase Storage) is encrypted at rest using AES-256, managed by AWS Key Management Service (KMS) operating within the eu-west-1 region.
Additional application-layer encryption is applied to sensitive credentials:
- OAuth refresh tokens (Microsoft 365 integration): encrypted with AES-256-GCM using a random 12-byte initialisation vector per token. Stored as
iv:ciphertext:authTaghexadecimal. The encryption key is held in Vercel environment variables and never written to the database. - Customer API keys: bcrypt-hashed at work factor 10 before database storage. The raw key is presented once at creation and cannot be retrieved thereafter.
In transit
All client–server traffic is encrypted with TLS 1.2 or higher. Vercel enforces HTTPS on all routes and automatically redirects plain HTTP. All internal service-to-service calls (application server → Supabase, application server → OpenRouter/Anthropic) use HTTPS with certificate validation enforced.
Key management
| Key type | Storage location | Rotation |
|---|---|---|
| AWS infrastructure keys | AWS KMS (eu-west-1) | Managed by AWS |
| Application secrets (JWT secret, API salt) | Vercel environment variables | Manual; rotated on staff change or incident |
| OAuth token encryption key | Vercel environment variables | Rotated annually or on breach |
| Supabase service role key | Vercel environment variables (server-side only) | Rotated on staff change |
| Customer API keys | bcrypt hash in database | Customer-initiated; immediately revocable |
Authentication and Access Control
User authentication
Gatewaychecker uses email magic link authentication via Supabase Auth. Users receive a one-time sign-in URL via email; there is no password database. This design eliminates credential stuffing, password reuse, and password-database breach risk as attack vectors.
Sessions are issued as short-lived JWTs signed by Supabase Auth. Tokens are rotated on use and invalidated immediately on sign-out.
Multi-factor authentication
TOTP-based MFA (authenticator app) is available to all users via Supabase Auth. Mandatory MFA enforcement for Enterprise tier accounts is planned for Q3 2026.
API key authentication
Customers on Professional and Enterprise plans may create API keys for programmatic integration. Each key:
- Uses the prefix
gcw_live_followed by 64 cryptographically random hexadecimal characters. - Is generated using Node.js
crypto.randomBytes(CSPRNG). - Is bcrypt-hashed at work factor 10 before being written to the database.
- Carries explicit permission scopes set at creation time:
submit(document submission),read_findings(findings retrieval). - Is immediately revocable from the Settings panel.
- Is displayed in plaintext once at creation and cannot be retrieved thereafter.
Role-based access control
Within each organisation, users hold one of three roles:
| Role | Permissions |
|---|---|
| Owner | Full access: billing, team management, API keys, all submission data |
| Admin | Team management, API key creation, all submission data |
| Member | Read/write access to submission data; no billing or team management |
Data Isolation
Gatewaychecker operates as a multi-tenant SaaS. Every database record carries an organisation_id foreign key. Row-Level Security (RLS) is enabled on all 11 database tables with both SELECT and write (INSERT/UPDATE/DELETE) policies.
RLS is implemented via a PostgreSQL STABLE SECURITY DEFINER function public.user_org_ids() which returns the set of organisation IDs associated with the authenticated user's JWT. All policies verify that the target record's organisation_id is within this set before permitting access.
The Supabase service-role key — which bypasses RLS — is used exclusively in server-side Next.js route handlers and Supabase Edge Functions. It is never included in client-side JavaScript bundles or exposed to the browser.
Defence-in-depth: even if an application bug bypassed the API layer, RLS at the database layer prevents cross-organisation data access.
Document Handling
Upload and extraction
Documents (PDF format) are uploaded over HTTPS to the Gatewaychecker application server. Text is extracted server-side using pdfjs-dist and unpdf in a Node.js environment. Extracted text is stored in the documents table in Supabase PostgreSQL, scoped to the submitting organisation. ZIP archives containing multiple PDFs are also accepted; each document is classified by type before analysis.
AI processing
Extracted document text is transmitted to the Anthropic Claude Sonnet API via OpenRouter for analysis against the BSA Gateway 2 criteria ontology. This processing is:
- Transient: document text is not cached, logged, or persisted by OpenRouter or Anthropic after the API response is returned.
- Non-training: Anthropic's API terms of service explicitly prohibit using API-submitted data to train or improve Anthropic models. This applies to all document content submitted via Gatewaychecker.
- Purpose-limited: document content is used solely to evaluate submissions against the Gateway 2 criteria ontology. It is not used for any other purpose.
Analysis runs within a Supabase Edge Function, ensuring the processing pipeline is isolated from the web-facing application server.
Retention
| Data type | Retention period |
|---|---|
| Extracted document text | Duration of account; deleted within 30 days of account closure |
| Findings, risk scores, evidence | Duration of account; deleted within 30 days of account closure |
| Human override notes | Duration of account |
| Usage events and audit logs | 24 months |
| Billing and transaction records | 7 years (UK VAT and accounting obligations) |
Network Security
| Control | Implementation |
|---|---|
| HTTPS enforcement | Vercel enforces HTTPS on all routes; HTTP permanently redirected (308) |
| Security headers | X-Frame-Options: DENY; X-Content-Type-Options: nosniff; Referrer-Policy: strict-origin-when-cross-origin; Permissions-Policy restricts camera, microphone, geolocation |
| Rate limiting | Analysis endpoint capped at 10 requests per user per hour, enforced at application layer via usage_events |
| Input sanitisation | All user-submitted strings stripped of HTML and script injection patterns; maximum field lengths enforced server-side on every route |
| API authentication | All application API routes require a valid Supabase JWT or API key; unauthenticated requests return 401 before any data is accessed |
| SQL injection prevention | All database queries use the Supabase client SDK with parameterised queries; no raw SQL string interpolation |
| CORS | Cross-origin requests restricted to gatewaychecker.co.uk and trust.gatewaychecker.co.uk |
Vulnerability Management
| Practice | Detail |
|---|---|
| Dependency scanning | GitHub Dependabot monitors all npm dependencies for known CVEs; security alerts are raised automatically |
| Manual audit | npm audit is run as part of the pre-deployment checklist on every release |
| Critical CVE patch SLA | 7 days from public disclosure |
| High CVE patch SLA | 30 days from public disclosure |
| Medium/low CVE | Assessed individually; addressed in the next scheduled release |
| Secret scanning | GitHub secret scanning is enabled; commits containing detectable API keys or credentials are blocked |
| Dependency pinning | Production dependencies are pinned to minor version ranges; lockfile (package-lock.json) is committed and verified on CI |
To report a suspected vulnerability: security@gatewaychecker.co.uk
Responsible disclosure is welcomed. We aim to acknowledge reports within 2 business days.
Backup and Recovery
Supabase (Pro plan) provides:
- Continuous WAL archiving: point-in-time recovery to any moment within the retention window.
- Daily automated snapshots: retained for 7 days.
| Metric | Target |
|---|---|
| Recovery Point Objective (RPO) | < 1 hour |
| Recovery Time Objective (RTO) | < 4 hours |
| Backup retention window | 7 days |
| Backup location | AWS eu-west-1 (Ireland) — same region as primary |
| Backup encryption | AES-256 via AWS KMS |
Backup restoration procedures are tested on a quarterly basis. Results are documented internally.
Incident Response
In the event of a security incident affecting customer data, Gatewaychecker will:
- Detect and triage within 4 hours of internal identification.
- Contain affected systems and assess the scope of impact.
- Notify affected customers within 72 hours of becoming aware of a personal data breach, as required by UK GDPR Article 33 and NCSC guidance.
- Notify the Information Commissioner's Office (ICO) where the breach is likely to result in a risk to the rights and freedoms of individuals.
- Issue a post-incident report detailing root cause, timeline, impact, and remediation actions, provided to affected customers within 14 days.
Security incidents should be reported to: security@gatewaychecker.co.uk
Certifications and Compliance Status
| Certification / Standard | Status | Target date |
|---|---|---|
| UK GDPR compliance | ✓ Implemented | In effect |
| PCI-DSS (card data) | ✓ Delegated to Stripe (Level 1) | In effect |
| Cyber Essentials | In progress | Q3 2026 |
| Cyber Essentials Plus | In progress | Q4 2026 |
| SOC 2 Type I | Planned | Q1 2027 |
| SOC 2 Type II | Planned | Q3 2027 |
| ISO 27001 | Planned | Q2 2027 |
| ISO 42001 (AI management systems) | Planned | Q4 2027 |
Contact
| Enquiry type | Contact |
|---|---|
| Security issues and vulnerability disclosures | security@gatewaychecker.co.uk |
| Privacy and data subject rights requests | privacy@gatewaychecker.co.uk |
| Legal and DPA enquiries | legal@gatewaychecker.co.uk |
| General and enterprise enquiries | hello@gatewaychecker.co.uk |
Questions about this document?
Contact security@gatewaychecker.co.uk