Authentication Security

Sessions are stateless JWTs; there is no server-side session table. This trades revocation immediacy for horizontal scalability and eliminates a session store as an attack and exhaustion target. The consequences of that trade-off are stated explicitly below.

Credential Hashing

The server applies the rule wherever a password is set; the browser checks it first only to explain it. Organizational controls (reuse history, dictionary/compromised-password blocking, rotation cadence) belong in your IdP when SSO is in use.

JWT Session Tokens

Revocation Semantics (state this to auditors)

Inactivity timeout: independent of the token's absolute lifetime, the client enforces Idle Timeout (Settings → Session & Security, default 10 minutes) as an inactivity window; Auto-Logout on Inactivity off turns it off for everyone. Interaction (pointer, keyboard, scroll) refreshes the window; once it elapses — checked periodically and again the moment the tab regains focus after a laptop wake — the app disconnects the user's database connections, clears the session, and returns to the sign-in screen with an explanatory notice.

Per-user revocation is immediate. Every request looks up the account behind the token. Deactivating or deleting a user ends their sessions on their next request (401 SESSION_ENDED, and the browser returns to sign-in with the reason); a role change applies to the next request; an administrator's password reset, or a password reset through a setup or reset link, ends every session issued before it. Rotating JWT_SECRET still ends all sessions at once.

Token Storage Trade-off

The bearer token lives in localStorage. This is an explicit, defensible choice given the header-based scheme:

The load-bearing dependency is therefore XSS prevention. Preserving the CSP and treating any new sink for untrusted HTML/script as a security-relevant change is the mitigating discipline.

Multi-Factor Authentication

RBAC & Separation of Duties

Every API route except sign-in, license status, health checks and client error reporting requires a signed-in user. That includes all of /api/connections, /api/db-devops/*, /api/ai/* and /api/notifications. Requests without a valid session token get 401.

Each user has exactly one built-in role: Admin, Release Manager, Approver or User. The server enforces these checks, and in DB DevOps a non-admin also needs the section the change belongs to (Configuration, Change Management, Schema or Governance) in one of their roles, or the change is refused with 403 SECTION_REQUIRED; see Roles & Access Control.

ActionWho can do it
Author and edit migration scripts; request an approvalAny signed-in user
Approve or reject a script; sign, reject or sign off an approval or releaseApprover, Release Manager or Admin
Withdraw a signature from a pending requestThe signer, or Admin
Revoke an approved requestApprover, Release Manager or Admin
Create or edit a release; delete a script; run, complete, fail or roll back an executionRelease Manager or Admin
Delete a release or an approval requestAdmin
Add or edit a DB DevOps connection (including bulk upload and import into DB DevOps)Release Manager or Admin
Add, edit, rename or delete environments and groupingsRelease Manager or Admin
Delete a DB DevOps connectionAdmin
View and test DB DevOps connectionsAny signed-in user
IDE connectionsTheir owner and admins, or everyone when the connection is shared. Anyone else gets 404 wherever the connection is named by its id: listing, connecting, the Object Explorer, queries, AI, Schema Ops and seed data
Create, edit, deactivate or delete users; roles; settings; AI provider configuration; identity provider configuration; data-protection export and erasureAdmin
Change a passwordAdmin for any user, or the user for their own account
Notifications and notification preferencesAlways the signed-in user's own

Self-approval. Admins choose, under Settings, Approval, whether people may approve their own work (Allow Self-Approval, on by default so a one-person install keeps working). When it is off, the server refuses with 403 and the reason: approving a script you wrote, signing an approval request you made or one for a script you wrote or a release you created, and signing off a release you created. The matching buttons are shown disabled, with the reason on hover. The switch is stored on the server and every change to it is audited under the signed-in admin.

A request that fails a role check gets 403 Insufficient permissions. Who did something is always taken from the signed-in session: script authors, approvers, rejecters, approval requesters, signers, release creators and execution runners are recorded as the signed-in user, whatever the request body says, so the audit trail can't be attributed to someone else. A signed-in user can still approve their own script if their role allows it. For a strict two-person rule on production, give authors the User role and approvers the Approver role, and treat Admin as a break-glass identity rather than a daily driver.

Brute-Force & Enumeration Resistance

SSO Federation

IdentityProviderService brokers SAML, OIDC, and LDAP, plus first-class providers (Azure AD, Okta, Google, AWS Cognito). Federated deployments should delegate password policy, MFA, conditional access, and session revocation to the IdP and treat the local credential path as break-glass only. IdP federation works with any active license.