Authentication & Permissions
Authenticate team members, portals, apps, and agents at the gateway. This guide follows version 3.1.7 (03acdf712c).
For the user model, see Organizations, Users & Permissions.
Credential families
backend/gateway/src/middlewares/userMiddleware.ts:
- Team member:
Authorization: Bearer <token>orauth-tokencookie JWT, verified againstmodels.Usersplusredis.get(user_token_<id>_<token>). Issued by Core API login (backend/core-api/src/modules/auth/); persisted with a 24h Redis TTL viasaveValidatedToken. - Client Portal:
x-app-tokenJWT (JWT_TOKEN_SECRET) resolving tomodels.ClientPortals(req.clientPortal). A separateclient-auth-tokenheader or cookie identifies a signed-in portal user (req.cpUser). - App:
erxes-app-tokenresolving to an activemodels.Appsrecord; the gateway synthesizesreq.user = { _id: 'app:<id>' }as a machine principal. - Website check:
erxes-core-tokenpluserxes-core-website-urlverified againsterxes.io/check-websitefor limited script flows.
Tenant selection uses getSubdomain(req) (backend/erxes-api-shared/src/utils/utils.ts): the leftmost label of the forwarded or request hostname. Backend models are generated per subdomain.
Permissions
Team-member authorization uses the permissions module (backend/core-api/src/modules/permissions/, shared utils in backend/erxes-api-shared/src/core-modules/permissions/). Plugins declare meta/permissions.ts; tRPC agent tools reference those actions. Portal operations (cp*) derive the portal from context and still enforce their own filters; the prefix alone does not imply published-only or read-only behavior.
Verify
- Sign in, capture the token, and call
/graphqlwithBearer, then with a missing token to confirm rejection. - Call a portal operation with
x-app-tokenand confirm another portal's data is not visible. - Rotate
JWT_TOKEN_SECRETin staging and confirm old tokens fail.