# Authentication

DIP requires client authentication using signed JWTs, compliant with the FAPI 2.0 Security Profile.

## Overview

All requests to the PAR and Token endpoints must include:

1. **Client Assertion** - A signed JWT authenticating your client
2. **Client Assertion Type** - Set to `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`

## Supported Algorithms

DIP supports the following signing algorithms (FAPI 2.0 compliant):

| Algorithm | Key Type      | Description                               |
| --------- | ------------- | ----------------------------------------- |
| `ES256`   | EC (P-256)    | ECDSA using P-256 and SHA-256             |
| `PS256`   | RSA           | RSASSA-PSS using SHA-256                  |
| `EdDSA`   | OKP (Ed25519) | Edwards-curve Digital Signature Algorithm |

> **Warning**
>
> `RS256` is NOT supported due to FAPI 2.0 requirements.

## Client Assertion JWT

The client assertion authenticates your client to DIP.

### Header

The JWT header must contain `alg` and `kid`. The `typ` claim is optional but must be `JWT` if present.

| Claim | Required | Description                              |
| ----- | -------- | ---------------------------------------- |
| `alg` | Yes      | Algorithm (`ES256`, `PS256`, or `EdDSA`) |
| `kid` | Yes      | Key ID matching your registered JWKS     |
| `typ` | No       | If present, must be `JWT`                |

**Example Header:**

```json
{
  "alg": "ES256",
  "kid": "my-signing-key-1",
  "typ": "JWT"
}
```

### Payload

The JWT payload must contain these **required claims**:

| Claim | Required | Description                        |
| ----- | -------- | ---------------------------------- |
| `iss` | Yes      | Issuer - must be your `client_id`  |
| `sub` | Yes      | Subject - must be your `client_id` |
| `aud` | Yes      | Audience - DIP base URL            |
| `exp` | Yes      | Expiration time (Unix timestamp)   |

The following **optional claims** are also allowed:

| Claim | Description                      |
| ----- | -------------------------------- |
| `iat` | Issued at time (Unix timestamp)  |
| `jti` | Unique JWT identifier            |
| `nbf` | Not before time (Unix timestamp) |

**Example Payload:**

```json
{
  "iss": "dip_aci_your_client_id",
  "sub": "dip_aci_your_client_id",
  "aud": "https://{dip-base-url}",
  "exp": 1759835872
}
```

> **Note**
>
> Standard JWT claims `iat`, `jti`, and `nbf` are accepted but not required. Any other claims will be rejected.

## JWKS Registration

Your public key must be registered with DIP in JWKS format.

### JWKS Format

```json
{
  "keys": [
    {
      "kty": "EC",
      "crv": "P-256",
      "alg": "ES256",
      "use": "sig",
      "kid": "my-signing-key-1",
      "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
      "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"
    }
  ]
}
```

### Required JWK Fields

| Field | Required | Description                              |
| ----- | -------- | ---------------------------------------- |
| `kty` | Yes      | Key type (`EC`, `RSA`, or `OKP`)         |
| `alg` | Yes      | Algorithm (`ES256`, `PS256`, or `EdDSA`) |
| `use` | Yes      | Must be `sig`                            |
| `kid` | Yes      | Unique key identifier                    |

### EC Key (P-256) Fields

| Field | Description              |
| ----- | ------------------------ |
| `crv` | Curve name (`P-256`)     |
| `x`   | X coordinate (Base64url) |
| `y`   | Y coordinate (Base64url) |

### RSA Key Fields

| Field | Description          |
| ----- | -------------------- |
| `n`   | Modulus (Base64url)  |
| `e`   | Exponent (Base64url) |

### OKP Key (Ed25519) Fields

| Field | Description            |
| ----- | ---------------------- |
| `crv` | Curve name (`Ed25519`) |
| `x`   | Public key (Base64url) |

## Key Rotation

DIP fetches your public keys from the JWKS URI registered for your client. To rotate keys:

1. Generate a new keypair
2. Add the new public key to your JWKS endpoint
3. Start using the new key (reference via `kid`)
4. After a transition period, remove the old key from your JWKS endpoint
