# Auth

Lavanda's platform boasts a variety of authentication and authorization systems tailored to specific use cases. This document focuses on the intricacies of third-party API integrations.

## Getting started

In order to connect to our API you will need to obtain a `client_id` and `client_secret`.

Please reach out to our customer success team to procure these details.

:::danger
Please keep your `client_id` and `client_secret` safe. Malicious actors could use them to make requests on your behalf.
:::

## Obtaining a token

To interact with the API, clients must provide a token as an `Authorization` header in each request. These tokens follow the JWT (JSON Web Token) standard and can be acquired with the aforementioned `client_id` and `client_secret`.

You can make a `POST` request to our API with a `grant_type` and your credentials to obtain a token.

```text
https://platapi.lavanda.app/v1/oauth2/token
```

Here is an example cURL request:

```sh
curl --location 'https://platapi.lavanda.app/v1/oauth2/token' \
--header 'Content-Type: application/json' \
--data '{
    "grant_type": "client_credentials",
    "client_id": “xxx”,
    "client_secret": “xxx”
}'
```

Assuming the request is a success, you will receive a response in the following format:

```json
{
    "access_token": "xxx",
    "expires_in": 3600,
    "token_type": "Bearer"
}
```

- `access_token` - The token you can use to make requests
- `expires_in` - The length of time the token is valid for (once it expires you will need to generate a new one)

Once you have received your token, you can use the introspection tool on [https://jwt.io/](https://jwt.io/) to view the internals. (Lavanda is not responsible for the content of external sites).

:::danger
Please remember to keep your token safe. Even though it has an expiry date, malicious actors could use it to make requests on your behalf.
:::

### Example token

```json
{
  "sub": "xxx",
  "token_use": "access",
  "scope": "platapi/lavanda",
  "auth_time": 1723021787,
  "iss": "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_xxxxxxxxx",
  "exp": 1723025387,
  "iat": 1723021787,
  "version": 2,
  "jti": "2c01fe59-64fc-45e5-9e30-54856d022b95",
  "client_id": "xxx"
}
```

- `sub` - Subject (this is the unique id of the person requesting the token)
- `iss` - Issuer (this is the service which issues the token - in our case this is AWS Cognito)
- `exp` - Expiry date
- `iat` - Issued at
- `client_id` - Client id (same value as the subject)

### Token refresh

When a token expires it will become invalid and you will need to generate a new one. To do so, you can follow the same process above.

:::note
Since each token is generated independently it is possible to have multiple at once. For security reasons we recommend you reuse a token until it's expiry instead of creating a new one for each request.
:::

### Scopes

Although the example token above contains a `scope`, at Lavanda we don't pass scopes on a per operation level in the token. Due to the fine-grained access control nature of our API we use operation based scopes internally to determine whether a client has permissions to perform all or part of a request.

### Acting on behalf of a user

If your integration performs actions on behalf of one of your own end users, you can optionally identify
that user when you request a token by including an `act` (actor) object. This embeds an
[OAuth 2.0 actor claim](https://datatracker.ietf.org/doc/html/rfc8693#name-act-actor-claim) in the issued
token, which Lavanda records against any actions taken with it.

Pass `act` as a JSON object containing a `sub` (the identifier of your end user). The field is optional —
omit it entirely to request a regular token.

```sh
curl --location 'https://platapi.lavanda.app/v1/oauth2/token' \
--header 'Content-Type: application/json' \
--data '{
    "grant_type": "client_credentials",
    "client_id": "xxx",
    "client_secret": "xxx",
    "act": {
        "sub": "your-end-user-id"
    }
}'
```

The resulting token carries the actor under the `act` claim, prefixed with your `client_id`:

```json
{
  "sub": "xxx",
  "act": {
    "sub": "xxx:your-end-user-id"
  },
  "token_use": "access",
  "scope": "platapi/lavanda",
  "iss": "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_xxxxxxxxx",
  "client_id": "xxx"
}
```

- `act.sub` - Your `client_id`, then the identifier of the end user you are acting on behalf of,
  separated by a colon

:::note
`act.sub` must be a non-empty string of at most 128 characters. Only `sub` is recorded — any other
fields inside `act` are ignored. The value is opaque to Lavanda, so use whatever identifier is
meaningful in your own system.

Because Lavanda cannot verify that you speak for the end user you name, the actor is recorded inside
your own namespace: the issued claim is `"<your client_id>:<the sub you sent>"`. This keeps every
actor attributable to the integration that asserted it, and means an actor id you supply can never
be mistaken for one belonging to another integration or to a Lavanda user. The actor is an
attribution record only — it never grants access, and all authorization is resolved from the
authenticated client.
:::

## Accessing your data

Assuming you have acquired a valid token you should now be able to make requests to our API. Since our
tokens work across workspaces it is possible to finely tune what access a given token has. Please reach
out to our customer support team for more information.

### Making a request

Once you have your token you can include it as an `Authorization` header as follows, adjust the query to suit your needs:

```sh
curl --request POST \
    --header 'content-type: application/json' \
    --header 'Authorization: Bearer xxx' \
    --url 'https://platapi.lavanda.app/v1' \
    --data '{"query":"","variables":{}}'
```
