Live data from Hacker News

We made compliance violations compiler errors, not audit findings

forklaunch.com

1–3 of 3 posts

Re: We made compliance violations compiler errors, not audit findings

#2
ForkLaunch is an open-source TypeScript framework. The compliance primitives below live in the framework core (MIT, standalone with MikroORM).

If your code compiles, it's compliant. If not, it doesn't compile.

Type system enforcing data classification. Every DB field must be classified pii, phi, pci, or none. Not a lint rule. tsc fails.

  const User = defineComplianceEntity({
    name: 'User',
    properties: {
      email: fp.string().unique().compliance('pii'),
      ssn: fp.string().nullable().compliance('phi'),
      cardNumber: fp.string().compliance('pci'),
      age: fp.integer().compliance('none'),
    }
  });
defineComplianceEntity wraps defineEntity with a ValidateProperties mapped type. Each property must carry a phantom marker only set by .compliance(). Miss one, call-site error.

fp is a Proxy over MikroORM's property builder. .compliance('pii') injects EncryptedType into the type pipeline. For enums, the Proxy strips the DB CHECK constraint (would reject ciphertext) and moves validation to the app layer.

The encryption tradeoff. Classified fields encrypt at rest via AES-256-GCM. Random IVs are most secure, but we chose deterministic: IV = HMAC-SHA256(key, plaintext)[0:12]. Same plaintext + same key = same ciphertext, so WHERE filtering and UNIQUE constraints still work on encrypted columns.

The downside: equality leaks. We mitigate with per-tenant HKDF-SHA256 key derivation (info=tenantId). Cross-tenant pattern leakage is eliminated; within-tenant leakage remains, but for multi-tenant SaaS this matches what SOC 2, HIPAA, and PCI-DSS actually require. HKDF over PBKDF2 because the master key is already high-entropy.

Mandatory access posture on every route. If a route returning PII forgets its auth check, encryption doesn't save you. Every handler takes a required access field: 'public', 'authenticated', 'protected', or 'internal'. The type narrows: 'protected' requires auth.allowedRoles, 'internal' requires hmac.secretKeys. Those combinations don't typecheck without the peer field.

Every HTTP/WS request emits a structured OpenTelemetry audit entry: userId, tenantId, route, method, SHA-256 body hash (not the body), status, duration, redacted field names, and a discriminated event type (http, ws, auth_failure, rate_limit, rbac_deny, super_admin_bypass). Zero app instrumentation.

Closing the escape hatches.

ORM: em.nativeInsert would bypass the type pipeline. We Proxy the EM and throw EncryptionRequiredError on native ops against encrypted entities.

DB: PostgreSQL RLS (SET LOCAL app.tenant_id) plus ORM global filters auto-appending WHERE organizationId = :tenantId.

Network (platform-deployed): each env gets its own VPC, private-subnet RDS, no public endpoints. KMS keys scoped per region × env.

AsyncLocalStorage + pg pool: enterWith() sets context per async resource, but pg pool callbacks run in the pool's resource, not the request's. Tenant ID disappears; decryption silently uses the wrong key. Fix: Proxy every EM method in AsyncLocalStorage.run() to propagate through pool boundaries.

Also in the framework: GDPR DSAR export/erase walking the entity registry (Art. 20/17), declarative retention, oxc-based CLI audit outputting risk scores and DPIAs, and standards-to-infra mapping (SOC 2 / HIPAA / GDPR / PCI-DSS / ISO 27001 → Pulumi AWS resources).

Thesis: any compliance posture that depends on humans remembering things will fail after MVP. If it's enforced structurally, it doesn't matter who or what writes the code.

Known limits: TS+MikroORM only; within-tenant equality leaks on encrypted columns; manual key rotation.

Docs: https://www.forklaunch.com/docs/compliance/overview Repo: https://github.com/forklaunch/forklaunch

Happy to dig into implementation or tradeoffs.