Skip to content
ABRQ DATADocs Abrq DIP · latest
Product page Request a trial
On this page

Authentication

Password authentication#

Local accounts authenticate with username and password:

  • Passwords are hashed with bcrypt (cost factor configurable via ABRQ_BCRYPT_ROUNDS, default 12). Plaintext passwords are never stored or logged.
  • Forced first-login change. A freshly seeded account must change its password before it can use the application — the UI blocks every other screen until the change completes.
  • Login attempts are rate-limited to 10 per minute per client (on top of the global API limit of 100 per minute).

Initial admin seed#

On first boot against an empty users table, the backend seeds one administrator account from ABRQ_INITIAL_ADMIN_USERNAME, ABRQ_INITIAL_ADMIN_EMAIL, and ABRQ_INITIAL_ADMIN_PASSWORD. Two guardrails apply:

  • In production, startup refuses to run with the literal default password — you must set a real one.
  • The seeded password is also written once to a 0600-permission file (ABRQ_INITIAL_PASSWORD_FILE, default /var/abrq-dip/initial-password.txt) so the bootstrap credential never has to travel through logs or chat. This is the only file the application ever writes credentials to.

JWT session model#

Interactive sessions use two tokens with different lifetimes and transports:

Token Lifetime Transport
Access token 15 minutes (ABRQ_ACCESS_TOKEN_TTL_MINUTES) Authorization: Bearer header
Refresh token 7 days (ABRQ_REFRESH_TOKEN_TTL_DAYS) HTTP-only cookie
  • Tokens are signed with ABRQ_JWT_SECRET (HMAC; ABRQ_JWT_ALGORITHM supports HS256/HS384/HS512, default HS256). Production requires a secret of at least 32 characters.
  • The refresh token lives in the abrq_refresh cookie: HttpOnly, SameSite=Strict, and path-scoped to /api/v1/auth — it is never sent to any other endpoint and is unreadable from JavaScript.
  • Rotation with reuse detection. Every refresh issues a new refresh token and invalidates the old one. If a previously used refresh token is presented again — the signature of token theft — the platform revokes the entire session family, forcing a fresh login, and records a refresh_token_reuse_detected event in the audit log.
  • Revoked tokens go on a server-side deny-list that is checked on every request; expired deny-list entries are pruned by the retention sweep.

Note. Rotating ABRQ_JWT_SECRET invalidates all outstanding sessions at once — a deliberate kill switch, independent of the secrets master key. See Secrets & encryption.

API tokens#

For scripts and integrations, users create personal API tokens under Settings → Tokens (admins manage any user's tokens):

  • Tokens carry the abrq_ prefix so they are recognizable in configs and secret scanners. The full value is shown once at creation and never again.
  • Each token has a scope: read or write, enforced centrally — a read-scoped token receives 403 on every mutating request, regardless of the user's roles.
  • Tokens can additionally be scoped to specific projects, limiting them to a subset of the ETL surface.
  • Tokens authenticate via the same Authorization: Bearer header as access tokens and can be revoked individually at any time.

SSO and LDAP#

Abrq DIP supports external identity at a concepts level here — admin setup is covered in authentication providers:

  • OIDC single sign-on. Admins register one or more OIDC providers; the provider configuration (client secret included) is stored encrypted. The login flow is the standard authorization-code dance: the backend issues a signed state JWT with a 600-second TTL (ABRQ_SSO_STATE_TTL_SECONDS) at the start of the flow and verifies it at the callback, defeating replayed or forged callbacks.
  • LDAP. Admins register LDAP providers whose bind configuration is stored encrypted; users authenticate with their directory credentials.

The SSE exception#

Two endpoints stream live logs over Server-Sent Events. Browsers cannot attach headers to EventSource connections, so these two endpoints alone accept the access token as a ?token= query parameter instead of a header:

  • GET /api/v1/cdc-tables/{id}/logs/stream
  • GET /api/v1/streams/{id}/runs/stream

The token is the same short-lived (15-minute) access token — the query-string exposure window is bounded by that TTL.

Unauthenticated surface#

Only the following endpoints accept requests without credentials: /health, /metrics, /docs, /openapi.json, POST /api/v1/auth/login, POST /api/v1/auth/refresh, and the SSO discovery/start/callback routes. Everything else requires a valid access token or API token.