Authentication Configuration
Auth is stateless JWT (HS256) over bcrypt-hashed credentials, with optional TOTP MFA and, on Enterprise, federated SSO. This page covers the token lifecycle, user provisioning, and the hardening surface an operator owns.
Flow
POST /api/auth/login resolves the user by email, verifies the submitted password against the stored bcrypt hash, and on success issues a JWT carrying userId, email, name, role, signed HS256 with JWT_SECRET. The client holds it in localStorage and sends Authorization: Bearer <token> on every call; the backend re-verifies signature and expiry per request. Because the token is stateless, anyone with JWT_SECRET can forge one for any user, keep it in a secret store, out of source and client code.
Password Hashing
bcrypt at cost 12, ~200-300ms/hash, per-hash salt, format $2b$12$.... Don't drop below 10.
Self-Service Password Reset
The sign-in screen shows a Forgot password? link for local (password) accounts. It routes to /forgot-password, where the user enters their email; the server mints a single-use, one-hour reset token and emails a link to /reset-password?token=… where they choose a new password. To prevent account enumeration the request endpoint always returns success, whether or not the email matches an account.
Email delivery is required for this to work. Configure SMTP (SMTP_HOST + SMTP_FROM, plus SMTP_PORT/SMTP_SECURE/SMTP_USER/SMTP_PASS as needed) so the app can send the reset email; MAIL_FROM overrides the envelope sender if set. Set APP_PUBLIC_URL to your externally reachable base URL so the link in the email is absolute (e.g. https://dbstudio.yourcompany.com). If no mail transport is configured the token is still minted but no email is sent, and the reset cannot complete, so treat SMTP as mandatory wherever local logins are used. SSO-managed users should reset at their identity provider instead.
Provisioning Users
Registration API
POST /api/auth/register
{ "email": "user@company.com", "password": "…", "name": "Jane Smith" }
Password is hashed server-side; default role is developer, an admin adjusts it afterward.
Direct insert (bootstrap admin / bulk)
node -e "require('bcrypt').hash('YourPassword123', 12).then(h => console.log(h));"
INSERT INTO users (email, password_hash, name, role, is_active)
VALUES ('admin@company.com', '$2b$12$…', 'Admin User', 'admin', true);
Roles
| Role | Access |
|---|---|
admin | Full access, incl. user management and system settings. |
developer | Author/edit scripts, request approvals. |
reviewer | Approve/reject scripts. |
deployer | Execute scripts, manage releases. |
viewer | Read-only. |
Token Lifecycle
TTL is JWT_EXPIRES_IN (default 8h). There is no refresh by design, on a 401 the client redirects to login. Logout clears client storage but, being stateless, the token stays cryptographically valid until expiry. To force a fleet-wide logout during an incident, rotate JWT_SECRET and restart, every outstanding signature fails at once.
Multi-Factor Authentication
Enterprise supports TOTP (RFC 6238) with 10 single-use backup codes stored as SHA-256 hashes; the TOTP secret is encrypted at rest with ENCRYPTION_KEY. Enrollment is POST /api/auth/mfa/setup then /enable.
Rate Limiting
Auth falls under the general bucket (GENERAL_RATE_LIMIT_MAX, default 2000 / 15 min per IP); DB DevOps routes use the wider DB_DEVOPS_RATE_LIMIT_MAX bucket. Breach returns 429. See Environment Variables for the knobs, and ensure the proxy forwards the real client IP or the per-IP keying is meaningless.
Hardening Checklist
- JWT_SECRET / ENCRYPTION_KEY, ≥32 chars (64 recommended), from a secret store. Rotating
ENCRYPTION_KEYorphans encrypted-at-rest data, back up first. - ENCRYPTION_KEY must be set, unset means secrets persist in plaintext behind a warning log.
- TLS in front, always. Terminate at the proxy; serve UI and API same-origin.
- Shortest practical
JWT_EXPIRES_IN. - Helmet sets security headers automatically; CSP permits
unsafe-evalsolely for the Monaco editor. - CORS allows only
CLIENT_URL, never*in production. - Least-privilege DB user.
- Bypass headers.
X-QA-Bypass-KeyandX-Agent-Keyskip auth/RBAC and are gated toNODE_ENV !== 'production', confirm prod actually setsNODE_ENV=production.
Enterprise SSO
Enterprise adds SAML, OIDC, and LDAP federation plus connectors for Azure AD, Okta, Google Workspace, and AWS Cognito, managed at /api/auth/idp/providers. See the Identity Providers page.