Security Overview

Simcha DB Studio executes SQL and DDL against production databases and custodies live credentials for every managed connection. The threat model is accordingly a privileged one: the application is both an authenticated multi-user surface and a secret store. Controls are layered so that a failure in any single control does not collapse the whole posture.

Control Layers

LayerMechanismProperty enforced
AuthenticationSigned JWT (HS256) checked against the account on every request, bcrypt(12) credential hashing, optional TOTP MFAIdentity assurance; no server-side session store to compromise or exhaust
AuthorizationRBAC middleware (extractUser / requireAuth / requireRole) over 4 roles plus custom roles, whose sections decide where a person can make changes; route gating by what the license includes; optional ban on self-approvalLeast privilege; separation of duties across the change-management workflow
Secret confidentialityAES-256-GCM at rest with per-record PBKDF2-SHA512 key derivationConnection passwords, repository-source and identity-provider secrets, MFA secrets, and AI provider keys and extra header values unreadable at rest; AI keys are never returned by the settings API
Transport / header hardeningCSP, frame denial, nosniff, referrer and permissions policies on every page and API response, plus HSTS and COOP over HTTPS; strict CORS allowlistDowngrade, framing, MIME-sniff, and cross-origin abuse mitigated
Abuse controlTiered rate limiting (general vs. DB DevOps bulk windows)Credential stuffing, brute force, and API flooding throttled
AccountabilityGlobal audit middleware writing a DB-sealed, append-only hash chainNon-repudiable, tamper-evident record of every state change

Trust Boundaries

The browser never speaks to Express directly. Requests traverse Next.js API routes (pages/api/*) which forward to the Express backend, propagating Authorization, X-Request-Id, and the non-prod X-QA-Bypass-Key header. Auth, RBAC, license gating, encryption, and audit all execute server-side; the frontend holds a bearer token and nothing else of consequence. X-QA-Bypass-Key is honored only when QA_BYPASS_KEY is set, signs the request in as a real admin account (qa@internal), and the server refuses to start when QA_BYPASS_KEY is set together with NODE_ENV=production. X-Agent-Key (matching AGENT_BYPASS_KEY) only exempts internal automation from rate limits and grants no identity or permissions; leave AGENT_BYPASS_KEY unset unless automation needs it.

HTTP Header Posture

The web tier sends these headers on every page and API response the browser receives (the Express API behind it sets its own Helmet headers as well). The last two are added only when the request reached the app over HTTPS, as reported by your TLS proxy's X-Forwarded-Proto: https; browsers ignore them on plain HTTP.

HeaderValueRationale
Content-Security-Policydefault-src 'self'; scripts and styles from the app only ('unsafe-eval' for the Monaco editor); images and workers also from data:/blob:; connections to the app and its WebSocket; no frames, plugins or foreign form targets; frame-ancestors 'none'Constrains every resource to the app's own origin; unsafe-eval is a scoped exception for Monaco
X-Frame-OptionsDENYClickjacking / UI-redress defense for browsers that predate frame-ancestors
X-Content-Type-OptionsnosniffBlocks MIME confusion on responses
Referrer-Policystrict-origin-when-cross-originNo paths or query strings leak to other sites
Permissions-Policycamera, microphone, geolocation, payment and USB disabledThe app never needs these browser capabilities
Cross-Origin-Opener-Policysame-originIsolates the app's window from pages it opens (HTTPS only)
Strict-Transport-Securitymax-age=31536000Pins HTTPS for the app's host (HTTPS only)

If NEXT_PUBLIC_API_URL points the browser at a separate API origin, that origin is added to the allowed connections. Treat any further CSP relaxation as a reviewable change.

Secrets Handled by the Application

Deployment Prerequisites (fail-loud, not fail-open)

ControlSeverityRequirement
JWT_SECRETCritical≥64 chars of CSPRNG output, from a secrets manager. Compromise = universal token forgery across all roles.
ENCRYPTION_KEYCriticalHigh-entropy, at least 32 characters, and required: the server refuses to start without it. Back it up with your other secrets; losing it makes stored connection passwords and MFA seeds unreadable.
TLS terminationCriticalTLS 1.2+ at the edge; HTTP→HTTPS redirect. The proxy must send X-Forwarded-Proto: https so the app adds HSTS.
Datastore isolationCriticalThe changeops/DevOps Postgres in a private subnet; ingress only from the app.
Non-prod bypass keys unsetCriticalLeave QA_BYPASS_KEY unset in production (the server refuses to start with it under NODE_ENV=production) and set AGENT_BYPASS_KEY only if internal automation needs its rate-limit exemption.
Managed-DB TLSHighsslmode=require or verify-full to target databases.
Secret rotationHighJWT_SECRET annually / on suspicion; DB passwords quarterly; repo tokens per provider policy.
Image scanningHighBlock critical/high CVEs pre-deploy; pin immutable tags.