A review-grade scoreboard of what is shipped in this repo against ISO/IEC 27001, ISO/IEC 42001, SOC 2, GDPR, and AIUC-1 — with honest gaps. Not certified.
Every claim below names the file in this repo that backs it. If a reviewer reads a claim here and cannot find it in the source tree, that is a bug — please flag it.
Up-front disclaimer
No third-party auditor has attested to ISO 27001, ISO 42001, SOC 2, or AIUC-1 alignment.
This page describes the controls shipped in the code — not a control attestation. The names «ISO/IEC 27001», «ISO/IEC 42001», «SOC 2», «GDPR», and «AIUC-1» are used to anchor the description to the public frameworks and the regulation that buyers ask about. Helmspur does not hold an ISO certificate, a SOC 2 Type I or Type II report, an AIUC-1 attestation, or any equivalent third-party sign-off as of this writing. GDPR is a legal obligation rather than a certification regime — the GDPR section on this page describes the data-handling posture, not a certified compliance level.
If a claim below doesn't match the code in this repo, that's a bug — please flag it at contact@helmspur.com.
The matrix below is a summary. Each framework has a dedicated section under it that names the controls in place (with file paths) and the controls still pending (honest gaps).
Annex A controls
AI management system
Trust Services Criteria
Legal obligation
Framework alignment
ISO/IEC 27001 maps onto operator-level controls. Below names the Annex A families that are already enforced in code in this repo, the families that are partially shipped, and the families that are still pending — no padding, no marketing copy.
In place — enforced by shipped code
src/lib/auth.ts, configured via src/lib/auth-config.ts); per-route gating uses requireAuth() from src/lib/require-auth.ts and requireAdmin() from src/lib/require-admin.ts.GET /api/brief/v1 (handler in src/app/api/brief/v1/route.ts) gates by a bearer API key. Keys are stored hashed: ApiKey.hash is scrypt-derived (N=2^15, r=8, p=1, keylen=64) with a per-row ApiKey.salt and a public-safe ApiKey.fingerprint (16-hex prefix of sha256 of the plaintext) — see prisma/schema/api-keys.prisma.ApiKeyAudit in prisma/schema/api-keys.prisma writes rows tagged action = 'generated' or 'rotated', carrying prefix (the public fingerprint) and createdAt — no plaintext, no salt, no hash ever logged./api/projects/[projectId]/… reads projectId from the URL and scopes queries with where: { projectId } — schema in prisma/schema/projects.prisma with @@index([projectId]) on Revision, @@index([projectId, createdAt]) and @@index([projectId, status]) on Clash, plus onDelete: Cascade back to Project.prisma/schema/contact.prisma, prisma/schema/waitlist.prisma) are self-contained with no @relation to any other module's model. Mail is sent via src/lib/email/send.ts through Polsia's platform proxy — no postmark, sendgrid, resend, or nodemailer import, and no vendor API key in any env file.proxy.ts emits per-request Content-Security-Policy built in src/lib/csp.ts, with upgrade-insecure-requests, frame-ancestors 'none', and a per-request script-src nonce with strict-dynamic. The IFC upload route is a same-origin multipart/form-data POST — no third-party upload URL.Still pending — honest gaps
Project.ownerEmail) rather than a centralised register.ISO/IEC 42001 governs organisations that develop or deploy AI systems. Helmspur itself is notan AI product — it is an IFC clash-detection tool. AI enters the picture only through Polsia's platform capabilities (a hosted AI proxy), and the scope of this section is that boundary, not a Helmspur-internal AI model.
In scope — what is shipped
package.json carries no openai, @anthropic-ai/sdk, @google-cloud/aiplatform, or mistralaidependency. Any future AI call lives behind Polsia's platform proxy, which is the only egress that holds provider credentials.src/app/api/ai/… route handlers, never in a client component. Browser code cannot reach the platform AI proxy directly..env. A grep over .env.example for OPENAI_API_KEY, ANTHROPIC_API_KEY, or equivalent returns zero matches — credentials live with the platform proxy, not the customer repo.Out of scope / pending — honest gaps
prisma/schema/projects.prisma, but the AI-prompt-time boundary is not yet pinned.SOC 2's Common Criteria are the closest match to the controls in this repo. The mapping below is from shipped code to each CC family — it is not a SOC 2 report, does not represent a Type I or Type II attestation, and covers the Common Criteria only. Availability, Confidentiality, and Processing Integrity are not formally covered by the controls in this repo today.
| Criterion | What | Backed by |
|---|---|---|
| CC6 — Access | Identity, roles, per-route gating. | better-auth — src/lib/auth.ts, requireAuth/requireAdmin |
| CC6.1 — API keys | Hashed key store, audit-logged generations / rotations. | prisma/schema/api-keys.prisma (ApiKey, ApiKeyAudit) |
| CC7 — System ops | db-backed storage; upload-route design (25 MB cap, 413). | src/app/api/projects/[projectId]/revisions/route.ts |
| CC8 — Change mgmt | PR-driven; module boundaries pinned in polsia.toml. | polsia.toml · general repo workflow |
| CC9 — Risk mitigation | CSP with per-request nonce; no vendor SDK in dependencies; no provider key in env. | src/lib/csp.ts · proxy.ts · package.json |
Not in scope for this page. Availability (A), Confidentiality (C), and Processing Integrity (PI) Common Criteria sub-families are not formally claimed. They are tracked here so a reviewer can see the negative space — what is not being asserted — alongside what is.
GDPR is a regulation, not a certification regime. There is no GDPR certificate a vendor can hold — what a reviewer reads here is the data-handling posture shipped in this repo, anchored to the sub-processor list and the data-model scoping. Helmspur is a controller for user/auth data and a processor for uploaded project content; both roles live on the same code, with the same per-row scoping.
In scope — what is shipped
/security/sub-processors and configured in polsia.toml under [env] DATABASE_URL = { source = "rdbms" }./security/sub-processors with data category and processing region per vendor — Polsia platform (EU/EEC); Stripe, Inc. via Polsia Connect (see Stripe's own list). Both rows last-reviewed 2026-08-23./api route that touches user-owned data is gated by requireAuth() (src/lib/require-auth.ts) for authenticated users and requireAdmin() (src/lib/require-admin.ts) for admin surfaces; queries carry where: { userId: user.id } sourced from the authenticated session./api/projects/[projectId]/… read projectId from the URL and scope reads and writes with where: { projectId }, and the schema marks Revision and Clash with @@index([projectId, ...]) for that exact predicate (schema: prisma/schema/projects.prisma).prisma/schema/contact.prisma and prisma/schema/waitlist.prisma carry no @relation to any other model — they exist solely to capture those forms and surface them in the same priority-leaning inbox.Revision and Clash carry onDelete: Cascade back to Project (prisma/schema/projects.prisma)./security: storage columns enumerated, raw .ifc bytes deliberately not stored (parsed in memory and dropped per src/lib/ifc/parser.ts), transport encrypted, sessions stored server-side only./security/contact page (ContactForm → POST /api/contact → ContactMessage table → founder email through src/lib/email/send.ts) logs each submission once in the same inbox, together with submitting address, company, project type, and message body.Pending gaps — honest, no padding
/security/contact and is actioned by the engineering owner against the FK-cascade path described above./api/brief/v1 procurement-API path./security/sub-processors points to Stripe's own published list and is not re-asserted here.AIUC-1 is a public AI-use-case framework. The boundary that this page reads against AIUC-1 controls is the same single-egress boundary the ISO 42001 section above already names. No AI call site is in production today; the framing here is what the planned AI surfaces would map to, against the controls that ship in this repo now, with no certification claim attached.
In scope — framework alignment as shipped
package.json carries no openai, @anthropic-ai/sdk, @google-cloud/aiplatform, or mistralai dependency. Any AI call site that lands in this repo goes through Polsia's platform proxy, which is the only egress that holds provider credentials.src/app/api/ai/… route handlers, never in a client component. Browser code cannot reach the platform AI proxy directly..env.example carries no OPENAI_API_KEY, ANTHROPIC_API_KEY, or equivalent — credentials stay on the proxy side, not in the customer repo.Pending gaps — honest, no padding
prisma/schema/projects.prisma, but the AI-prompt-time boundary is not yet pinned.The shipped features that back each framework section, grouped with the file paths a reviewer can open directly.
ISO/IEC 27001
src/lib/auth.ts, src/lib/auth-config.ts, src/lib/require-auth.ts, src/lib/require-admin.tsprisma/schema/projects.prisma, src/app/api/projects/[projectId]/route.ts, src/app/api/projects/[projectId]/revisions/route.tssrc/lib/csp.ts, proxy.tsprisma/schema/api-keys.prisma, src/app/api/brief/v1/route.ts, src/lib/brief/api-key-auth.tsprisma/schema/contact.prisma, prisma/schema/waitlist.prisma, src/app/api/contact/route.ts, src/app/api/waitlist/route.ts, src/lib/email/send.tsISO/IEC 42001
package.json contains no openai, @anthropic-ai/sdk, @google-cloud/aiplatform, or mistralai.src/app/api/ai/… when they exist..env.example carries no OPENAI_API_KEY, ANTHROPIC_API_KEY, or equivalent variable.SOC 2 — Common Criteria CC6–CC9
src/lib/auth.ts, src/lib/require-auth.ts, src/lib/require-admin.ts, src/app/(dashboard)/dashboard/src/app/api/projects/[projectId]/revisions/route.ts, src/lib/ifc/parser.tspolsia.toml + the general PR-driven repo workflowsrc/lib/csp.ts, proxy.ts, package.json, .env.exampleGDPR — Regulation (EU) 2016/679
/security/sub-processorssrc/lib/ifc/parser.ts, prisma/schema/projects.prisma, /security (storage section)src/lib/require-auth.ts, src/lib/require-admin.ts, src/app/api/projects/[projectId]/route.tsprisma/schema/contact.prisma, prisma/schema/waitlist.prisma, src/app/api/contact/route.ts, src/app/api/waitlist/route.ts, src/lib/email/send.tsprisma/schema/projects.prisma (onDelete: Cascade on Revision / Clash), /security (retention section)AIUC-1 — use-case framework alignment
package.json contains no openai, @anthropic-ai/sdk, @google-cloud/aiplatform, or mistralaisrc/app/api/ai/… when they exist.env.example carries no OPENAI_API_KEY, ANTHROPIC_API_KEY, or equivalent variableThe same engineering owner handles both the trust story and this framework scoreboard — so a question about a specific ISO clause, a SOC 2 mapping, or a missing item above goes to the same inbox, and the same-day reply applies.
Reader's checklist
Every claim above is enforced in code you can clone: the upload route at src/app/api/projects/[projectId]/revisions/route.ts, the data model in prisma/schema/projects.prisma, the auth narrative in src/lib/auth.ts and src/lib/auth-config.ts, the bearer-protected brief route at src/app/api/brief/v1/route.ts, the hashed key store in prisma/schema/api-keys.prisma, and the CSP story in src/lib/csp.ts + proxy.ts. If a claim doesn't match what you read, treat that as a bug — and tell contact@helmspur.com.