Introduction to Authentication & Authorization
Authorization in Platformatic DB is role-based (see Roles And User Information for further details).
A user is supposed to have a list of roles associated.
Platformatic delegates authentication and assignment of the roles
to an external authentication service.
The job of the authentication service is to authenticate users and assign their roles correctly.
Supported authentication service integrations are:
- JWT
- Webhook
We refer to the user roles and other informations (like userId
) as User Metadata.
To make testing and developing easier, it's possible to bypass these checks if a adminSecret
is set. See HTTP Headers.
JWT
JWT is built on top of fastify-jwt.
To configure it, the quickest way is to pass a shared secret
, e.g.:
"authorization": {
...
"jwt": {
"secret": "<shared-secret>"
},
...
}
For more complex configurations, please check fastify-jwt options.
JWKS
Platformatic DB supports JWKS. To configure it:
...
"authorization": {
"jwt": {
"jwks": {
"allowedDomains": [
"https://ISSUER_DOMAIN"
]
}
},
}
...
More get-jwks options can be specified.
When a JWT token is received, Platformatic DB gets the correct public key from https:/ISSUER_DOMAIN/.well-known/jwks.json
and uses it to verify the JWT signature. The token carries all the informations, like the kid
, which is the key id used to sign the token itself, so no other configurations are strictly necessary.
It's also possible to enable JWKS with no options:
...
"authorization": {
"jwt": {
"jwks": true
}
},
}
...
In this case, the JWKS URL is calculated from the iss
(issuer) field of JWT, so every JWT token from an issuer that exposes a valid JWKS token will pass the validation. For that reason, this configuration should be used only for development, while in every other case the allowedDomains
should be specified.
Webhook
Platformatic can use a webhook to authenticate the requests.
In this case, the URL is configured on authorization:
"authorization": {
...
"webhook": {
"url": "<webhook url>"
},
...
}
When a request is received, Platformatic sends a POST
to the webhook, replicating the same body and headers, except for:
host
connection
In the Webhook case, the HTTP response contains the roles/user information as HTTP headers.
JWT and Webhook
It's possible to configure the server to first try to validate a JWT token and if that is not found, forward the request to the webhook.
HTTP Headers
Note that using admin API key on HTTP headers is highly insecure and should be used only within protected networks.
If a request has X-PLATFORMATIC-ADMIN-SECRET
HTTP header set with a valid adminSecret
(see configuration reference]) the role is set automatically as platformatic-admin
, unless a different role is set for user impersonation (which is disabled if JWT or Webhook are set, see below).
Also, the following rule is automatically added to every entity, allowing the user that presented the adminSecret
to perform any operation on any entity:
{
"role": "platformatic-admin",
"find": false,
"delete": false,
"save": false
}
User Impersonation
When JWT or Webhook are set, user impersonation is not enabled, and the role is always set as platfomatic-admin
automatically.
If a user presents a valid X-PLATFORMATIC-ADMIN-SECRET
, can also impersonate users with different roles.
The roles to impersonate can be specified by X-PLATFORMATIC-ROLE
containing a comma separated list of roles.
User Metadata
In all cases, the roles/user information is passed to Platformatic from the external authentication service as a string (JWT claims or HTTP headers).
We can refer to these as user metadata. Platformatic saves the user metadata for each request in a user
object.
Roles can be set using X-PLATFORMATIC-ROLE
as list of comma-separated roles (this key is configurable).
Note that roles are just strings. Some "special roles" are reserved:
platformatic-admin
: this identifies a user who has admin powersanonymous
: set automatically when no roles are associated
Events and Subscriptions
Platformatic DB supports GraphQL subscriptions and therefore db-authorization must protect them.
The check is performed based on the find
permissions, the only permissions that are supported are:
find: false
, the subscription for that role is disabledfind: { checks: { [prop]: 'X-PLATFORMATIC-PROP' } }
validates that the given prop is equalfind: { checks: { [prop]: { eq: 'X-PLATFORMATIC-PROP' } } }
validates that the given prop is equal
Conflicting rules across roles for different equality checks will not be supported.
Programmatically skip authorization rules
In custom plugins, it's possible to skip the authorization rules on entities programmatically by setting the skipAuth
flag to true
, e.g.:
// this works even if the user's role doesn't have the `find` permission
const res = await app.platformatic.entities.page.find({skipAuth: true})
This is useful for custom plugins for which the authentication is not necessary, so there is no user role set when invoked.
Skip authorization rules is not possible on the automatically generated REST and GraphQL APIs.