Skip to content

Authentication and Authorization

This page documents the authentication and authorization mechanisms identified in the WhiteLotusAI REST API gateway source. It describes the JWT lifecycle, protected routes, role-based access control (RBAC), identity propagation, and outstanding security verification items.

Documentation status

Scope: Source-inspected gateway implementation
Verification: Partial; runtime and cross-service verification remain outstanding
Code changes: None made as part of this documentation review

This document is not a penetration-test report or a certification of production security.

1. Overview

WhiteLotusAI uses JSON Web Tokens (JWTs) to authenticate API requests at the REST API gateway. The gateway issues access and refresh tokens following successful authentication operations, validates access tokens on protected routes, and maintains refresh-token records in Redis.

The implementation separates authentication from authorization:

  • Authentication establishes the identity associated with a valid token.
  • Authorization determines whether the authenticated identity is permitted to perform an operation.
  • Identity propagation passes user and tenant context to downstream services, where applicable.

Important security distinction

A valid JWT does not, by itself, prove that a user is authorized to access a particular resource. Route-level permissions, ownership checks, tenant isolation, and downstream service controls must also be verified.

2. Authentication architecture

2.1 Source components

The principal gateway implementation files are:

Component Source file Responsibility
Authentication API rest_api/package/app/api/auth.py Registration, login, refresh, and logout handlers
Bearer validation rest_api/package/app/auth/auth_bearer.py HTTP bearer credentials and access-token validation
Token creation and decoding rest_api/package/app/auth/auth_handler.py JWT claims, signing, decoding, and token lifetimes
Route permissions rest_api/package/app/auth/auth_routes.py Route-to-role permission mappings
Refresh-token cache rest_api/package/app/cache/refresh_token.py Refresh-token records and cache operations
Gateway settings rest_api/package/app/settings.py Authentication-related configuration

2.2 Request and token lifecycle

The following diagram represents the documented source-level flow. It is a logical overview, not a runtime trace.

flowchart TB
    USER(["User or API Client"])

    subgraph AUTH["Authentication Operations"]
        direction TB
        LOGIN["Registration or Login"]
        USERSVC["User Service"]
        ISSUE["Issue Access and Refresh Tokens"]
        REFRESH["Refresh Token Request"]
        CACHE["Redis Refresh-Token Cache"]
    end

    subgraph PROTECTED["Protected API Requests"]
        direction TB
        REQUEST["Request with Bearer Token"]
        VALIDATE["JWTBearer Validation"]
        PERMISSION["Route Permission Check"]
        HANDLER["Route Handler"]
        DOWNSTREAM["Downstream Service"]
    end

    USER --> LOGIN
    LOGIN --> USERSVC
    USERSVC -->|"Successful response"| ISSUE
    ISSUE -->|"Tokens returned"| USER
    ISSUE --> CACHE

    USER --> REQUEST
    REQUEST --> VALIDATE
    VALIDATE -->|"Valid access token"| PERMISSION
    PERMISSION -->|"Allowed by configured policy"| HANDLER
    HANDLER --> DOWNSTREAM

    USER --> REFRESH
    REFRESH --> CACHE
    CACHE -.->|"Token lookup and rotation"| REFRESH
    REFRESH -->|"Replacement tokens, when successful"| USER

    classDef client fill:#dbeafe,stroke:#2563eb,color:#1e3a8a,stroke-width:2px
    classDef auth fill:#d1fae5,stroke:#059669,color:#064e3b,stroke-width:2px
    classDef security fill:#fef3c7,stroke:#d97706,color:#78350f,stroke-width:2px
    classDef service fill:#ede9fe,stroke:#7c3aed,color:#4c1d95,stroke-width:2px

    class USER client
    class LOGIN,USERSVC,ISSUE,REFRESH,CACHE auth
    class REQUEST,VALIDATE,PERMISSION security
    class HANDLER,DOWNSTREAM service

    style AUTH fill:transparent,stroke:#059669,stroke-width:1.5px
    style PROTECTED fill:transparent,stroke:#d97706,stroke-width:1.5px

Diagram interpretation

The flow summarizes the reported implementation. It does not establish transactionality, atomic refresh-token rotation, fail-closed authorization, or consistent enforcement across all downstream services.

3. Authentication endpoints

The authentication router is defined in rest_api/package/app/api/auth.py, with the default API prefix /api.

Method Endpoint Purpose Authentication context
POST /api/auth/register Register a user and issue tokens after success Registration flow
POST /api/auth/login Authenticate credentials and issue tokens Login flow
POST /api/auth/refresh Validate a refresh token and issue replacements Refresh-token validation
POST /api/auth/logout Delete the submitted refresh-token record Valid access token required by the route

The endpoint descriptions reflect the inspected implementation. Confirm the effective HTTP status codes and request/response schemas against the registered routes and tests.

3.1 Registration

The registration handler forwards the submitted registration details to the user service. When the service reports success, the gateway creates access and refresh tokens and returns them with the user profile.

The handler also provides responses for duplicate-email and general registration-failure cases.

Verification checklist

  • Confirm request validation and required fields.
  • Verify duplicate-account handling and appropriate HTTP status codes.
  • Confirm that tokens are issued only after successful registration.
  • Verify that sensitive registration data is not written to logs.
  • Confirm the returned user profile excludes sensitive authentication data.

3.2 Login

The login handler forwards the submitted email and password to the user service. If the service reports success, the gateway creates access and refresh tokens.

The response includes the access token, refresh token, bearer token type, and user profile.

When the user service does not report success, the handler returns an invalid-credentials message. The exact HTTP status depends on the response handling and status supplied by the service.

Credential handling

Passwords must be transmitted over appropriately secured connections and must never be logged in plaintext. Authentication errors should not reveal whether a particular account exists unless explicitly required by the approved security policy.

3.3 Refresh-token rotation

The inspected refresh handler performs the following operations:

  1. Decodes the supplied refresh token.
  2. Checks the token against the refresh-token cache.
  3. Deletes the existing refresh-token record.
  4. Retrieves the associated user through the user service.
  5. Creates replacement access and refresh tokens if the user lookup succeeds.

The handler returns 401 Unauthorized when the refresh token is invalid, expired, or absent from the cache. A separate user-not-found response is also defined.

The precise behavior for concurrent requests, Redis failures, and downstream service errors remains unverified.

Refresh rotation requires failure testing

Because the existing refresh-token record is deleted before user retrieval and replacement-token issuance, an intermediate failure may leave the client without a usable refresh token. Concurrent refresh requests may also interact with the same record. Test these cases before treating rotation as reliable or atomic.

3.4 Logout

The logout route declares JWTBearer as a dependency. It obtains the user identifier from the validated access-token payload and requests deletion of the submitted refresh-token record.

The handler returns a success message after the deletion call completes.

Logout is not necessarily access-token revocation

Deleting a refresh-token record does not automatically invalidate an already-issued access token. The inspected implementation validates access tokens independently; the effective access-token revocation behavior must be established separately.

4. JWT structure and configuration

Token creation and decoding are implemented in rest_api/package/app/auth/auth_handler.py.

Property Source-level behavior
Signing algorithm Configurable through JWT_ALGORITHM; default HS256
Signing secret Configurable through JWT_SECRET_KEY
Access-token lifetime Configurable through ACCESS_TOKEN_EXPIRE_MINUTES; default 60 minutes
Refresh-token lifetime Configurable through REFRESH_TOKEN_EXPIRE_DAYS; default 7 days
Token type claim kind, with values access or refresh
User identifier sub claim
Role Included in the access-token payload
Tenant Access-token creation defaults to DEFAULT_TENANT_ID when no tenant is supplied
Refresh-token records Redis-backed cache

Defaults are not deployment evidence

The values above describe source defaults. They do not establish which values are active in a running environment.

The inspected settings also define INTERNAL_SECRET with a development-style fallback. Production configuration must be checked to ensure that placeholder or fallback secrets cannot be used unintentionally.

4.1 Illustrative token payload

The following is a fictional, non-secret example to illustrate the documented claim names. It is not a captured token or a guarantee of the complete payload schema.

{
  "sub": "example-user-id",
  "kind": "access",
  "role": "MEMBER",
  "tenant_id": "example-tenant",
  "exp": 1790000000
}

The example includes a tenant claim for illustration. Verify the exact tenant claim name, required claims, and expiration handling against the implementation before using this example as an API contract.

Security requirements:

  • Use a securely generated signing secret and a deliberate rotation policy.
  • Explicitly allow only approved signing algorithms during token validation.
  • Validate token type, expiration, and required claims.
  • Prevent refresh tokens from being accepted as access tokens.
  • Never commit actual signing secrets or internal service credentials.
  • Keep token lifetimes consistent with the approved deployment policy.

5. Access-token validation

The JWTBearer dependency is implemented in rest_api/package/app/auth/auth_bearer.py.

The inspected dependency:

  1. Extracts HTTP bearer credentials.
  2. Rejects missing or invalid authorization headers.
  3. Decodes and validates the access token.
  4. Rejects tokens that cannot be validated as access tokens.
  5. Checks the route permission entry when a matching entry is found in AUTH_ROUTES.
  6. Attaches the decoded payload to request.credentials and request.state.credentials.

Route handlers commonly obtain the authenticated user identifier from:

request.state.credentials["sub"]

This snippet illustrates access to the decoded subject claim; it is not a standalone authentication implementation.

5.1 Expected response categories

Condition Documented behavior Verification note
Missing or invalid bearer credentials 401 Unauthorized Verify all protected routes
Invalid or expired access token 401 Unauthorized Verify expiration and token-type checks
Configured role restriction is not satisfied 403 Forbidden Verify the matching permission entry is actually applied
Permission mapping is missing or mismatched Potentially bypasses the configured role-restriction branch Requires fail-closed behavior testing

Authorization mapping is security-critical

The permission lookup depends on route tags and handler names matching AUTH_ROUTES. A missing or mismatched entry may prevent the intended role-restriction branch from executing. Do not assume every protected endpoint receives the correct authorization policy merely because JWTBearer is declared.

6. Role-based access control

The authorization table is defined in rest_api/package/app/auth/auth_routes.py.

The table supports:

  • all — any authenticated user, according to the configured mapping.
  • A list of role names, such as ["ADMIN"] — the specified roles are permitted by that mapping.

The inspected table includes ADMIN restrictions for these user-management handlers:

Handler Declared permission
list_users ADMIN
update_role ADMIN
deactivate_user ADMIN

The table also defines permissions for several profile, session, chat, RAG, and integration handlers.

6.1 Authorization decision model

flowchart TD
    A["Request with Valid Access Token"]
    B["Resolve Route Tag and Handler"]
    C{"Matching Permission Entry?"}
    D{"Role Allowed?"}
    E["Continue to Handler"]
    F["Return 403"]
    G["Review Missing Mapping"]

    A --> B --> C
    C -->|Yes| D
    C -->|No| G
    D -->|Yes| E
    D -->|No| F

    classDef input fill:#e8eaf6,stroke:#5c6bc0,color:#20243a
    classDef decision fill:#fff3e0,stroke:#ef8c22,color:#633b0b
    classDef allowed fill:#e0f2f1,stroke:#00897b,color:#173b38
    classDef denied fill:#ffebee,stroke:#d9534f,color:#6d2020
    classDef review fill:#fce4ec,stroke:#ad4775,color:#5b2340

    class A,B input
    class C,D decision
    class E allowed
    class F denied
    class G review

Required policy

A missing or unrecognized permission mapping should not silently authorize a privileged operation. The intended policy should be explicit and tested, with privileged routes failing closed when authorization configuration is incomplete.

The diagram's missing-mapping branch is a recommended review outcome, not a claim that the current implementation returns that outcome.

6.2 Route-policy verification

For each registered endpoint, confirm:

  • The route is registered under the expected prefix and router.
  • The intended authentication dependency is active.
  • The route tag and handler name match the authorization table.
  • The required roles are enforced.
  • Missing mappings are rejected or handled by an explicitly approved policy.
  • Both allowed and denied requests are covered by automated tests.

7. Protected route families

The following routers declare JWTBearer as a router-level dependency in the inspected source.

Router Source file Declared protection
Profile rest_api/package/app/api/profile.py JWTBearer
Session rest_api/package/app/api/session.py JWTBearer
Administration rest_api/package/app/api/admin.py JWTBearer
RAG rest_api/package/app/api/rag.py JWTBearer

The logout endpoint declares the dependency directly on the route. Registration, login, and refresh serve separate authentication purposes.

This inventory documents declared dependencies, not proof of effective authorization. Check the actual route registrations, permission mappings, and downstream access controls.

8. Identity, ownership, and tenant isolation

The gateway passes user identifiers to downstream services for several operations. For example, session handlers derive the user identifier from the validated JWT payload and pass it to the session service.

The RAG router derives user, role, and tenant values from the token payload, with a configured default tenant fallback.

The following controls require verification for every resource-bearing endpoint:

  • Trusted identity: derive the caller identity from validated authentication context.
  • Resource ownership: prevent access to another user's resources by changing request identifiers.
  • Tenant isolation: enforce tenant boundaries within the responsible service and data-access layer.
  • Role enforcement: apply authorization consistently across gateway and downstream operations.
  • Internal authentication: prevent unauthorized internal requests from forging or overriding trusted identity context.
  • Context integrity: ensure downstream services cannot mistake caller-controlled values for verified claims.

A gateway check is not a complete ownership guarantee

Authentication at the gateway does not establish that a downstream service enforces resource ownership or tenant isolation. Verify the complete request path, including internal service authentication and database queries.

9. Security requirements and operational guidance

The following are security requirements and verification criteria, not a declaration that all controls are implemented.

Area Required control
Secret management Supply signing and internal-service secrets through secure configuration; reject unsafe production defaults
Transport security Use appropriately secured connections for authentication and token transmission
Logging Exclude passwords, raw tokens, and provider credentials from ordinary application logs
Token validation Verify signature, approved algorithm, expiration, and token type
Token rotation Test refresh rotation under concurrent requests and dependency failures
Revocation Define and test logout, refresh-token revocation, and access-token expiry behavior
Authorization Test both allowed and denied requests for every privileged route
Ownership Verify that user identifiers cannot be manipulated to access other users' resources
Tenant isolation Verify tenant boundaries across services and persisted data
Failure handling Ensure Redis or downstream failures do not result in unintended authorization
Configuration Confirm that deployed values match the approved security policy

9.1 Example verification matrix

Use the following matrix when implementing or reviewing authentication tests.

Test scenario Expected security outcome
Protected route without a token Request rejected
Protected route with an expired token Request rejected
Refresh token submitted as an access token Request rejected
Authenticated MEMBER requests an ADMIN-only operation Request denied
Privileged route has no matching permission entry No silent authorization; fail-closed policy verified
User changes a resource ID to another user's resource Access denied unless explicitly authorized
Refresh operation fails after the old token is deleted Recovery behavior is documented and tested
Redis becomes unavailable during refresh Failure does not produce unintended access
User logs out and reuses an access token Actual revocation policy is verified
Request crosses tenant boundaries Access denied unless explicitly authorized

The table describes expected security outcomes and test cases. It is not evidence that these tests currently exist or pass.

10. Open verification findings

The following findings were recorded during source inspection. No application code was changed as part of this documentation update.

ID Finding Required follow-up
AUTH-01 The permission table is keyed by route tag and handler name. A missing match does not enter the configured role-restriction branch in JWTBearer. Compare all registered protected routes against the table and test fail-closed behavior.
AUTH-02 The inspected permission table includes profile.delete_me, but the visible profile handlers do not establish a corresponding registered route. Reconcile the permission table with the complete registered route inventory.
AUTH-03 The session router defines a rename handler, but the inspected permission table does not list rename_session. Verify effective route dependencies and the intended policy.
AUTH-04 The RAG router defines publish_document, but the inspected permission table does not list that handler. Verify route registration and the intended policy.
AUTH-05 The default signing-secret value is a placeholder. Confirm deployed configuration overrides the placeholder and uses secure secret management.
AUTH-06 Logout deletes a refresh-token record, while access tokens are validated independently. Define and verify the intended access-token revocation model.
AUTH-07 Refresh-token rotation deletes the existing record before retrieving the user and issuing replacement tokens. Test concurrent refresh requests, service failures, and recovery behavior.
AUTH-08 Full authentication and ownership enforcement across internal services has not been independently verified. Review internal request authentication, ownership checks, and tenant isolation.

Finding classification

These items are source-review findings and verification gaps. They do not establish that an exploit has been demonstrated, that a runtime failure has been reproduced, or that a remediation has been deployed.

The following is a suggested prioritization for engineering review, not a statement of confirmed exploitability.

  1. Authorization enforcement: reconcile route registrations and permission mappings; verify fail-closed behavior for privileged operations.
  2. Secret configuration: prevent unsafe signing-secret and internal-secret defaults from reaching production.
  3. Identity and tenant boundaries: verify ownership checks and internal-service authentication across the request path.
  4. Refresh-token lifecycle: test rotation, concurrency, cache failures, and recovery.
  5. Logout semantics: document the actual access-token revocation policy.
  6. Regression coverage: add automated positive and negative tests for all authentication and authorization boundaries.

11. Source references

The primary files used for this documentation are listed below.

Area Files
Authentication routes rest_api/package/app/api/auth.py
Protected routers rest_api/package/app/api/profile.py, rest_api/package/app/api/session.py, rest_api/package/app/api/admin.py, rest_api/package/app/api/rag.py
Token validation rest_api/package/app/auth/auth_bearer.py
Token creation and decoding rest_api/package/app/auth/auth_handler.py
Authorization mappings rest_api/package/app/auth/auth_routes.py
Refresh-token cache rest_api/package/app/cache/refresh_token.py
Configuration rest_api/package/app/settings.py

These paths identify the inspected source locations. Confirm them against the current application checkout when implementation details change.

12. Verification status and maintenance

This page describes authentication mechanisms identified in the inspected source snapshot and lists areas that require further verification.

It is not a complete authentication contract, a penetration-test report, or proof of production security.

Update this document only when changes are supported by source review, automated test results, or reproducible runtime evidence.

Before marking a finding resolved, record:

  • The code change or control that addresses the finding.
  • The relevant automated test or reproducible verification evidence.
  • The affected routes and downstream services.
  • Any remaining limitations or deployment-specific requirements.

Document scope: WhiteLotusAI REST API gateway authentication and authorization.