# Pushed Authorization Request (PAR)

The PAR endpoint allows clients to push authorization request parameters directly to DIP before redirecting the user. This is required for all authorization flows.

## Endpoint

```
POST /par
```

## Why PAR?

- **Security**: Sensitive parameters are sent server-to-server, not exposed in browser URLs
- **Integrity**: Request parameters cannot be tampered with by the user
- **URL Length**: Avoids URL length limitations for complex requests
- **FAPI Compliance**: Required by FAPI 2.0 Security Profile

## Request Format

### Headers

```http
Content-Type: application/x-www-form-urlencoded
```

### Parameters

| Parameter               | Required | Type   | Description                                                      |
| ----------------------- | -------- | ------ | ---------------------------------------------------------------- |
| `client_id`             | Yes      | string | Your OAuth client identifier                                     |
| `client_assertion_type` | Yes      | string | Must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` |
| `client_assertion`      | Yes      | string | Signed JWT for client authentication                             |
| `request`               | Yes      | string | Signed JWT containing authorization parameters                   |

### Example Request

```http
POST /par HTTP/1.1
Host: {dip-base-url}
Content-Type: application/x-www-form-urlencoded

client_id=dip_aci_your_client_id
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6Im15LWtleSIsInR5cCI6IkpXVCJ9...
&request=eyJhbGciOiJFUzI1NiIsImtpZCI6Im15LWtleSIsInR5cCI6IkpXVCJ9...
```

## Client Assertion JWT

See [Authentication](https://docs.stoe.no/id-check/getting-started/authentication.md) for full details.

**Header (3 claims exactly):**

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

**Payload (4 required claims, 3 optional):**

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

## Request Object JWT

The request object contains all authorization parameters.

### Header

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

### Payload Parameters

| Parameter               | Required | Type   | Description                      |
| ----------------------- | -------- | ------ | -------------------------------- |
| `iss`                   | Yes      | string | Must be your `client_id`         |
| `sub`                   | Yes      | string | Must be your `client_id`         |
| `aud`                   | Yes      | string | DIP base URL                     |
| `exp`                   | Yes      | number | Expiration time (Unix timestamp) |
| `client_id`             | Yes      | string | Your OAuth client identifier     |
| `response_type`         | Yes      | string | Must be `code`                   |
| `redirect_uri`          | Yes      | string | Registered callback URL          |
| `scope`                 | Yes      | string | Must be `openid`                 |
| `state`                 | Yes      | string | CSRF protection value            |
| `nonce`                 | Yes      | string | Replay protection value          |
| `code_challenge`        | Yes      | string | PKCE code challenge (S256)       |
| `code_challenge_method` | Yes      | string | Must be `S256`                   |
| `claims`                | Yes      | object | OIDC4IA claims request           |

### Claims Parameter Structure

The `claims` parameter defines which verified claims to request. You only need to include the document details fields and identity claims that you want to receive - omit any fields you don't need.

```json
{
  "id_token": {
    "verified_claims": {
      "verification": {
         "trust_framework": { "value": "stoe" },
          "evidence": [
            {
              "type": {
                "value": "document"
              },
              "document_details": {
                "type": null,
                "document_number": null,
                "date_of_issuance": null,
                "date_of_expiry": null,
                "issuer": null,
                "personal_number": null
              }
            }
          ]
        },
        "claims": {
          "name": { "essential": true },
          "given_name": { "essential": true },
          "family_name": { "essential": true },
          "picture": { "essential": true },
          "gender": { "essential": true },
          "birthdate": { "essential": true },
          "nationalities": { "essential": true }
        }
    }
  }
}
```

> **Note:** Only include the `document_details` fields and `claims` that you need. For example, if you only need `given_name` and `birthdate`, only include those in the `claims` object. Similarly, if you only need the document type and expiry date, only include `type` and `date_of_expiry` in `document_details`.

> **Note:** Any requested evidence or claims that are not available in the ID check data will be omitted from the response. The response only contains data that was successfully retrieved.

### Trust Framework Values

| Value       | Description                                                                                                                                                            |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stoe`      | Standard trust framework                                                                                                                                               |
| `stoe_etsi` | ETSI-compliant with stricter validation. Requires `given_name` and `family_name` to be requested. Issuer check must be valid (only available for Norwegian documents). |

### Evidence Types

| Type       | Description                                    |
| ---------- | ---------------------------------------------- |
| `document` | Physical identity document (passport, ID card) |

### Document Details Fields

All fields use `null` to indicate they should be populated:

| Field              | Type   | Description                                                                                                                                                                           |
| ------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`             | string | Document type (`passport`, `idcard`)                                                                                                                                                  |
| `document_number`  | string | Document identification number                                                                                                                                                        |
| `date_of_issuance` | string | Issue date (ISO 8601: `YYYY-MM-DD`)                                                                                                                                                   |
| `date_of_expiry`   | string | Expiry date (ISO 8601: `YYYY-MM-DD`)                                                                                                                                                  |
| `issuer`           | null   | Issuing authority details. Response contains `country_code` (ISO 3166-1 alpha-3) and `name`.                                                                                          |
| `personal_number`  | string | For Norwegian documents, this is the fødselsnummer (NNIN). For non-Norwegian documents, this may contain a national identification number from the issuing country, or may be absent. |

Note: The fields requested, will only be included in the response if the data is available from the Document. For example, if you request `date_of_issuance` but this data is not available from the document, it will be omitted from the response.

### Verified Claims Fields

| Field           | Type      | Description                                                                    |
| --------------- | --------- | ------------------------------------------------------------------------------ |
| `name`          | string    | Full name                                                                      |
| `given_name`    | string    | First name(s)                                                                  |
| `family_name`   | string    | Last name(s)                                                                   |
| `picture`       | string    | Portrait photo from identity document (data URI: `data:image/jpeg;base64,...`) |
| `gender`        | string    | Gender (`male`, `female`, `unknown`, `unspecified`)                            |
| `birthdate`     | string    | Date of birth (ISO 8601: `YYYY-MM-DD`)                                         |
| `nationalities` | string\[] | List of nationalities (ISO 3166-1 alpha-3)                                     |

## Complete Request Object Example

```json
{
  "iss": "dip_aci_your_client_id",
  "sub": "dip_aci_your_client_id",
  "aud": "https://{dip-base-url}",
  "exp": 1759835872,
  "client_id": "dip_aci_your_client_id",
  "response_type": "code",
  "redirect_uri": "https://client.example.org/callback",
  "scope": "openid",
  "state": "af0ifjsldkj",
  "nonce": "n-0S6_WzA2Mj",
  "code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
  "code_challenge_method": "S256",
  "claims": {
    "id_token": {
      "verified_claims": {
        "verification": {
          "trust_framework": { "value": "stoe" },
          "evidence": [
            {
              "type": {
                "value": "document"
              },
              "document_details": {
                "type": null,
                "document_number": null,
                "date_of_issuance": null,
                "date_of_expiry": null,
                "issuer": null,
                "personal_number": null
              }
            }
          ]
        },
        "claims": {
          "given_name": { "essential": true },
          "family_name": { "essential": true },
          "picture": { "essential": true },
          "gender": { "essential": true },
          "birthdate": { "essential": true },
          "nationalities": { "essential": true }
        }
      }
    }
  }
}
```

## Response

### Success Response (201 Created)

```json
{
  "request_uri": "urn:ietf:params:oauth:request_uri:550e8400-e29b-41d4-a716-446655440000",
  "expires_in": 60
}
```

| Field         | Type   | Description                         |
| ------------- | ------ | ----------------------------------- |
| `request_uri` | string | URI to use in authorization request |
| `expires_in`  | number | Lifetime in seconds (typically 60)  |

### Error Response

```json
{
  "error": "invalid_request",
  "error_description": "Missing required parameter: client_id"
}
```

### Error Codes

| Error             | HTTP Status | Description                                                                                                   |
| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------- |
| `invalid_request` | 400         | Missing or invalid parameters, invalid request object claims, scope errors, or signature verification failure |
| `invalid_client`  | 401         | Client authentication failed (unknown client, key not found, or invalid JWK)                                  |
| `not_found`       | 404         | Encryption key not found for client                                                                           |
| `server_error`    | 500         | Internal server error                                                                                         |

## Using the Request URI

After receiving the `request_uri`, redirect the user to the authorization endpoint:

```
GET https://{dip-base-url}/auth
  ?client_id=dip_aci_your_client_id
  &request_uri=urn:ietf:params:oauth:request_uri:550e8400-e29b-41d4-a716-446655440000
```

## Next Steps

- [Token Request](https://docs.stoe.no/id-check/api/token.md) - Exchange authorization code for tokens
- [Authentication](https://docs.stoe.no/id-check/getting-started/authentication.md) - JWT requirements
- [ID Token](https://docs.stoe.no/id-check/id-token.md) - ID token structure
