Skip to content

Transparency · Open Trust Protocol

Our security & privacy posture, in the open.

Adaptensor City publishes a full security & privacy audit before onboarding our first paying municipal customer — and re-publishes it quarterly. We don’t hide behind a paid certification. We show our actual posture, including the parts still in progress.

V1 · 2026.1· last updated May 13, 2026 · auditor: Claude AI (Opus 4.7), supervised by Adaptensor, Inc.

20
PASS
of 24
2
PARTIAL
of 24
0
FAIL
of 24

Two controls scored N/A (no inventory module; reserved module-specific control). Detailed mapping below.

Why we publish this

We’re building a platform that small municipalities will run their public-facing operations on — reporting potholes, paying water bills, signing up for council updates. Trust is the product. The right way to earn it is to show our work.

This report follows the same framework AdaptBooks and our other modules publish under: 24 controls across six criteria (Security, Availability, Processing Integrity, Confidentiality, Privacy, and module-specific controls). Every finding — critical to cosmetic — is documented with the file path and the fix.

What we closed before V1

The first internal audit pass surfaced 24 findings, including three critical and five high-severity gaps. Sessions 16 through 19 closed all of them:

CRITICALField-level AES-256-GCM encryption module for sensitive secrets; tested round-trip + tampered-ciphertext rejection.
CRITICALPrivacy policy, terms of service, and cookie consent banner shipped on every page (marketing, admin, tenant).
CRITICALResident PII removed from platform notifications; only the town owner receives identifying information.
HIGHZod 4 schema validation on every JSON-body write route — 18 route files covered, public routes return generic errors to prevent enumeration.
HIGHWelcome emails now carry RFC 8058 one-click unsubscribe headers; tokens minted at signup, not lazily.
HIGHRight-to-erasure flows for both town owners (type-to-confirm + emailed token) and subscribers (single-link GDPR-Article-17 deletion).
HIGHAudit log made append-only at the database level via PL/pgSQL triggers; blocks UPDATE and DELETE against every role including the table owner.
HIGHDistributed rate limiting via Upstash Redis on all public endpoints; fail-open with logged warnings if unreachable.
MEDIUMContent-Security-Policy header shipping in report-only mode (will flip to enforcing once verified clean).
MEDIUMStructured logging via pino with path-based PII redaction; 18 named scopes for filterable production logs.
MEDIUMRole allow-list at the database level (owner / editor / viewer / water_operator / issue_handler) with helper for per-route enforcement.
MEDIUMClerk user.deleted webhook now revokes town admin access and marks orphaned towns automatically.
MEDIUMDaily 09:00 UTC data-disposal cron: subscriber hard-delete 30 days after unsubscribe; form submissions anonymized at 2 years.

Control scorecard

Each control is rated PASS, PARTIAL, FAIL, or N/A. PARTIAL means the control is substantially implemented with a documented gap. See the full report for evidence and file references on every line.

CriterionStatusNotes
1.1 Authentication & IdentityPASSClerk SSO across Adaptensor ecosystem
1.2 Authorization & Access ControlPASSuserOwnsTown + role allow-list
1.3 Network SecurityPASSFull headers; CSP in report-only
1.4 Vulnerability ManagementPARTIALManual npm audit; no automated scanning yet
1.5 Input ValidationPASSZod on every write route
1.6 EncryptionPASSTLS 1.3 + Neon AES-256 + field-encryption module
1.7 Logging & MonitoringPASSpino + PII redaction + immutable audit log
1.8 Change ManagementPASSGit + Drizzle migrations + Vercel auto-deploy
2.1 Infrastructure ResiliencePASSVercel + Neon serverless, all SOC 2
2.2 Backup & RecoveryPARTIALNeon PITR; manual export pending
2.3 Offline CapabilityPASSInstallable PWA per tenant
3.1 Financial AccuracyPASSInteger cents end-to-end; Zod amount caps
3.2 Inventory AccuracyN/ANo inventory module
3.3 Data ValidationPASSSame Zod coverage as 1.5
4.1 Data ClassificationPASSSensitive data identified and protected
4.2 Data MinimizationPASSPublic APIs return only resident-facing fields
4.3 Data DisposalPASSDaily retention cron + right-to-erase
5.1 Privacy Notice & ConsentPASSPrivacy + terms + cookie banner
5.2 Data Subject RightsPASSSelf-serve delete; Clerk user.deleted handled
5.3 Third-Party ProcessorsPASSDocumented in privacy policy
6.1 Tenant VerificationPASSManual approval gate
6.2 Resident PrivacyPASSRate-limited; minimized responses
6.3 Stripe Connect IsolationPASSPer-town accounts; $0 platform fee
6.4 Multi-Tenant IsolationPASStownId enforced on every query

What’s still open

The two PARTIAL ratings and four LOW findings below are documented here because they are real gaps — not paperwork issues. Each has a planned close date in our V2 quarterly report.

MEDIUM

Role allow-list not yet wired to per-route authorization

The five-role model exists at the database and helper level; the admin UI to assign non-owner roles is the next session’s work. Current behavior is unchanged (owner-only). Tracked for June 2026.

LOW

Audit-log retention is manual

Because audit log UPDATE/DELETE is blocked by database triggers, log trimming requires a documented admin procedure rather than the daily cron. We chose tamper resistance over automation. A privileged trim job is targeted for Q3 2026.

LOW

CSP still in report-only mode

One-week observation window in production with zero browser-console violations is required before flipping to enforcing. Targeted for May 2026.

LOW

No self-serve data export tooling

Right-to-portability is satisfied today by emailing support@adaptensor.com. A one-click export from the admin dashboard is targeted for Q3 2026.

Closed since publication: Upstash rate-limit provisioned and verified enforcing in production (May 13). GitHub Dependabot security alerts and weekly version-bump PRs enabled (May 13).

Who else touches your data

We share the minimum data needed with the sub-processors below. Every one of them is SOC 2 Type II certified. We do not run advertising, analytics, or behavioral tracking on the platform.

ProcessorPurposeData
ClerkAuthenticationEmail, name, session tokens
StripeSubscription billing + per-town water payment ConnectPayment metadata; cards are Stripe-hosted (we never see them)
NeonManaged PostgreSQLAll persisted application data, encrypted at rest
VercelApplication hosting + cronRequest/response data; per-tenant TLS
ResendTransactional + announcement emailRecipient address, message content
UpstashDistributed rate limitingHashed rate-limit keys (IP-derived); no PII

What we’re doing well

  • Append-only audit log. Database-level triggers block UPDATE and DELETE against every role, including the table owner. Tamper-evident by construction.
  • Email-loop town deletion. The owner must type the town name and click a one-time token sent to their on-file address. Defeats accidental clicks and forwarded-email attacks.
  • PII redaction in logs. Email, phone, token, and reporter fields are replaced with [REDACTED] before any log line leaves the server.
  • RFC 8058 one-click unsubscribe on every transactional welcome and broadcast email. Tokens are minted at signup, never reused, never lazy.
  • Per-tenant Stripe Connect.Town water payments flow directly to the town’s Connect account. The platform never custodies the funds and charges $0 application fee.
  • No behavioral tracking. Zero analytics, advertising, or cross-site tracking on either the marketing site or any resident-facing tenant site, by default.

Accessibility

Adaptensor City targets Web Content Accessibility Guidelines (WCAG) 2.1 Level AA, the legal bar set by the U.S. Department of Justice's 2024 final rule under Title II of the Americans with Disabilities Act. Small municipalities have until April 26, 2027 to meet this standard. We're published and verifiable today, well ahead.

Phases 1–3 + 5 complete as of May 13, 2026: zero critical or serious axe-core violations on every public route, contrast tokens audited and fixed at the token level, keyboard reorder added to the builder, skip link wired into every page. Phase 4 (manual screen-reader pass) is partial: marketing flow verified via Windows Narrator (skip link, heading order, landmarks, link labels); admin builder and resident submit flows verified by code review only and deferred to an external auditor or a future internal pass with a trained operator. The Playwright spec at tests/a11y.spec.ts is committed; we run npm run a11y before each deploy.

Email support@adaptensor.com to report a barrier. We respond within 5 business days and prioritize fixes ahead of other non-critical work. Full conformance statement, scope, and known limitations: ACCESSIBILITY.md.

Audit history

VersionDateScore
V1 (Initial)May 13, 202620 / 24 PASS · 0 FAIL
V2 (Quarterly, target)August 2026TBD
V3 (Quarterly, target)November 2026TBD

When something goes wrong, our response is documented and public: Incident response runbook.

Full report

Read the full V1 report with every fix verification, evidence pointer, and remediation plan: CITY_OTP_AUDIT_V1.md.

Found something we missed? Email support@adaptensor.com. We treat every report as in-scope for the bug-bounty intent of this program; we will credit you in the next quarterly audit unless you ask us not to.

See also the Privacy Policy and Terms of Service.