sethucms
Security and running it

Security

Security drives the architecture. This page lists the controls the MVP must have.

Threat model

Drawing diagram…
ThreatControl
Stolen credentials from the control planeEnvelope encryption, key held in KMS, not in the database
Credentials leaking to clientsClients only call the API; secrets never leave vault
SSRF through "bring your own database" hostsBlock private ranges and metadata endpoints unless explicitly configured
Query injectionParameterised queries, identifier allowlist from introspected metadata, operator allowlist
Over-broad database accessDedicated least-privilege role, read-only by default
Cross-tenant impactIsolated workers, per-connection pool and rate limits
Unaccountable changesAppend-only audit log outside tenant databases

Credentials

  • Encrypt connection secrets with a data key wrapped by a KMS key (envelope encryption), with a documented rotation path.
  • Back up the key separately from database backups. Losing it makes secrets unrecoverable.
  • Prefer identity-based access over stored passwords:
    • AWS: IAM database auth, cross-account role with external ID, Secrets Manager ARN
    • Google: service accounts, Cloud SQL connector, IAM database auth
    • Azure: Entra ID tokens, managed identities (tokens expire, so the vault refreshes them)
  • Never log secrets. Redact connection strings in errors.

Least privilege

  • Ask tenants for a dedicated CMS role scoped to the needed schemas or tables.
  • Connections are read-only by default; write mode is an explicit opt-in.
  • Firebase: the Admin SDK uses a service account with full access and is not gated by Security Rules. Scope the service account with IAM and enforce authorization in the CMS.
  • Supabase: the service-role key bypasses row-level security. To enforce RLS, forward the editor's JWT or use a dedicated Postgres role instead.

Network controls

  • Require TLS (verify-full where supported); allow custom CA bundles.
  • Publish static egress IPs so tenants can allowlist the platform.
  • Support SSH tunnels and private networking (PrivateLink, Private Service Connect, Azure Private Link).
  • Resolve and validate hostnames server-side; re-check after DNS resolution to avoid rebinding.

Injection defence

  • Compile the query AST to parameterised queries only.
  • Allowlist table and column names against introspected metadata.
  • MongoDB: reject operator injection ($where, $function, keys starting with $ from user input).
  • Firestore and DynamoDB: validate field paths.
  • Raw-query features sit behind a separate permission and are always audited.

Access control

  • SSO/OIDC for editors, MFA for admins.
  • RBAC at collection level, plus field rules (hide, mask, read-only) and row filters.
  • Permission checks run in the gateway, independent of database grants (defence in depth).

Audit

Append-only, stored in the control plane, never in tenant databases. Record: actor, tenant, connection, collection, record id, operation, before/after diff with sensitive fields redacted, IP, timestamp. Also log connection create/update, credential reads by workers, and permission changes.

Security test suite

tests/security/ must cover SQL and NoSQL injection, identifier allowlist bypass, SSRF (private IPs, metadata IPs, DNS rebinding), permission bypass (field and row rules), secret leakage in logs and errors, and cross-tenant access.

Supply chain

Generate an SBOM in CI, pin dependencies, and run dependency scanning on every pull request.