# OAuth2 Authentication

The *OAuth 2.0 Authorization Framework* is formalized in RFC-6749. Our IAM (Identity and Access Management) solution provides the *Client Credentials* flow for
machine-to-machine integrations with our APIs.

## Client Credentials flow

The *Client Credentials* flow is ideal for machine-to-machine integrations. As an API consumer, all you need is a client ID and client secret to authenticate
your application with the APIs.


```mermaid
sequenceDiagram
    participant Integration
    participant IAM
    participant API

    Integration->>+IAM: Authenticate with id and secret
    IAM->>IAM: Validate credentials
    IAM->>-Integration: Access tokens
    loop
      Integration->>+API: Request
      API->>-Integration: Response
      alt When Response code is unauthenticated
        Integration->>+IAM: Authenticate with id and secret
        IAM->>IAM: Validate credentials
        IAM->>-Integration: Access tokens
      end
    end
```

### Requesting an access token

In order to manually request a token, you can use one of the following methods

#### Basic auth header

* Retrieve the `Token URL` from the API you want to access,
* Create a `Basic Authorization` header:
  * `Base64Encode("${clientId}:${clientSecret}")`
* Send a `POST` request to the `Token URL`:
  * URL: https://auth.conundra.eu/auth/realms/prod/protocol/openid-connect/token
  * Header:
    * Content-Type: `application/x-www-form-urlencoded`
    * Authorization: `Basic <ENCODED AUTHORIZATION>`
  * Body:
`grant_type="client_credentials"`


A sample `curl`-request is shown below:


```shell
curl --location 'https://auth.conundra.eu/auth/realms/prod/protocol/openid-connect/token' \
     --header 'Authorization: Basic <ENCODED AUTHORIZATION>' \
     --form 'grant_type="client_credentials"'
```

#### Post request with credentials in the body

* Retrieve the `Token URL` from the API you want to access,
* Send a `POST` request to the `Token URL`:
  * Body:
`grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}`


A sample `curl`-request is shown below:


```shell
curl -s https://auth.conundra.eu/auth/realms/prod/protocol/openid-connect/token -d "grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}"
```

An example response should look something like this:


```json
{
   "access_token" : "ey...",
   "expires_in" : 300,
   "not-before-policy" : 0,
   "refresh_expires_in" : 0,
   "scope" : "",
   "token_type" : "Bearer"
}
```

This will inform you how long it is valid, how long you should wait until refreshing, what the scope is and how it should be used.

### Refreshing an access token

As specified in the OAuth2 specification (RFC-6749), the [Client Credentials flow](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.4) does not support
refresh tokens. When a response is returned with a HTTP/401 status code, it is up to the client to acquire a new access token. This is typically handled through
an interceptor on the API calls which makes the refreshes transparent from the point of view of the client application logic.

#### When to acquire a new token

Implement token renewal in your application using these guidelines:

1. Before expiration (recommended)
  * Monitor the expires_in value from the authentication response
  * Set up a renewal process to trigger when 80-90% of the token lifetime has elapsed
  * Example: For a token with expires_in: 300 (5 minutes), request a new token after 270 seconds
2. On authentication failures:
When receiving a 401 Unauthorized response, check the WWW-Authenticate header:
  * If it contains error="invalid_token": Your token has likely expired - request a new one immediately
  * If it contains other errors (e.g., insufficient_scope, invalid_request): Review the [OAuth 2.0 Bearer Token specification](https://www.rfc-editor.org/rfc/rfc6750.html#section-3.1) for appropriate handling
  * If no error details are provided: The issue may require further investigation (incorrect endpoint, network issues, or server-side problems)


### Authentication Rate limits

For security and reliability reasons, the OAuth2.0 endpoints are protected with rate-limiting.
Up to 50 requests per second from the same IP are allowed, further requests will be rejected with a 429 response code.

In case we detect suspicious behavior such as continuous failed login attempts from the same IP, the IP will be temporarily blocked.
When this happens, you will start seeing connection errors, ssl/tls handshake errors or something similar.