Skip to content

Authentication API

The Authentication API provides local login, OIDC Authorization Code with PKCE, DUMB token handling, provider configuration, and user management.


Overview

Backend-native authentication endpoints are prefixed with /auth. Through the normal DUMB Frontend proxy, add /api (for example, /api/auth/login). When authentication is enabled, protected API endpoints require a valid JWT token in the Authorization: Bearer <token> header.


Endpoints

GET /auth/status

Returns the current authentication status.

Response

{
  "enabled": true,
  "has_users": true,
  "setup_skipped": false,
  "mode": "hybrid",
  "local_login_enabled": true,
  "oidc_login_enabled": true,
  "oidc_provider_name": "Authelia"
}
Field Type Description
enabled boolean Whether authentication is currently required
has_users boolean Whether any user accounts exist
setup_skipped boolean Whether initial setup was skipped
mode string local, hybrid, or oidc
local_login_enabled boolean Whether password login is available
oidc_login_enabled boolean Whether the OIDC login flow is available
oidc_provider_name string Display name shown by the login UI

GET /auth/provider

Returns the current mode and redacted OIDC provider configuration. The stored client secret is never returned; client_secret_configured indicates whether one exists.

PUT /auth/provider

Saves local, hybrid, or OIDC-only authentication. OIDC and hybrid requests include the issuer, client credentials, callback URL, scopes, claim mapping, optional allowed groups, and transport policy.

The callback must be the exact /api/auth/oidc/callback path on DUMB's browser-facing HTTPS FQDN. The API rejects HTTP, localhost, IP addresses, single-label hostnames, credentials, query strings, and fragments.

Set confirm_oidc_only=true when selecting OIDC-only mode. A blank client_secret preserves the existing stored secret.

POST /auth/oidc/test

Validates the proposed OIDC configuration and resolves provider metadata without saving it.

GET /auth/oidc/start?return_to=/

Creates bounded state, nonce, and PKCE values and returns:

{
  "authorization_url": "https://auth.example.com/api/oidc/authorization?..."
}

GET /auth/oidc/callback

Browser callback registered with the identity provider. DUMB validates the provider response and redirects to /login with a short-lived one-time exchange code in the URL fragment.

POST /auth/oidc/exchange

Redeems the one-time callback code for DUMB access and refresh tokens:

{
  "code": "<one-time-exchange-code>"
}

The code is single-use and does not contain provider tokens.


POST /auth/login

Authenticates a user and returns JWT tokens.

Request body

{
  "username": "admin",
  "password": "yourpassword"
}

Response

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer"
}

Error responses

Status Description
401 Invalid credentials
401 User account is disabled or the credentials are invalid

Example

Directly against the backend from inside the DUMB container, or after intentionally publishing port 8000:

curl -X POST http://127.0.0.1:8000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "yourpassword"}'

From the host in the standard deployment, use the DUMB Frontend proxy on the published port:

curl -X POST http://localhost:3005/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "yourpassword"}'

POST /auth/refresh

Exchanges a refresh token for new access and refresh tokens.

Request body

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}

Response

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer"
}

Error responses

Status Description
401 Invalid or expired refresh token

POST /auth/verify

Verifies that an access token is valid.

Pass the access token in the required token query parameter:

POST /auth/verify?token=eyJhbGciOiJIUzI1NiIs...

Response

{
  "valid": true,
  "username": "admin"
}

POST /auth/setup

Creates the first user account and enables authentication. Only works when no users exist.

Request body

{
  "username": "admin",
  "password": "yourpassword"
}

Response

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer"
}

Error responses

Status Description
400 Users already exist
400 Username is shorter than 3 characters or password is outside the 8–72 character range

POST /auth/skip-setup

Skips the initial setup wizard, leaving authentication disabled.

Response

{
  "message": "Authentication setup skipped successfully"
}

POST /auth/enable

Enables authentication. Requires at least one user to exist.

Response

{
  "message": "Authentication enabled successfully"
}

Error responses

Status Description
400 No users exist - create a user first

POST /auth/disable

Disables authentication, allowing unauthenticated access to all endpoints.

Security warning

Disabling authentication exposes all DUMB functionality without any access control.

Response

{
  "message": "Authentication disabled successfully"
}

User management endpoints

These endpoints require authentication when auth is enabled.

GET /auth/users

Lists all user accounts.

Response

{
  "users": [
    {
      "username": "admin",
      "disabled": false
    },
    {
      "username": "readonly",
      "disabled": true
    }
  ]
}

POST /auth/users

Creates a new user account.

Request body

{
  "username": "newuser",
  "password": "userpassword"
}

Response

{
  "username": "newuser",
  "disabled": false
}

Error responses

Status Description
400 Username already exists
400 Username is shorter than 3 characters or password is outside the 8–72 character range

PUT /auth/users/{username}

Updates a user account (enable/disable).

Path parameters

Parameter Type Description
username string The username to update

Request body

{
  "disabled": true
}

Response

{
  "username": "readonly",
  "disabled": true
}

Error responses

Status Description
400 Cannot disable the last active user
400 User not found

DELETE /auth/users/{username}

Deletes a user account.

Path parameters

Parameter Type Description
username string The username to delete

Response

{
  "message": "User deleted successfully"
}

Error responses

Status Description
400 Cannot delete yourself, cannot delete the last user, or user not found

Token structure

JWT tokens contain the following claims:

{
  "sub": "admin",
  "exp": 1704067200,
  "type": "access"
}
Claim Description
sub Username (subject)
exp Expiration timestamp (Unix epoch)
type Token type: access or refresh

Token lifetimes

Token Type Default Lifetime
Access Token 60 minutes
Refresh Token 30 days

Using authentication with other endpoints

When authentication is enabled, include the access token in the Authorization header:

curl -X GET http://localhost:3005/api/process/processes \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

WebSocket authentication

For WebSocket connections, pass the token as a query parameter:

ws://localhost:3005/ws/status?token=eyJhbGciOiJIUzI1NiIs...

Error handling

Common error responses

Status Error Description
401 Unauthorized Missing or invalid token
401 Token expired Access token has expired
403 Forbidden User account is disabled
422 Validation Error Invalid request body

Token refresh flow

When receiving a 401 response:

  1. Send the refresh token to POST /auth/refresh (or /api/auth/refresh through the frontend proxy)
  2. If successful, retry the original request with the new access token
  3. If refresh fails, redirect the user to login