Framework readiness

Helmspur's posture against ISO 27001, ISO 42001, SOC 2, GDPR, and AIUC-1.

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.

Not certified

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.

Status at a glance

Where each framework sits today.

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).

ISO/IEC 27001
Partial

Annex A controls

Authentication, access control, logging, segregation, transport — shipped in code. Asset inventory, formal risk treatment, and Statement of Applicability are still pending.
ISO/IEC 42001
In scope

AI management system

Single AI egress through Polsia's platform proxy — no provider SDK in this repo. Impact assessment, data lineage, human-oversight policy, model card registry, and AI incident playbook are still pending.
SOC 2
Mapped

Trust Services Criteria

Common Criteria CC6 (access) — CC9 (risk mitigation) mapped from shipped controls. No Type I or Type II report. Availability, confidentiality, and processing integrity are not formally covered.
GDPR
In scope

Legal obligation

Helmspur is subject to Regulation (EU) 2016/679 (GDPR) as a controller of user/auth data and a processor of uploaded project content — a legal obligation, not a certification. There is no GDPR certification regime.
AIUC-1
Readiness

Framework alignment

AIUC-1 is a public AI-use-case framework. The page describes framework alignment of Helmspur's eventual AI call sites against AIUC-1 controls — not certification. AIUC-1 has no third-party-attestation path in scope here.
ISO/IEC 27001

Annex A control coverage — what is shipped, what is pending.

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

  • A.5 / A.8 — Identity & access. Sign-in and session state come from better-auth (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.
  • A.5.15 / A.8.5 — Secure authentication. The public procurement API at 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.
  • A.5.30 — Audit logging for keys. 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.
  • A.8.3 — Information access restriction. Every route under /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.
  • A.8.15 / A.8.24 — Segregation. Contact-form and waitlist tables (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.
  • A.8.20 / A.8.22 — Transport & framing. 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

  • A.5.9 — Inventory of information & associated assets. No formal asset register; project ownership is per-row (Project.ownerEmail) rather than a centralised register.
  • A.6 — Risk treatment & Statement of Applicability. No SoA document; risk treatment is operational, not formally documented.
  • A.5.25–A.5.30 — Incident management & continuity. No formal incident-response runbook or business-continuity plan beyond the FK-cascade deletion path.
ISO/IEC 42001

AI-system governance — scope, posture, gaps.

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

  • Single egress — no provider SDK in this repo. 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.
  • Server-only call sites. Planned AI surfaces land in src/app/api/ai/… route handlers, never in a client component. Browser code cannot reach the platform AI proxy directly.
  • No third-party model provider key in .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

  • AI impact assessment. No documented AI risk/impact assessment for the planned call sites.
  • Data lineage. No formal trail of which uploaded-element fields can flow into an AI prompt; the upload payload contract is documented in prisma/schema/projects.prisma, but the AI-prompt-time boundary is not yet pinned.
  • Human-oversight policy. No documented human-in-the-loop review step for AI-assisted outputs.
  • Model-card registry. No centralised registry enumerating which model(s) the platform proxy routes to per capability.
  • AI change-management. The PR-driven change-management loop is in place (general repo), but a model upgrade / down-switch procedure specific to AI surfaces is not yet written.
  • AI-incident playbook. No documented incident-response procedure for an AI-specific failure mode (e.g. prompt-injection, jailbreak, model-degradation).
SOC 2

Trust Services Criteria mapping — Common Criteria CC6 through CC9.

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.

CriterionWhatBacked by
CC6 — AccessIdentity, roles, per-route gating.better-auth — src/lib/auth.ts, requireAuth/requireAdmin
CC6.1 — API keysHashed key store, audit-logged generations / rotations.prisma/schema/api-keys.prisma (ApiKey, ApiKeyAudit)
CC7 — System opsdb-backed storage; upload-route design (25 MB cap, 413).src/app/api/projects/[projectId]/revisions/route.ts
CC8 — Change mgmtPR-driven; module boundaries pinned in polsia.toml.polsia.toml · general repo workflow
CC9 — Risk mitigationCSP 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

Regulation (EU) 2016/679 — the data-handling posture, not a certification.

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

  • EU/EEC processing region. All app data lives in the EU/EEC platform-default region, declared on /security/sub-processors and configured in polsia.toml under [env] DATABASE_URL = { source = "rdbms" }.
  • Documented sub-processor list. Every third party with data access is enumerated on /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.
  • Per-user data scoping. Every /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.
  • Per-project content scoping. Routes under /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).
  • Purpose limitation. The waitlist and contact-form tables are self-contained: 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.
  • Right-to-deletion via cascade. Closing and deleting a project removes its revisions, clashes, and linked rows in one transaction — Revision and Clash carry onDelete: Cascade back to Project (prisma/schema/projects.prisma).
  • Data-handling envelope. Documented on /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.
  • Intake path. The /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

  • Article 30 record of processing. No formal record of processing activity lives in this repo — that artifact lives in compliance artifacts outside the app.
  • Self-serve Data Subject Access Request (DSAR). No DSAR endpoint. A deletion request goes through /security/contact and is actioned by the engineering owner against the FK-cascade path described above.
  • Data Protection Impact Assessment (DPIA). No formal DPIA on the contact / waitlist intake path or on the /api/brief/v1 procurement-API path.
  • International transfer mechanism — Stripe sub-region. No formal transfer-mechanism callout per Stripe sub-region; the region row on /security/sub-processors points to Stripe's own published list and is not re-asserted here.
AIUC-1

Use-case framework alignment — readiness, not certification.

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

  • Single AI egress — no provider SDK in this repo. 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.
  • Server-only call sites. Planned AI surfaces live under src/app/api/ai/… route handlers, never in a client component. Browser code cannot reach the platform AI proxy directly.
  • No third-party model provider key in env. .env.example carries no OPENAI_API_KEY, ANTHROPIC_API_KEY, or equivalent — credentials stay on the proxy side, not in the customer repo.
  • Same boundary as ISO 42001. The AIUC-1 read sits on top of the boundary already described in the ISO 42001 section above — one platform proxy, no provider SDK, no provider key in env.

Pending gaps — honest, no padding

  • AI use-case risk / impact assessment. No documented assessment for the planned call sites.
  • Data-lineage map. No formal line drawn from an uploaded IFC field to the AI-prompt boundary; the upload payload contract is documented in prisma/schema/projects.prisma, but the AI-prompt-time boundary is not yet pinned.
  • Human-oversight step. No documented human-in-the-loop review step for AI-assisted outputs.
  • Model-card registry. No centralised registry enumerating which model the platform proxy routes to per capability.
  • AI-incident playbook. No documented runbook for AI-specific failure modes (prompt injection, jailbreak, model degradation).
  • Model change-management. No formal model upgrade / down-switch procedure for the AI call sites.
Evidence

File paths behind every claim above.

The shipped features that back each framework section, grouped with the file paths a reviewer can open directly.

ISO/IEC 27001

  • Identity, sessions, admin grant: src/lib/auth.ts, src/lib/auth-config.ts, src/lib/require-auth.ts, src/lib/require-admin.ts
  • Per-project scoping & cascade: prisma/schema/projects.prisma, src/app/api/projects/[projectId]/route.ts, src/app/api/projects/[projectId]/revisions/route.ts
  • Transport & CSP: src/lib/csp.ts, proxy.ts
  • Hashed API keys & rotation audit: prisma/schema/api-keys.prisma, src/app/api/brief/v1/route.ts, src/lib/brief/api-key-auth.ts
  • Segregation of contact, waitlist, and email paths: prisma/schema/contact.prisma, prisma/schema/waitlist.prisma, src/app/api/contact/route.ts, src/app/api/waitlist/route.ts, src/lib/email/send.ts

ISO/IEC 42001

  • No provider SDK — package.json contains no openai, @anthropic-ai/sdk, @google-cloud/aiplatform, or mistralai.
  • Single egress lives on the platform proxy side; this repo's role is server-only call sites under src/app/api/ai/… when they exist.
  • No provider key in env — .env.example carries no OPENAI_API_KEY, ANTHROPIC_API_KEY, or equivalent variable.

SOC 2 — Common Criteria CC6–CC9

  • CC6: src/lib/auth.ts, src/lib/require-auth.ts, src/lib/require-admin.ts, src/app/(dashboard)/dashboard/
  • CC7: src/app/api/projects/[projectId]/revisions/route.ts, src/lib/ifc/parser.ts
  • CC8: polsia.toml + the general PR-driven repo workflow
  • CC9: src/lib/csp.ts, proxy.ts, package.json, .env.example

GDPR — Regulation (EU) 2016/679

  • Sub-processor list with data category + region: /security/sub-processors
  • Storage envelope & raw-byte exclusion: src/lib/ifc/parser.ts, prisma/schema/projects.prisma, /security (storage section)
  • Per-user / per-project session scoping: src/lib/require-auth.ts, src/lib/require-admin.ts, src/app/api/projects/[projectId]/route.ts
  • Intake path (purpose-limited): prisma/schema/contact.prisma, prisma/schema/waitlist.prisma, src/app/api/contact/route.ts, src/app/api/waitlist/route.ts, src/lib/email/send.ts
  • Deletion cascade & FK scoping: prisma/schema/projects.prisma (onDelete: Cascade on Revision / Clash), /security (retention section)

AIUC-1 — use-case framework alignment

  • No provider SDK — package.json contains no openai, @anthropic-ai/sdk, @google-cloud/aiplatform, or mistralai
  • Single egress on the platform-proxy side; this repo's role is server-only call sites under src/app/api/ai/… when they exist
  • No provider key in env — .env.example carries no OPENAI_API_KEY, ANTHROPIC_API_KEY, or equivalent variable
  • AIUC-1 boundary is the same single-egress boundary that backs the ISO 42001 section above
Framework-specific walkthrough

Where to send a finding.

The 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.