Authentication
Every MAIA Plus call carries one of four credentials. They are issued by different mechanisms, live for different lengths of time, and are accepted on different routes. Mixing them up is the most common integration failure.
The four families
Section titled “The four families”| Family | Presentation | Lifetime | Accepted by |
|---|---|---|---|
| WebUI session | maia_webui_token cookie | 12 hours | The browser UI, and administrator routes |
| MAIA token | Authorization: Bearer, MAIA_Token header, or maia_token cookie | 8 hours | Technician Copilot, requester Copilot, ticket search |
| Webhook API key | x-api-key: whk_… | Until revoked | The target it is bound to, and nothing else |
| Secret reference | ${secret:KEY} inside configuration | — | Resolved server-side when a call is made |
A WebUI session does not open the technician Copilot, and a technician token does not open the WebUI. Those surfaces are separate by design, not by omission.
How a technician session is minted
Section titled “How a technician session is minted”Technicians never see a login form. The page script performs a silent exchange:
- It reads the
maia_auth_flagcookie. Present means a session already exists — nothing happens. - Without it, the script calls
POST /api/v1/auth/login-via-sdpon the same origin. - MAIA forward the browser’s ServiceDesk Plus cookies to SDP (
GetHeaderDetails) and reads the identity from the answer. - It resolves the SDP account and the portal of that SDP session, then issues a signed token carrying the user, the SDP user type, the account, the portal and a
jti. - The token is set as
maia_tokenfor 8 hours;maia_auth_flaglives 30 seconds less, so the UI indicator never outlives the credential it describes.
The exchange fails closed: no resolvable SDP session, no identity, or an unresolvable portal means 401 and no token.
Revocation is real, and per request
Section titled “Revocation is real, and per request”Every request re-verifies the token and asks the session store whether its jti is still active. That gives three distinct outcomes:
| What happened | Result |
|---|---|
| Token expired (8 hours) | 401 MAIA_TOKEN_INVALID |
Signed out through MAIA (POST /api/v1/auth/logout) | 401 MAIA_SESSION_REVOKED on the next call |
| Signed out of ServiceDesk Plus only | The MAIA token keeps working until it expires |
The last row matters. MAIA does not call SDP on every request, so an SDP logout does not reach the MAIA session. If you need a technician to lose access immediately, revoke the MAIA session; do not assume the SDP sign-out did it.
Roles are bound to the surface
Section titled “Roles are bound to the surface”| Surface | Required SDP user type | Checked where |
|---|---|---|
| Technician Copilot | Technician | 403 TECHNICIAN_ROLE_REQUIRED |
| Requester Copilot | Requester | 403 REQUESTER_ROLE_REQUIRED |
| Administrator routes | MAIA administrator session | requireWebUiAdmin |
The role is taken from the signed token, not from anything the caller sends. A technician cannot address the requester surface by naming a different portal; the portal is a claim in the token.
Webhook keys
Section titled “Webhook keys”A webhook key starts with whk_, is sent in the x-api-key header, and is bound to one target — plus, for models and workflows, to one model or workflow.
- Wrong target →
401 WEBHOOK_TARGET_FORBIDDEN, even if the key is valid elsewhere. - Revoked key →
401 WEBHOOK_API_KEY_INVALID. - Inactive policy →
401 WEBHOOK_POLICY_NOT_ALLOWED; agent and profile-bound flow targets recheck the policy on every delivery. - Event override attempt →
401 WEBHOOK_EVENT_OVERRIDE_FORBIDDEN; the event is part of the key, never the request.
If the x-api-key header is absent — or present but not prefixed whk_ — the request falls through to generic authentication, which is how the legacy routes keep working. That fallback is a compatibility layer, not a supported way to call a new integration.
Full procedure: Webhook keys.
Secret references
Section titled “Secret references”Configuration that needs a credential stores a reference, not the value. The syntax is ${secret:KEY}, where KEY is one of the keys the product knows about; unknown keys are rejected rather than resolved.
Resolution happens at call time on the server, so the value never reaches the browser, the workflow graph or an audit payload. See Security and secrets for where those values physically live and what a backup of them contains.
Failure behaviour
Section titled “Failure behaviour”| Symptom | Cause | Fix |
|---|---|---|
Bootstrap 401 | SDP session not forwarded, or not resolvable | Check the same-host /maia proxy, then the SDP session |
Copilot 401 MAIA_TOKEN_REQUIRED | No MAIA token at all | The page script did not run; check the Page Script rule |
Copilot 403 TECHNICIAN_ROLE_REQUIRED | Account is not an SDP technician | Use a technician account |
Administrator route 403 | Signed in, but not an administrator | Use an administrator account |
Everything 401 after a key rotation | Old value still deployed | Deploy the new value, then revoke the old key |
Related topics
Section titled “Related topics”API reference · Errors and permissions · Page scripts · Roles, portals and scope