> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add JWT machine-to-machine authentication

> How to configure JWT machine-to-machine authentication in Atoti Limits using the built-in support or a custom LimitsJwtRestClientBuilder, covering the service-principal property and Authorization header setup

## Overview

Atoti Limits includes native support for [JSON Web Tokens](https://auth0.com/docs/secure/tokens/json-web-tokens).
We can utilize this support to send MtM requests using the `Authorization: Jwt ...` header.

<Note>
  This is the default authentication mechanism in Atoti Limits, but we will show how it is
  implemented nonetheless to provide a sample extension mechanism.
</Note>

## Use the default support

To use the native support, specify the following properties in **both Atoti Limits and your connected server**:

```yml theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
limits:
  autoconfiguration:
    service-principal: admin // this specifies the principal user designated to invoke MtM request with JWT MtM authentication
```

## How it works

As described in [Adding Custom Machine-to-Machine (MtM) Authentication](.#how-to-add-custom-mtm-authentication),
we need to add some custom implementations to our code.

### 1. Add a custom `ILimitsRestClientBuilder` bean in the Connected Server and Atoti Limits.

This example is an implementation of `ILimitsRestClientBuilder`, which uses JWT authentication:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Getter
public class LimitsJwtRestClientBuilder implements ILimitsRestClientBuilder {

  protected final RestClient.Builder restClientBuilder;

  // We inject any services we need into our provider
  public LimitsJwtRestClientBuilder(
      // this is used to get or generate the JWT
      IJwtService jwtService,
      UserDetailsService userDetailsService,
      // this is used to get the authorities of the service user
      // we use this class to pull in properties, but you could use any property extraction mechanism
      LimitsConnectionConfigurationProperties limitsConnectionConfigurationProperties
  ) {

    // we build the client builder to be used for requests
    this.restClientBuilder =
        buildRestClient(jwtService, userDetailsService, limitsConnectionConfigurationProperties);
  }

  private RestClient.Builder buildRestClient(
      IJwtService jwtService,
      UserDetailsService userDetailsService,
      LimitsConnectionConfigurationProperties limitsConnectionConfigurationProperties) {
    String servicePrincipal =
        limitsConnectionConfigurationProperties.getAutoconfiguration().getServicePrincipal();
    if (servicePrincipal == null) {
      throw new LimitsRuntimeException(
          "You must specify the `limits.autoconfiguration.service-principal` property if you are using JWT machine-to-machine authentication!");
    }
    Collection<String> authorities =
        userDetailsService.loadUserByUsername(servicePrincipal).getAuthorities().stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toSet());
    final String jwt = jwtService.getToken(servicePrincipal, authorities);
    // here is where we set the `Authorization: Jwt ...` header
    return RestClient.builder().defaultHeader(AUTHORIZATION, "Jwt " + jwt);
  }
}
```

### 2. Expose your custom `ILimitsRestClientBuilder` bean in the Spring context

Once you have written your bean you can [expose it](..#importing-spring-beans-into-the-project)
to the Spring context.
