What this is about
Every request to CDMS first goes through the filter chain of CIAS. The filter chain is a piece of code in front of the endpoints. It reads the token from the header Authorization: Bearer <token>, checks its signature and validity, and determines who is asking and in which tenant.
The stations
-
Filter chainRead tokenIs there a token in the header
Authorization?↳ no 403, without a CDMS error body -
Filter chainCheck tokenIs the signature genuine, the token not expired, from the configured issuer, an access token and issued for this application?↳ no 401 with
WWW-Authenticate: Bearer error="invalid_token" -
CIASTenantCan the tenant be determined, and is it served here?↳ no 403, in the field
errore.g.cias.authentication.tenant-unresolved -
CDMSRoleDoes the operation require a role, and does the person have it?↳ no 403
missing-permission|<role> - CDMS runs the request, with the filters of the row level
What the filter chain does in detail is described in What happens with the token on every request.
Decision table
| Token | Path | Role required | Answer |
|---|---|---|---|
| none | endpoint of a model | – | 403 from the filter chain |
| invalid, expired, signed by someone else or for another client | any | – | 401 invalid_token |
| none | open path, e.g. the public registration | – | 200 |
| none | /v3/api-docs, /swagger-ui | – | 401, asks for user name and password |
| valid | endpoint of a model | yes, but not in the token | 403 missing-permission|<role> |
| valid | endpoint of a model | no (publicAccess) | allowed, for any signed-in person |
Variants
When: The request has no header Authorization.
The filter chain knows no person. It answers 403 for every endpoint of a model. The body is not a CDMS error response, so there is no messageKey.
Result: The client has to sign in first.
When: The token is expired, broken, signed with someone else's key, from another issuer, an ID token, or issued for another client.
The filter chain checks the signature against the keys of the realm, the expiry date, the issuer, the type and whether the token names the application's client. If a check fails, it answers 401 with the header WWW-Authenticate: Bearer error="invalid_token". This also applies to open paths: an invalid token is never treated as "no token". See What happens to the token on every request.
Result: The client renews the token and repeats the request. See Renew the token.
When: Paths that can be reached without a token
Reachable without a token are OPTIONS requests that the browser sends before a request to another address, and paths a module explicitly publishes, such as the public registration. The API description under /v3/api-docs and the Swagger UI under /swagger-ui need no token, but a login of their own with a user name and password that the operator issues. Without configured credentials they answer 401. Health and metrics live on a port of their own that is not reachable from outside.
Result: No endpoint of a model can be reached without a token.
When: The model file has publicAccess: true on the endpoint.
CDMS requires no role for this operation. The token is still needed: the filter chain runs first. Any person with a valid token may run the operation, and the filters of the row level still apply.
Result: "Public" here means: for any signed-in person. See Model roles.
When: GET /{id}/file?access_token=<token>
A browser cannot send a header with a link. That is why the download takes the token as a parameter in the URL. It is checked exactly like in the header: invalid → 401, tenant not permitted → 403, then read and download role.
Result: See Downloading.
Pitfalls
Where to go next
- Which role an operation requires: Model roles
- The levels after the token: The three levels at a glance