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:
- Decodes the supplied refresh token.
- Checks the token against the refresh-token cache.
- Deletes the existing refresh-token record.
- Retrieves the associated user through the user service.
- 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:
- Extracts HTTP bearer credentials.
- Rejects missing or invalid authorization headers.
- Decodes and validates the access token.
- Rejects tokens that cannot be validated as access tokens.
- Checks the route permission entry when a matching entry is found in
AUTH_ROUTES. - Attaches the decoded payload to
request.credentialsandrequest.state.credentials.
Route handlers commonly obtain the authenticated user identifier from:
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.
10.1 Recommended remediation order¶
The following is a suggested prioritization for engineering review, not a statement of confirmed exploitability.
- Authorization enforcement: reconcile route registrations and permission mappings; verify fail-closed behavior for privileged operations.
- Secret configuration: prevent unsafe signing-secret and internal-secret defaults from reaching production.
- Identity and tenant boundaries: verify ownership checks and internal-service authentication across the request path.
- Refresh-token lifecycle: test rotation, concurrency, cache failures, and recovery.
- Logout semantics: document the actual access-token revocation policy.
- 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.