Corebanq Public Docs
Auth

Description

Overview

The Authentication API provides comprehensive authentication and authorization functionality:

  • User authentication with username/password
  • Multi-factor authentication (2FA)
  • JWT token management (access & refresh tokens)
  • API key authentication
  • CORS configuration
  • Kubernetes-friendly session management
  • Device tracking and security

Core Concepts

Authentication Methods

1. Bearer Token

  • Access token (JWT, 15 minutes)
  • Refresh token (14 days, HTTP-only cookie)
  • Token rotation on refresh
  • Refresh-token idle timeout policy (configurable inactivity window)

2. API Key

  • Static keys from configuration
  • Request header: X-API-Key
  • Used for service-to-service communication

3. Application Identity (X-App-ID)

  • Deterministic identifier sent via X-App-ID header (e.g. web-app, admin-app, configurator-app)
  • Scopes the refresh-token cookie per application (refresh_token_web-app, refresh_token_admin-app, etc.)
  • Prevents cross-app token collisions when multiple frontends share the same domain
  • Backend validates the header against a configurable whitelist (auth.allowed_app_ids)
  • The App ID is stored inside the refresh token in Redis; on refresh the value must match
  • When no whitelist is configured, any non-empty value is accepted (backward-compatible)

4. Multi-Factor Authentication (2FA)

  • Email OTP
  • Phone OTP
  • TOTP (Time-based One-Time Password)
    • RFC 6238 compliant
    • 30-second time window
    • 6-digit codes
    • QR code generation for setup
    • Backup codes for recovery

5. MFA Session Boundary

  • challenge_token is a pre-auth token used only for MFA/TOTP challenge flows.
  • access_token is a post-auth token with sub=user_auth and is the only bearer token accepted on protected routes.
  • For MFA-enabled users, the initial /v1/authenticate response does not issue an authenticated access token or refresh-token cookie.
  • The authenticated session is created only after successful /v1/verify-2FA.
  • Replaying challenge_token on protected routes or /v1/refresh-token is rejected.

6. MFA mode semantics (mfa_mode)

  • off: After a successful password check, authentication completes without an interactive MFA step (no challenge payload); the API issues normal session artifacts (access_token, refresh cookie when applicable).
  • email / phone / totp: Successful password verification yields a pre-auth challenge (credential_type, challenge_token, localized message) until /v1/verify-2FA succeeds.
  • totp_setup_required: When TOTP is required but not yet enrolled, the challenge response uses credential_type: "totp_setup_required" and a localized message (see auth_m.totp_setup_required in auth_m.yaml). This applies in particular to Internal-role users with mfa_mode: totp and no TOTP secret yet (enrollment must finish before a full session is granted). Non-internal users in totp mode without a secret may receive the same payload when no validated email/phone fallback is available.

7. Internal invitation default MFA (users module)

Users created via /v1/users/admin/invite get their stored mfa_mode from auth.internal_invite.mfa_mode in the auth app-config module (totp, email, or phone), so privileged invites can enforce stricter MFA than the tenant default.

Security Features

Brute Force Protection

  • Maximum login attempts (configurable)
  • Cooling-off period
  • IP-based rate limiting
  • Device tracking

Admin Account Protection

  • Email Alert System: Failed admin login attempts trigger immediate email notifications
  • Alert Throttling: Email notifications have configurable cooldown periods to prevent spam
  • Enhanced Logging: Admin access attempts include detailed metadata (IP, user agent, timestamps)
  • Escalated Security: Admin accounts receive stricter security policies and monitoring
  • Real-time Notifications: Security teams receive instant alerts for suspicious admin activity

Token Security

  • HTTP-only cookies for refresh tokens
  • Secure token rotation
  • Device binding
  • IP tracking

Cache Degradation (Fail-Closed)

Authentication depends on cache availability for refresh token validation and access token blacklist checks. If the cache is unavailable, auth endpoints and protected routes return 503 Service Unavailable. This prevents accepting stale access tokens when revocation cannot be enforced.

Endpoints

Authentication

Login

POST /v1/authenticate

Authenticate user and get tokens.

If the user's mfa_mode is off, the response contains the authenticated access_token and the server sets the refresh-token cookie (no MFA challenge).

If mfa_mode is email, phone, or totp (and TOTP is already enrolled where applicable), the response is a challenge response instead: no authenticated session artifacts are issued yet, and the client must complete /v1/verify-2FA first.

If TOTP is required but not enrolled, the challenge may use credential_type: "totp_setup_required" so the client can complete TOTP setup before verification.

Request Body:

{
  "username": "user@example.com",
  "password": "secure_password"
}

Response:

{
  "credential_type": "email",
  "message": "OTP sent successfully",
  "challenge_token": "eyJ0eXAi...",
  "user_id": "123e4567-e89b-12d3-a456-426614174000"
}

Admin Login

POST /v1/authenticate/admin

Authenticate admin user with Internal role and get tokens. This endpoint requires the user to have the Internal role and includes enhanced security monitoring.

When mfa_mode is not off, the initial response is a pre-auth challenge; authenticated bearer/session artifacts are issued only after /v1/verify-2FA succeeds (or after TOTP enrollment when credential_type is totp_setup_required).

Request Body:

{
  "username": "admin@example.com",
  "password": "secure_password"
}

Response:

{
  "access_token": "eyJ0eXAi...",
  "expires_in": 900,
  "idle_timeout_seconds": 900,
  "user_id": "123e4567-e89b-12d3-a456-426614174000"
}

Error Response (403):

{
  "code": "auth.unauthorized_role",
  "message": "User does not have the required Internal role"
}

Admin Security Features:

  • Enhanced Monitoring: Failed admin login attempts trigger immediate security alerts
  • Email Notifications: Administrators receive real-time email alerts for suspicious activity
  • Extended Cooling Periods: Admin accounts have longer lockout periods for security
  • IP Tracking: All admin access attempts are logged with IP addresses and user agents

Refresh Token

POST /v1/refresh-token

Get new access token using refresh token.

The Authorization header must contain a real authenticated user_auth access token. Pre-auth challenge_token values are rejected.

Response:

{
  "access_token": "eyJ0eXAi...",
  "expires_in": 900,
  "idle_timeout_seconds": 900,
  "user_id": "123e4567-e89b-12d3-a456-426614174000"
}

Verify 2FA

POST /v1/verify-2FA

Verify 2FA code and complete authentication.

This is the elevation point for MFA-enabled users. On success, the server issues the authenticated access_token and the refresh-token cookie.

When auth.2fa_challenge=true, clients must also send the challenge token returned by /v1/authenticate in X-MFA-Challenge.

Request Body:

{
  "user_id": "123e4567-e89b-12d3-a456-426614174000",
  "otp": "123456"
}

Response:

{
  "access_token": "eyJ0eXAi...",
  "expires_in": 900,
  "idle_timeout_seconds": 900,
  "user_id": "123e4567-e89b-12d3-a456-426614174000"
}

Logout

POST /v1/logout

Invalidate tokens and end session.

When the Authorization: Bearer {access_token} header is provided, the access token is immediately invalidated. Any subsequent requests using that token will return 401 Unauthorized, even if the token has not yet expired.

TOTP Management

Setup TOTP

POST /v1/totp/setup

Initialize TOTP setup for a user. Returns QR code and secret for authenticator app setup.

Request Headers:

Authorization: Bearer {challenge_token}   # pre-auth TOTP setup flow

Use authenticated Authorization: Bearer {access_token} only for post-login TOTP management routes such as disable/recovery operations.

Response:

{
  "secret": "JBSWY3DPEHPK3PXP",
  "qr_code": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
  "backup_codes": [
    "123456789",
    "987654321",
    "456789123",
    "789123456",
    "321654987"
  ],
  "issuer": "CoreBanq",
  "account_name": "user@example.com"
}

Verify TOTP Setup

POST /v1/totp/verify-setup

Verify TOTP setup by confirming the first code from authenticator app.

Request Body:

{
  "secret": "JBSWY3DPEHPK3PXP",
  "totp_code": "123456"
}

Response:

{
  "success": true,
  "message": "TOTP successfully enabled"
}

Verify TOTP Code

POST /v1/totp/verify

Verify TOTP code during authentication process.

Request Body:

{
  "user_id": "123e4567-e89b-12d3-a456-426614174000",
  "totp_code": "123456"
}

Response:

{
  "access_token": "eyJ0eXAi...",
  "expires_in": 900,
  "user_id": "123e4567-e89b-12d3-a456-426614174000"
}

Verify Backup Code

POST /v1/totp/verify-backup

Verify backup code as alternative to TOTP.

Request Body:

{
  "user_id": "123e4567-e89b-12d3-a456-426614174000",
  "backup_code": "123456789"
}

Response:

{
  "access_token": "eyJ0eXAi...",
  "expires_in": 900,
  "user_id": "123e4567-e89b-12d3-a456-426614174000",
  "remaining_codes": 4
}

Disable TOTP

DELETE /v1/totp/disable

Disable TOTP for the authenticated user.

Request Headers:

Authorization: Bearer {access_token}

Request Body:

{
  "current_password": "user_password",
  "totp_code": "123456"
}

Response:

{
  "success": true,
  "message": "TOTP successfully disabled"
}

Regenerate Backup Codes

POST /v1/totp/backup-codes/regenerate

Generate new backup codes (invalidates existing ones).

Request Headers:

Authorization: Bearer {access_token}

Request Body:

{
  "totp_code": "123456"
}

Response:

{
  "backup_codes": [
    "987654321",
    "123456789",
    "456123789",
    "789456123",
    "321987654"
  ]
}

Error Handling

All errors follow a standard format:

{
  "status": 401,
  "message": "Invalid credentials"
}

All error responses include the X-Request-ID header for tracing:

HTTP/1.1 401 Unauthorized
Content-Type: application/json
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000

{"status":401,"message":"Invalid credentials"}

Tip: When reporting issues, always include the X-Request-ID from the response header for faster debugging.

Error Codes

Authentication Errors

CodeDescription
auth.unauthorizedInvalid credentials
auth.account_lockedAccount locked due to too many attempts
auth.unauthorized_roleUser does not have the required role
auth.invalid_tokenInvalid access token
auth.token_expiredToken has expired
auth.invalid_refresh_tokenInvalid refresh token
auth.device_info_mismatchDevice mismatch detected
auth_m.invalid_app_idX-App-ID value is not in the allowed whitelist
auth_m.app_id_mismatchX-App-ID does not match the app that created the refresh token
auth_m.invalid_challengeInvalid MFA challenge token
auth_m.challenge_already_usedMFA challenge token has already been used or expired from cache

Admin Account Errors

CodeDescription
auth.admin_lockedAdmin account locked due to failed attempts
auth.unauthorized_roleUser does not have required Internal role
auth.admin_alert_sentSecurity alert sent to administrators

TOTP Errors

CodeDescription
auth.totp_invalid_codeInvalid TOTP code
auth.totp_code_expiredTOTP code has expired
auth.totp_already_enabledTOTP is already enabled for this user
auth.totp_not_enabledTOTP is not enabled for this user
auth.totp_setup_requiredTOTP setup must be completed first
auth.backup_code_invalidInvalid backup code
auth.backup_code_usedBackup code has already been used
auth.backup_codes_exhaustedAll backup codes have been used

API Key Errors

CodeDescription
auth.api_key_requiredMissing API key
auth.invalid_api_keyInvalid API key

Configuration

JWT Settings

auth:
  jwt_secret: "your_secret_key"
  access_token_ttl_minutes: 15
  refresh_token_ttl_minutes: 20160  # 14 days
  refresh_token_idle_timeout_minutes: 15  # inactivity timeout for refresh usage

Refresh Idle Timeout Behavior

  • refresh_token_idle_timeout_minutes defines the inactivity window for refresh-token usage.
  • If the refresh token is not used within this window, refresh validation fails and re-authentication is required.
  • API token responses include idle_timeout_seconds so clients can align UI timers with backend policy.
auth:
  cookie:
    # Allow insecure cookies (HTTP) for local development (default: false)
    allow_insecure: false
    
    # SameSite mode: strict, lax, or none (default: none)
    # 'none' is required for cross-origin requests (e.g., frontend on separate domain/port)
    same_site: "none"
    
    # Domain for the cookie (default: empty/host-only)
    # - Empty: Cookie is set for the specific host only (best for production)
    # - "localhost": Auto-set when SameSite=None and host is localhost/127.0.0.1 (fixes cross-port dev)
    # - Explicit Value: Set if valid for subdomains (e.g., ".example.com")
    domain: ""

App ID Whitelist

auth:
  allowed_app_ids:
    - web-app
    - admin-app
    - configurator-app

When the whitelist is configured, only the listed values are accepted in the X-App-ID header. An unknown value returns 400 Bad Request. When the list is empty or absent, any non-empty X-App-ID value is accepted (backward-compatible).

The App ID is persisted in the refresh token stored in Redis. During token refresh, the backend compares the stored App ID with the incoming X-App-ID header. A mismatch immediately revokes the token and returns 401 Unauthorized. Tokens created before this feature (no App ID stored) are not affected; the check is skipped for them.

API Key Settings

auth:
  api_keys:
    - "key1"
    - "key2"

Admin Security Settings

auth:
  admin_email: "security@company.com"
  brute_force:
    alert:
      ttl_minutes: 60  # Email notification cooldown
  audit_fields_internal: true  # Remove audit fields for non-internal users

CORS Settings

auth:
  cors:
    allowed_origins: ["https://example.com"]
    allowed_methods: "GET,POST,PUT,DELETE,OPTIONS"
    allowed_headers: "Content-Type,Authorization,X-API-Key"
    allow_credentials: "true"

TOTP Settings

auth:
  totp:
    issuer: "CoreBanq"
    digits: 6
    period: 30  # seconds
    skew: 1     # allow 1 period of drift
    backup_codes_count: 5
    qr_code_size: 256  # pixels

Security Best Practices

  1. Token Management

    • Use short-lived access tokens
    • Secure refresh token storage
    • Implement token rotation
    • Monitor suspicious activity
  2. Device Security

    • Track device information
    • Detect suspicious changes
    • Implement device fingerprinting
    • Alert on security events
  3. Rate Limiting

    • Per-IP rate limits
    • Cooling-off periods
    • Graduated response
    • Admin notifications
  4. TOTP Security

    • Enforce unique codes (prevent replay attacks)
    • Secure secret storage
    • Backup code management
    • QR code security
    • Time synchronization
  5. Admin Account Security

    • Real-time email alerts for failed login attempts
    • Enhanced monitoring and logging
    • Stricter cooling-off periods
    • IP address and user agent tracking
    • Configurable notification thresholds

Headers

Request Headers

HeaderDescription
AuthorizationBearer token
X-API-KeyAPI key
X-Device-IDDevice identifier
X-App-IDApplication identifier (web-app, admin-app, configurator-app). Scopes refresh-token cookies per app.
X-Request-IDOptional client-provided request ID for tracing (auto-generated if not provided)
Accept-LanguagePreferred language

Response Headers

HeaderDescription
X-Request-IDUnique request identifier for tracing and correlation
Set-CookieRefresh token

Authorization on protected routes and refresh must always carry a post-auth access_token with sub=user_auth. challenge_token values are accepted only by explicit MFA/TOTP challenge handlers. | Access-Control-Allow-* | CORS headers |

Request Tracing

All API requests include automatic request ID tracing for debugging and support purposes.

How It Works

  1. Client-Provided ID: If you include an X-Request-ID header in your request, the API will use that ID
  2. Auto-Generated ID: If no X-Request-ID is provided, the API automatically generates a unique UUID
  3. Response Header: The X-Request-ID is always returned in the response headers
  4. Log Correlation: All server-side logs include the request ID for easy debugging

Usage Example

# With client-provided request ID
curl -X POST https://api.example.com/v1/authenticate \
  -H "Content-Type: application/json" \
  -H "X-Request-ID: my-custom-trace-123" \
  -d '{"username": "user@example.com", "password": "password"}'

# Response headers will include:
# X-Request-ID: my-custom-trace-123
# Without request ID (auto-generated)
curl -X POST https://api.example.com/v1/authenticate \
  -H "Content-Type: application/json" \
  -d '{"username": "user@example.com", "password": "password"}'

# Response headers will include:
# X-Request-ID: 550e8400-e29b-41d4-a716-446655440000

Benefits

  • Debugging: Easily trace requests through server logs
  • Support: Provide the request ID when reporting issues for faster resolution
  • Correlation: Track related requests across multiple API calls
  • Monitoring: Use request IDs in observability tools for request tracing

Language Support

The API supports localization through the Accept-Language header:

  • English (en)
  • German (de)
  • French (fr)
  • Italian (it)

TOTP Integration Flow

Initial Setup

  1. User requests TOTP setup via /v1/totp/setup
  2. System generates secret and QR code
  3. User scans QR code with authenticator app
  4. User verifies setup with /v1/totp/verify-setup
  5. System enables TOTP and provides backup codes

Authentication with TOTP

  1. User provides username/password via /v1/authenticate
  2. System responds with totp_required: true
  3. User provides TOTP code via /v1/totp/verify
  4. System validates and returns access token

Backup Code Usage

  1. User cannot access authenticator app
  2. User provides backup code via /v1/totp/verify-backup
  3. System validates, returns token, and marks code as used
  4. User should regenerate backup codes

Example Integration

// Setup TOTP
const setupResponse = await fetch('/v1/totp/setup', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
});

const { secret, qr_code, backup_codes } = await setupResponse.json();

// Display QR code to user
displayQRCode(qr_code);

// Verify setup
const verifyResponse = await fetch('/v1/totp/verify-setup', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    secret: secret,
    totp_code: userEnteredCode
  })
});

// Store backup codes securely
storeBackupCodes(backup_codes);

Admin Security Monitoring

// Example admin login with security monitoring
const adminLoginResponse = await fetch('/v1/authenticate/admin', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: 'admin@company.com',
    password: adminPassword
  })
});

if (!adminLoginResponse.ok) {
  // Failed admin login triggers:
  // 1. Enhanced logging with IP and user agent
  // 2. Email notification to security team
  // 3. Extended cooling-off period
  // 4. Real-time alert system activation
  
  const error = await adminLoginResponse.json();
  if (error.code === 'auth.admin_locked') {
    // Admin account is locked - security team has been notified
    showSecurityLockoutMessage();
  }
}

Rate Limiting

The API implements rate limiting per IP:

  • 1000 requests per minute per IP
  • 100 requests per minute per endpoint
  • 5 failed login attempts before cooling-off
  • Admin Protection: Failed admin login attempts trigger immediate email alerts to security teams

Rate Limit Headers

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1616876520

On this page