> For the complete documentation index, see [llms.txt](https://docs.pal.aic.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pal.aic.io/foundations/authentication-and-licensing.md).

# Authentication and licensing

PAL.NET keeps authentication and licensing at the runtime boundary. Every operation must pass both checks before an authenticated HTTP request is sent.

## Access-token provider

Implement `IPalantirAccessTokenProvider` when the host owns token acquisition:

```csharp
public sealed class MyAccessTokenProvider : IPalantirAccessTokenProvider
{
    public ValueTask<PalantirAccessToken> GetAccessTokenAsync(
        PalantirAuthenticationContext context,
        CancellationToken cancellationToken = default)
    {
        // Resolve a token from the approved identity integration.
        // Use context.OperationId and context.Scopes when requesting it.
        throw new NotImplementedException();
    }
}
```

The context contains only the operation identifier and requested scopes. `PalantirAccessToken` contains the token value and expiry; its `ToString()` is redacted so accidental formatting does not disclose credentials.

The provider must:

* request or validate the scopes needed by the operation;
* honour cancellation;
* return an unexpired token or fail clearly;
* never log the token, client secret, authorization header, or token endpoint response;
* refresh before expiry according to the provider's policy.

## Foundry OAuth2 adapter

For a Foundation host with client credentials, configure `Palantir:ClientCredentials` and call:

```csharp
services.AddPalantirFoundryOAuth2(new PalantirClientCredentialsOptions
{
    TokenEndpoint = new Uri("https://customer.palantircloud.com/oauth2/token"),
    ClientId = clientId,
    ClientSecret = clientSecret,
    RefreshSkew = TimeSpan.FromMinutes(2),
    RequestTimeout = TimeSpan.FromSeconds(30)
});
```

PAL.NET adapts AIC.Foundry's OAuth2 client-credentials implementation. Foundry owns token acquisition, caching, HTTP handling, and logging; PAL.NET owns the operation-scoped token contract.

## Offline entitlement

Register AIC-issued signed entitlement verification with:

```csharp
services.AddPalantirOfflineLicense(new PalantirOfflineLicenseOptions
{
    LicenseFilePath = licensePath,
    PublicKeyPem = publicKeyPem,
    ProductId = "PAL.NET",
    ReloadInterval = TimeSpan.FromMinutes(5),
    ClockSkew = TimeSpan.FromMinutes(2)
});
```

The offline guard validates the signed envelope, algorithm, product, validity window, enrollment host, and requested operation. It retains no licence evidence in exception messages or diagnostic payloads. Missing, invalid, expired, mismatched, or incomplete entitlement data fails closed with `PalantirLicenseException`.

## Fail-closed defaults

`AddPalantir` initially registers an unconfigured token provider and an unlicensed guard. This is intentional: a service can build and validate its container without making a remote call, but an API operation cannot execute until the application replaces those defaults with approved implementations.

## Scopes and permissions

Generated operation descriptors carry published operation scopes. When an operation has no explicit scope override, the runtime uses `PalantirClientOptions.DefaultScopes`. A valid token does not bypass upstream permissions; the Palantir identity must still be entitled to the resource and action.

## Authentication failures

* Missing provider: the operation fails before network access.
* Expired/invalid token: the upstream response is mapped to `PalantirErrorClassification.Authentication`.
* Insufficient permission: HTTP 403 maps to `Authorisation`.
* Missing entitlement: `PalantirLicenseException` is raised before the request.
