Introduction
API-Key Keys are randomly generated string strings you can use to authenticate and authorize requests. They are essentially designed for Machine to Machine communication and don’t rely on session or interactive mechanisms such as login and password prompt, but can also be used to grant temporary access to resources thanks to the built in expiration (see the fully qualified link documentation).
Note |
---|
An API-Key is a plain text token which grants privileges, therefore it must be considered as a secret and not exposed to your end-user if you don’t want to grant these privileges to your users. |
An API-Key is bound to a given user, who is then responsible of all the actions performed by his tokens.
However the API-Keys have their own roles definition, making it possible to create multiple tokens with different scopes:
In this example, a single user possesses 3 tokens, each with different role scopes.
Note that to avoid privilege escalation, a user cannot have API-Keys with broader role than his own role definition - in the example the user has the 2 roles on all inboxes, so it’s allowed to create tokens on specific inboxes.
Usage
Creation and usage of API-Keys is fairly simple, although extra attention needs to be taken when setting up the correct roles and permissions. The next sections will walk you through the creation process and how to use an API-Key to make authenticated calls to our API.
Info |
---|
The API calls example below hide the Authorization header, but all calls are made on endpoints requiring proper authentication and authorization to manage users, roles and api-keys. You can use the interactive Swagger UI to make the calls below after login with your user and password. |
Use your own tenant URL: in the example below we’ll use the alfredo organization on Q.
Creation
Before creating an API-Key, you must properly set up the roles and users in your tenant:
Roles
...
and permissions
The roles list is passed at API-Key creation and cannot be modified after: a token permissions roles are immutable.
Note |
---|
Do not bind your API-Key to admin roles if you expose your token to the end user: otherwise they will be able to perform admin operations themselves! Reserve admin level tokens to machine to machine communication, ie. your back-end communicates directly to ours. |
The roles can be managed via the UI or via the API using the /roles endpoints.
Code Block |
---|
curl --request GET |
...
--url https://alfredo.contract-q.fit/admin/roles |
Let’s take the Operator role from the roles list and write down its id:
...
Info |
---|
Your role “id” attribute will not be same, use your own! |
Each API endpoint in the Swagger should tell you the required permission to use it:
...
You can alter role to add or remove permissions, depending on your intention. Keep in mind you should grant only the required permissions for your application, and not grant all permissions.
You must use the same roles for the API-Key and the matching user: you can’t use different ones even if they have the same permissions
User
Each API-Key is explicitly bound to a user at creation and any action done with this token will appear as made by this user. It must be an already existing user and have at least the permissions roles you want to give to the token (ie no privilege escalation - a user can’t have a token with higher privileges than the ones he has).
Given my “Operator” role, I should create (one time only) a dedicated user for my operator tokens:
Code Block |
---|
curl --request POST \
--url https://alfredo.contract-q.fit/admin/users \
--header 'Content-Type: application/json' \
--data '{
"username": "demo",
"active": true,
"password": "largerandomandsafepasswordnotlikethisone",
"roles": [
{"role": "5e429c7f4657cc2eaf0e7d4f"}
]
}' |
This demo user has the Operator role on all inboxes: we will be able to create API-Keys with the Operator role on specific inboxes, or on all inboxes (higher or equal permissions). Write down its ID, we’ll use it later:
Code Block |
---|
{
"username": "demo",
"roles": [
{
"role": "5e429c7f4657cc2eaf0e7d4f"
}
],
"active": true,
"id": "61e9790f2b0c965851c3cd6d",
"confirmed_at": null
} |
API-Key
The API-Key itself can only be created using the API using the /auth/api-keys endpoints, it is not yet available in the UI.
Code Block |
---|
curl --request GET |
...
--url https://alfredo.contract-q.fit/admin/auth/api-key |
Each API-Key has the following attributes you can set:
Auto expiration date
Can be short lived or even disabled, ie non expiring
Enable / disable Active flag to temporary disable the token
Roles list - NOT update-able
Each element has a Role ID (you can get this from the /roles endpoint)
an inbox scope if applicable, to restrict to an inbox
a document_id scope if applicable, to restrict to an inbox
...
You will get back the randomly generated token back - keep it secret!
Code Block |
---|
{
"token": "XXX",
"user": "61e9790f2b0c965851c3cd6d",
"active": true,
"expire_at": "2022-03-20T00:00:00+00:00",
"roles": [
{
"role": "5e429c7f4657cc2eaf0e7d4f"
}
]
} |
Make requests
The API-Key can be passed in 2 different ways:
HTTP Header
The recommended and simplest way is to pass the token in the X-API-KEY HTTP header with each of your requests:
Code Block |
---|
curl --request GET \ --url https://alfredo.contract-q.fit/admin/inboxes \ --header 'X-API-KEY: XXX' |
Query string
You could also pass the token in the query string, although it is not recommended:
Code Block |
---|
curl --request GET --url 'https://alfredo.contract-q.fit/admin/inboxes?api_key=XXX' |
Revocation
You can temporary disable an API-Key using the PATCH endpoint:
Code Block |
---|
curl --request PATCH \
--url https://alfredo.contract-q.fit/admin/auth/api-key/XXX \
--header 'Content-Type: application/json' \
--data '{
"active": false
}' |
The requests made using the API-Key will now be denied until active is reset to true.
You can permanently revoke the API-Key by deleting it - warning: this cannot be undone.
Code Block |
---|
curl --request DELETE --url https://alfredo.contract-q.fit/admin/auth/api-key/XXX |
The API-Key will be removed and cannot be recovered ; since it is randomly generated you won’t get the same token again.