Identifying the caller
UserMiddleware tries three sources, in order:
1
Authorization: Bearer <jwt>
The session token the web app holds. It’s verified, and the user it names is loaded.
2
The session cookie
A cookie named
user, holding the same kind of token. It’s used only outside /api/ and /admin/api/, so browser credentials can’t authenticate an API call.3
X-Api-Key
An API key replaces the user above, on
/api/* when the User API is enabled, and on /admin/api/* when the Admin API is enabled.Session tokens
Signing in returns the token in the response body and sets the cookie. The cookie is
httpOnly, SameSite=lax, and marked secure when the site is configured for HTTPS. COOKIE_PREFIX and COOKIE_DOMAIN adjust its name and scope for installations that share a domain with other applications.
API keys
Each user has one key, managed under Settings → API keys in the app. It carries the owner’s permissions, which means a key belonging to an administrator can call the Admin API when that API is enabled. The two APIs are switched on separately under Settings → Features → REST API. When an API is off, its key authentication is skipped entirely, and requests fail as unauthenticated.Workspaces
Almost everything belongs to a workspace rather than a user. After identifying the caller, the middleware resolves one:- The
X-Workspace-Idheader, when present. - Otherwise the user’s current workspace.
Authorization
Roles are deliberately coarse:
user and admin. Anything finer is a per-resource decision.
Access control classes
Presentation\AccessControls\* holds the resource rules, with a Permission enum covering the actions the application distinguishes, such as reading, editing and deleting, plus resource-specific ones.
Two conventions are worth copying into your own code:
- A resource the caller may not see is a
404, not a403, so IDs can’t be probed. - A resource that exists but is withheld by the caller’s plan is a
403, because telling them it exists is the point.
Signing in
Single sign-on ships with Google, GitHub, Facebook and LinkedIn providers, each configured in the admin panel. Captcha validation can be required on the public forms.
Bring your own keys
ByokMiddleware applies a workspace’s own provider credentials when the installation allows it. The billing service then skips credit deduction for calls made with those keys, which is why AI services always receive the model alongside the workspace.
Extending
- To protect your own endpoints, extend the base class that already carries the middleware you need. See Routes and request handlers.
- To authenticate someone who isn’t an Aikeedo user, such as a widget visitor, issue your own scoped token and verify it in your own middleware. See Public pages and endpoints.