Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: unify API Auth docs (Admin, Camunda 8, and Web Modeler APIs) #4078

Merged
merged 22 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
78db6ec
feat: unify API authentication docs (administration/next)
pepopowitz Jul 23, 2024
1bce3b4
feat: unify API authentication docs (modeler/next)
pepopowitz Jul 25, 2024
2f6e2bd
feat: unify API authentication docs (camunda/next)
pepopowitz Jul 26, 2024
fef25d0
feat: rewrite saas curl requests for readability and flexibility
pepopowitz Aug 8, 2024
f123e72
oops: import dependencies
pepopowitz Aug 8, 2024
9f74a7a
chore: consistent format for substitution values
pepopowitz Aug 9, 2024
55eb693
Merge branch 'main' into pepopowitz/3649-unify-api-auth-docs
pepopowitz Aug 9, 2024
d1f2a3b
Update Camunda API client creation instructions
pepopowitz Aug 9, 2024
a079315
improve: use actual environment variable names as downloaded from con…
pepopowitz Aug 9, 2024
316beeb
improve: use actual environment variable names as downloaded from con…
pepopowitz Aug 9, 2024
d43ee03
improve: use actual environment variable names as downloaded from con…
pepopowitz Aug 9, 2024
1a2b822
improve: better explanation of target URLs (c8 api)
pepopowitz Aug 12, 2024
6e601d3
improve: better explanation of target URLs (web modeler)
pepopowitz Aug 12, 2024
cd70c06
improve: no need for variable indirection (admin)
pepopowitz Aug 12, 2024
3299555
docs: use instead of for variables, for readability.
pepopowitz Aug 12, 2024
ecd3db6
no port number here
pepopowitz Aug 12, 2024
831074e
feedback: incorporate edits from Operate PR
pepopowitz Aug 22, 2024
ec449ec
edit: one more active voice thing
pepopowitz Aug 22, 2024
d74d1df
feedback: sync tab sections to each other
pepopowitz Aug 22, 2024
c0051fd
chore: backport admin API changes from vNext to vCurrent
pepopowitz Aug 23, 2024
7bbf5e0
chore: backport web modeler API changes from vNext to vCurrent
pepopowitz Aug 23, 2024
1e39ced
Merge branch 'main' into pepopowitz/3649-unify-api-auth-docs
pepopowitz Aug 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 62 additions & 26 deletions docs/apis-tools/administration-api/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,72 @@ sidebar_position: 2
description: "Learn about access tokens and client credentials and scopes to get started with the Administration API."
---

To access the API endpoint, you need an access token. Your client must send a header in each request:

`Authorization: Bearer <Token>`

For example, send a request using _curl_:
All Administration API requests require authentication. To authenticate, generate a [JSON Web Token (JWT)](https://jwt.io/introduction/) and pass it in each request.

## Generating a token

1. Create client credentials by clicking **Console > Organization > Administration API > Create new credentials**.
2. Add permissions to this client for [the needed scopes](#client-credentials-and-scopes).
3. Upon creating the client, capture the following values required to generate a token:
<!-- this comment convinces the markdown processor to still treat the table as a table, but without adding surrounding paragraphs. 🤷 -->
| Name | Environment variable name | Default value |
| ------------------------ | -------------------------------- | -------------------------------------------- |
| Client ID | `CAMUNDA_CONSOLE_CLIENT_ID` | - |
| Client Secret | `CAMUNDA_CONSOLE_CLIENT_SECRET` | - |
| Authorization Server URL | `CAMUNDA_OAUTH_URL` | `https://login.cloud.camunda.io/oauth/token` |
| Audience | `CAMUNDA_CONSOLE_OAUTH_AUDIENCE` | `api.cloud.camunda.io` |
<!-- this comment convinces the markdown processor to still treat the table as a table, but without adding surrounding paragraphs. 🤷 -->
:::tip
When client credentials are created, the `Client Secret` is only shown once. Save this `Client Secret` somewhere safe.
:::
4. Execute an authentication request to the token issuer:
```bash
curl --request POST ${CAMUNDA_OAUTH_URL} \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode "audience=${CAMUNDA_CONSOLE_OAUTH_AUDIENCE}" \
--data-urlencode "client_id=${CAMUNDA_CONSOLE_CLIENT_ID}" \
--data-urlencode "client_secret=${CAMUNDA_CONSOLE_CLIENT_SECRET}"
```
5. A successful authentication response looks like the following:
```json
{
"access_token": "<TOKEN>",
"expires_in": 300,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0
}
```
6. Capture the value of the `access_token` property and store it as your token.

## Using a token

Include the captured token as an authorization header in each request: `Authorization: Bearer <TOKEN>`.

For example, to call the Administration API's `/members` endpoint, send the following request:

```shell
curl -X POST -H -H :accept: application/json" -H "Authorization: Bearer <TOKEN>" -d '' http://api.cloud.camunda.io/clusters
curl --header "Authorization: Bearer ${TOKEN}" \
https://api.cloud.camunda.io/members
```

A successful response would include [a list of organization members](https://console.cloud.camunda.io/customer-api/openapi/docs/#/default/GetMembers). For example:

```json
[
{
"name": "User Userton",
"email": "[email protected]",
"roles": ["admin"],
"invitePending": false
}
]
```

For all requests, include the access token in the authorization header: `authorization:Bearer ${TOKEN}`.
## Token expiration

Access tokens expire according to the `expires_in` property of a successful authentication response. After this duration, in seconds, you must request a new access token.

## Client credentials and scopes

Expand All @@ -40,25 +95,6 @@ A client can have one or multiple permissions from the following groups:

The full API description can be found [here](https://console.cloud.camunda.io/customer-api/openapi/docs/#/).

:::note
After client credentials are created, the `Client Secret` is only shown once. Save this `Client Secret` somewhere safe.
:::

## Access token

Once you have your client credentials, you can retrieve an access token using the following command:

```bash
curl --header "Content-Type: application/json" \
--request POST \
--data '{"grant_type":"client_credentials", "audience":"api.cloud.camunda.io", "client_id":"XXX", "client_secret":"YYY"}' \
https://login.cloud.camunda.io/oauth/token
```

:::note
Access tokens have a validity period found in the access token. After this time, a new access token must be requested.
:::

## Rate limiting

The OAuth service rate limits about one request per second for all clients with the same source IP address.
Expand Down
166 changes: 123 additions & 43 deletions docs/apis-tools/camunda-api-rest/camunda-api-rest-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,137 @@ title: "Authentication"
description: "Step through authentication options that can be used to access Camunda 8 REST API."
---

To access the API endpoint, you need an access token.

Your client must send a header in each request:

`Authorization: Bearer <Token>`

For example, send a request using _curl_:
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

All Camunda 8 REST API requests require authentication. To authenticate, generate a [JSON Web Token (JWT)](https://jwt.io/introduction/) depending on your environment and pass it in each request.

## Generating a token

<Tabs groupId="environment" defaultValue="saas" queryString values={
[
{label: 'SaaS', value: 'saas' },
{label: 'Self-Managed', value: 'self-managed' },
]}>

<TabItem value='saas'>

1. [Create client credentials](/guides/setup-client-connection-credentials.md) in the **Clusters > Cluster name > API** tab of [Camunda Console](https://console.camunda.io/).
2. Add permissions to this client for **Zeebe**.
3. Upon creating the client, capture the following values required to generate a token:
<!-- this comment convinces the markdown processor to still treat the table as a table, but without adding surrounding paragraphs. 🤷 -->
| Name | Environment variable name | Default value |
| ------------------------ | -------------------------------- | -------------------------------------------- |
| Client ID | `ZEEBE_CLIENT_ID` | - |
| Client Secret | `ZEEBE_CLIENT_SECRET` | - |
| Authorization Server URL | `ZEEBE_AUTHORIZATION_SERVER_URL` | `https://login.cloud.camunda.io/oauth/token` |
| Audience | `ZEEBE_TOKEN_AUDIENCE` | `zeebe.camunda.io` |
| Zeebe REST Address | `ZEEBE_REST_ADDRESS` | - |
<!-- this comment convinces the markdown processor to still treat the table as a table, but without adding surrounding paragraphs. 🤷 -->
:::tip
When client credentials are created, the `Client Secret` is only shown once. Save this `Client Secret` somewhere safe.
:::
4. Execute an authentication request to the token issuer:
```bash
curl --request POST ${ZEEBE_AUTHORIZATION_SERVER_URL} \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode "audience=${ZEEBE_TOKEN_AUDIENCE}" \
--data-urlencode "client_id=${ZEEBE_CLIENT_ID}" \
--data-urlencode "client_secret=${ZEEBE_CLIENT_SECRET}"
```
5. A successful authentication response looks like the following:
```json
{
"access_token": "<TOKEN>",
"expires_in": 300,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0
}
```
6. Capture the value of the `access_token` property and store it as your token.

</TabItem>

<TabItem value='self-managed'>

1. [Add an M2M application in Identity](/self-managed/identity/user-guide/additional-features/incorporate-applications.md).
2. [Add permissions to this application](/self-managed/identity/user-guide/additional-features/incorporate-applications.md) for **Camunda 8 REST API**.
3. Capture the `Client ID` and `Client Secret` from the application in Identity.
4. [Generate a token](/self-managed/identity/user-guide/authorizations/generating-m2m-tokens.md) to access the REST API. Provide the `client_id` and `client_secret` from the values you previously captured in Identity.
```shell
curl --location --request POST 'http://localhost:18080/auth/realms/camunda-platform/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "client_id=${CLIENT_ID}" \
--data-urlencode "client_secret=${CLIENT_SECRET}" \
--data-urlencode 'grant_type=client_credentials'
```
5. A successful authentication response looks like the following:
```json
{
"access_token": "<TOKEN>",
"expires_in": 300,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0
}
```
6. Capture the value of the `access_token` property and store it as your token.

</TabItem>

</Tabs>

## Using a token

Include the captured token as an authorization header in each request: `Authorization: Bearer <TOKEN>`.

For example, to call the Camunda 8 REST API's `/topology` endpoint, send the following request against the target environment:

<Tabs groupId="environment" defaultValue="saas" queryString values={
[
{label: 'SaaS', value: 'saas' },
{label: 'Self-Managed', value: 'self-managed' },
]}>

<TabItem value='saas'>

:::tip
The `${ZEEBE_REST_ADDRESS}` variable below represents the URL of the Camunda 8 REST API. You can capture this URL when creating an API client. You can also construct it as `https://${REGION}.zeebe.camunda.io/${CLUSTER_ID}/`.
:::

</TabItem>

<TabItem value='self-managed'>

:::tip
The `${ZEEBE_REST_ADDRESS}` variable below represents the URL of the Camunda 8 REST API. You can configure this value in your Self-Managed installation. The default value is `http://localhost:8080/`.
:::

</TabItem>

</Tabs>

```shell
curl -XGET -H'Accept: application/json' -H'Authorization: Bearer <TOKEN>' http://localhost:8080/v2/topology
curl --header "Authorization: Bearer ${TOKEN}" \
${ZEEBE_REST_ADDRESS}/v2/topology
```

### How to obtain the access token

You must obtain a token to use the Camunda 8 REST API. When you create a Zeebe [client](/guides/setup-client-connection-credentials.md), you get all the information needed to connect to Zeebe.

Refer to our guide on [building your own client](../build-your-own-client.md).

The following settings are needed:

| Name | Description | Default value |
| ------------------------ | ----------------------------------------------- | ------------------ |
| client id | Name of your registered client | - |
| client secret | Password for your registered client | - |
| audience | Permission name; if not given use default value | `zeebe.camunda.io` |
| authorization server url | Token issuer server | - |

Send a token issue _POST_ request to the authorization server with the following content:
A successful response would include [information about the cluster](/apis-tools/camunda-api-rest/specifications/get-cluster-topology.api.mdx). For example:

```json
{
"client_id": "<client-id>",
"client_secret": "<client-secret>",
"audience": "<audience>",
"grant_type": "client_credentials"
"brokers": [
...
],
"clusterSize": 3,
"partitionsCount": 3,
"replicationFactor": 3,
"gatewayVersion": "8.6.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea - Could be fancy here and get a variable for the product version 🤷‍♀️

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, in general I didn't feel great about these sample API responses. I want to show enough that it's useful, but not so much that people get lost in the details or it's drifting from the real response.

}
```

Refer to the following example with _curl_:
## Token expiration

```shell
curl -X POST --header 'content-type: application/json' --data '{"client_id": "<client-id>", "client_secret":"<client-secret>","audience":"<audience>","grant_type":"client_credentials"}' https://<authorization server url>
```

If the authentication is successful, the authorization server sends back the access token, when it expires, scope, and type:

```json
{
"access_token": "ey...",
"scope": "...",
"expires_in": 86400,
"token_type": "Bearer"
}
```
Access tokens expire according to the `expires_in` property of a successful authentication response. After this duration, in seconds, you must request a new access token.
Loading
Loading