Authentication¶
Protected endpoints require an API key:
Standard endpoints accept eitherAI_HUB_USER_API_KEY or
AI_HUB_ADMIN_API_KEY; endpoints using get_admin_api_key() accept only
AI_HUB_ADMIN_API_KEY and never accept the user key. A configured, non-empty
environment key applicable to the authentication boundary is authoritative:
any mismatch returns 403 and never falls back to MongoDB.
If every applicable variable is absent or empty and DATABASE_URL is not set,
authentication falls back to the common MongoDB APIKeys collection. The
authenticated context retains the stored key, isAdmin and clientId, while
dataSource, environment and userEmail fields are ignored. Administrator
endpoints require isAdmin: true on this fallback record.
If every applicable variable is absent or empty while DATABASE_URL is set,
authentication returns 403; there is no PostgreSQL key lookup. The configured
PostgreSQL database remains the complete runtime scope, and the obsolete
aihub_api_keys table and its application model were removed by Alembic.
Optional bearer JWT validation remains active in both database modes.
Every operation needing an administrator key lives in the Administration
application under /admin/api/v1, documented in /admin/docs. A path outside
/admin therefore never requires an administrator key.
MongoDB routes use the API key's non-empty clientId for tenant routing, with
Client-ID as a fallback, and the fixed smartmobility data source. Keys
validated from the environment have no stored clientId, so the same header
fallback remains available.
Endpoints exposing a separate legacy data_source input keep their documented
contract; no data source is read from the authentication record.
The deployment environment is resolved once when FastAPI starts. It uses the
trimmed APP_IDENTIFIER_SHORT value unless that variable is missing, empty or
equals mutu (case-insensitive); in those cases it uses the trimmed ENV
value. Startup fails when neither variable provides a value. The resolved value
is shared by the Main API and every mounted application; it is never read from
MongoDB or PostgreSQL API-key attributes.
Endpoints that expose an environment query parameter use this resolved value
when the parameter is omitted. Swagger displays it as the parameter default. A
caller may send the same value explicitly, but a different value, including an
empty string, returns 400 because one running instance cannot access another
deployment environment.
Documentation access¶
The generated Zensical site under /docs/, Swagger, ReDoc and the corresponding
OpenAPI JSON schemas are public. They do not require an API key or a browser
session. Use Authorize to provide X-API-Key before using Try it out on
a protected API operation.
Client header¶
Client-ID is never compared with the value stored on the API key. Endpoints
that need tenant routing prefer a non-empty MongoDB clientId, then fall back
to this header. Environment-backed keys always use the header fallback because
they do not contain a client identifier. If neither source provides a value,
authentication still succeeds and the resolved client identifier is None;
each endpoint decides whether it can continue without a client database.
PostgreSQL never requires this header and never uses it to select data.
The header name is Client-ID, not X-Client-ID.
Legacy-compatible routes¶
HTTP paths were preserved while routers were moved into their business
packages. The /admin segment in a historical URL therefore does not by
itself determine the required key.
The following entity-owned routes require the standard API key even though
their path still contains /admin:
/api/v1/admin/get_userand/api/v1/admin/get_team_members;/api/v1/admin/get_job;/api/v1/admin/get_opportunity.
They appear under the Users, Jobs and Opportunities Swagger categories of the
Main API. Operations that genuinely need an administrator key are served by the
Administration application under /admin/api/v1.
For backward compatibility, the following routes keep their historical public access and must not be treated as authenticated replacements:
GET /jom/admin/get_user;GET /jom/admin/get_number_of_active_users;GET /jom/admin/get_number_of_active_opportunities;POST /jom/admin/get_one_offer_scores;POST /jom/admin/get_one_user_scores;POST /jom/admin/talent_match_insights_by_id;POST /jpm/admin/get_one_user_scores.
New integrations should use the API-key-protected /api/v1/... contracts when
an equivalent exists. The public routes remain only to avoid breaking existing
clients.
Bearer JWT¶
Endpoints that enable JWT checking accept an optional bearer token:
When present, the token is validated with the public key at
JWT_PUBLIC_KEY_PATH. Only RS256 is accepted, and iat, nbf, exp and sub
claims are required. The non-empty sub claim becomes the authenticated user ID.
The validated raw bearer token can then be passed to LangGraph tools that need
downstream authorization.
An invalid or expired token returns 401. If a bearer token is supplied but the
public key is missing or unreadable, the API returns 500 because JWT validation
is not configured safely. Omitting the bearer token does not fail endpoints that
do not otherwise require a user identity.
Example:
curl 'http://localhost:8000/chatbot/api/v2/chat' \
--header 'X-API-Key: <api-key>' \
--header 'Client-ID: 725' \
--header 'Authorization: Bearer <jwt>' \
--header 'Content-Type: application/json' \
--data '{
"userApplicationId": "user-123",
"userConversationId": "conversation-123",
"messageApplicationId": "message-123",
"sender": "user",
"type": "text",
"message": "Show me relevant opportunities",
"locale": "en",
"source": "Web",
"data": {}
}'