Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / API reference

Reference

Authentication and headers

Credentials, cookies, tenant selection, language, deactivation, and audit headers that Cluster ERP API clients send and receive, at mechanism level.

This page lists the credentials and HTTP headers that the Cluster ERP API reads and writes, at the level a client developer needs to call it. It covers tenant users, the operator console, and the token-based supplier portal and signup routes. The design of sessions and tokens is explained in Authentication and sessions; this page does not repeat it and does not describe internal checks beyond their results.

Credentials

Credential Carried in Used by Source
Access token Authorization: Bearer header desktop client and scripts; every route that depends on get_current_user or require_permission src/cluster_erp/modules/auth/session_cookies.py:63-75
Access cookie HttpOnly cookie cluster_access, with the __Host- prefix over TLS web client after a cookie-transport sign-in src/cluster_erp/modules/auth/session_cookies.py:35, src/cluster_erp/modules/auth/session_cookies.py:51-55
Refresh token JSON body of POST /api/v1/auth/refresh desktop client and scripts src/cluster_erp/modules/auth/login/schemas.py:41-44
Refresh cookie HttpOnly cookie cluster_refresh, path /api/v1/auth web client src/cluster_erp/modules/auth/session_cookies.py:36-39, src/cluster_erp/modules/auth/session_cookies.py:145-153
Operator token Authorization: Bearer header on /api/v1/vendor/* operator console; separate from tenant tokens src/cluster_erp/server/routes/vendor.py:84-95
Portal token path segment {token} supplier portal routes under /api/v1/procurement/portal/rfqs/ src/cluster_erp/modules/procurement/purchase_rfqs/portal_routes.py:34-64
Signup token JSON body field signup_token or verify_token signup status, resend, cancel, and verify src/cluster_erp/server/routes/signup.py:102-112

A well-formed Bearer header wins over the access cookie; a Bearer value of null or undefined is ignored (src/cluster_erp/modules/auth/session_cookies.py:63-75).

Sign-in and token refresh

The sequence shows the tenant user flow at mechanism level. The web client asks for the cookie transport; the desktop client and scripts use the body transport.

sequenceDiagram
 participant Client
 participant Login as POST /auth/login
 participant Refresh as POST /auth/refresh
 participant Route as Protected route
 Client->>Login: LoginRequest, optional X-Token-Transport cookie
 Login-->>Client: LoginResponse with tokens, or empty tokens and Set-Cookie
 Client->>Route: Bearer header or access cookie
 Route-->>Client: 200, or 401 AUTH_TOKEN_EXPIRED
 Client->>Refresh: refresh token in body or refresh cookie
 Refresh-->>Client: new access and refresh token pair
 Client->>Route: retry with the new access token
Step Behaviour Source
Sign-in request LoginRequest carries username, password, and remember_me. src/cluster_erp/modules/auth/login/schemas.py:8-13
Failed sign-in Answers 401 with AUTH_INVALID_CREDENTIALS. Repeated failures lock the account for a period, and a per-client attempt budget answers 429 with AUTH_TOO_MANY_ATTEMPTS. src/cluster_erp/modules/auth/login/routes.py:71-97, src/cluster_erp/modules/auth/login/routes.py:136-180
Sign-in response LoginResponse carries access_token, refresh_token, token_type, user, and permissions. With the cookie transport the two token fields are empty strings and the tokens are set as cookies. src/cluster_erp/modules/auth/login/schemas.py:16-21, src/cluster_erp/modules/auth/login/routes.py:214-257
Session length Without remember_me, a cookie-transport session gets session cookies and a session end of jwt_session_hours. src/cluster_erp/modules/auth/login/routes.py:219-226, src/cluster_erp/modules/auth/session_cookies.py:124-153
Refresh The presented refresh token is spent and a new pair is issued; the response mirrors the transport of the request. src/cluster_erp/modules/auth/login/routes.py:260-370
Sign-out POST /api/v1/auth/logout revokes the presented tokens, stamps last_logout_at, clears the cookies, and answers 204. src/cluster_erp/modules/auth/login/routes.py:373-432
Current user GET /api/v1/auth/me returns MeResponse with user and permissions. src/cluster_erp/modules/auth/login/routes.py:434-459

Token lifetimes come from the settings jwt_access_expire_minutes, jwt_refresh_expire_days, and jwt_session_hours (src/cluster_erp/config/settings.py:307-312). The values are described in Settings reference.

Request headers

Header Purpose When required Source
Authorization Bearer access token, or operator token on /api/v1/vendor/* every protected route when no access cookie is sent src/cluster_erp/modules/auth/session_cookies.py:63-75
Cookie access and refresh cookies of the web client cookie transport src/cluster_erp/modules/auth/session_cookies.py:63-84
X-Token-Transport value cookie asks sign-in to set cookies instead of returning tokens sign-in from a browser src/cluster_erp/modules/auth/session_cookies.py:31-43
X-Requested-With must equal CSRF_VALUE on every cookie-authenticated request whose method is not GET, HEAD, or OPTIONS; otherwise 403 AUTH_CSRF_HEADER_MISSING cookie transport writes and refresh src/cluster_erp/modules/auth/session_cookies.py:33-34, src/cluster_erp/modules/auth/session_cookies.py:112-121
X-Tenant-Domain the sign-in mail domain, used to route a request to its tenant when no signed token carries a tenant claim multi-tenant mode, before sign-in src/cluster_erp/server/dependencies.py:138-148
Accept-Language the first two letters select the language of label texts; default en optional; read by 49 dependency uses of get_language src/cluster_erp/server/dependencies.py:247-249
X-Deact-Reason, X-Deact-Note URL-encoded reason and note stamped onto a record that a DELETE deactivates optional on deactivation requests src/cluster_erp/server/dependencies.py:63-72
X-Session-Id, X-Correlation-Id written into the database session settings for audit; a correlation id is generated when absent optional src/cluster_erp/server/dependencies.py:34-63
If-None-Match revalidation of GET /api/v1/_meta; a match answers 304 optional src/cluster_erp/server/app.py:1553-1555
Accept-Encoding gzip selects the pre-compressed metadata body optional src/cluster_erp/server/app.py:1544-1552
Content-Length compared with max_request_body_bytes; a larger value answers 413 every request with a body src/cluster_erp/server/app.py:1396-1411
Origin cross-origin access is granted only to configured console origins and only on /api/v1/vendor/fleet operator console in a browser src/cluster_erp/server/app.py:1362-1388

Response headers

Header When Source
Set-Cookie sign-in and refresh with the cookie transport; deletion on sign-out src/cluster_erp/modules/auth/session_cookies.py:124-158
ETag, Cache-Control: private, no-cache, Vary GET /api/v1/_meta src/cluster_erp/server/app.py:1546-1556
Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy every response src/cluster_erp/server/app.py:1412-1421
Strict-Transport-Security responses to HTTPS requests src/cluster_erp/server/app.py:1426-1429
Retry-After: 2 an unhandled-error response with status 503 src/cluster_erp/server/error_handler.py:309
Access-Control-Allow-Origin and related /api/v1/vendor/fleet for a configured console origin src/cluster_erp/server/app.py:1365-1388

Tenant selection

When multi_tenant is off, every request uses the process database (src/cluster_erp/server/dependencies.py:117-118). When it is on, get_db_session resolves the tenant from the signed tenant claim of the presented token, then from the X-Tenant-Domain header. A request that resolves to no active tenant gets one generic 401 with AUTH_TENANT_UNRESOLVED (src/cluster_erp/server/dependencies.py:104-157). The model is explained in Multi-tenancy.

Permission checks

require_permission(*codes) is a dependency that resolves the user and requires every listed code; a missing code answers 403 with AUTH_PERMISSION_DENIED and details.required_permission (src/cluster_erp/modules/auth/guards.py:205-240, src/cluster_erp/core/errors.py:388-394). For each code it also evaluates the attribute policies configured for that code. Codes listed in the setting abac_strict_permission_codes are denied when no policy exists (src/cluster_erp/modules/auth/guards.py:216-235, src/cluster_erp/config/settings.py:341). Some routes check the signed-in user inside the handler instead, with get_current_user; the module pages name the guard of every route. Roles and policies are explained in Roles and permissions and ABAC policies.

Terms introduced

Term Code identifier Definition Turkish term Source
cookie transport TRANSPORT_COOKIE The web sign-in mode in which the tokens travel only as HttpOnly cookies instead of in the response body. çerez taşıması src/cluster_erp/modules/auth/session_cookies.py:31-32
operator token require_operator The Bearer token of an operator console account, read only by the /api/v1/vendor routes. operatör belirteci src/cluster_erp/server/routes/vendor.py:84-95
portal token token The path segment that identifies a supplier's RFQ invitation on the supplier portal routes. portal belirteci src/cluster_erp/modules/procurement/purchase_rfqs/portal_routes.py:34

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13