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¶
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¶
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¶
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 for full details.
Header (3 claims exactly):
Payload (4 claims exactly):
{
"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¶
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.
{
"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": {
"country_code": null,
"name": null
},
"personal_number": null,
"active_authentication_result": null,
"issuer_check": 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_detailsfields andclaimsthat you need. For example, if you only needgiven_nameandbirthdate, only include those in theclaimsobject. Similarly, if you only need the document type and expiry date, only includetypeanddate_of_expiryindocument_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) |
electronic_record |
Verification based on data from an electronic source (e.g., population register) |
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.country_code |
string | Issuing country (ISO 3166-1 alpha-3) |
issuer.name |
string | Issuing authority name |
personal_number |
string or object | For Norwegian documents, this is returned as an object: {"type": "no-fnr", "value": "<NNIN>"}. For non-Norwegian documents, this is returned as a plain string containing the NIN (National Identification Number) from the issuing country, if available. |
active_authentication_result |
string | Document chip authentication result |
issuer_check |
object | Issuer verification status. Note: Only available for Norwegian documents; will be UNKNOWN or omitted for non-Norwegian documents. |
Electronic Record Evidence (Population Register)¶
To request verification against the Norwegian Population Register (Folkeregisteret), include an electronic_record evidence element with type: population_register.
Important: Folkeregisteret lookup is only available for RPs that have a contractual agreement with us for this service. Contact us to enable this feature for your client.
Request Structure¶
{
"type": { "value": "electronic_record" },
"record": {
"type": { "value": "population_register" },
"source": {
"name": "Folkeregisteret"
},
"personal_number": "12345678901"
}
}
Electronic Record Fields¶
| Field | Required | Type | Description |
|---|---|---|---|
type.value |
Yes | string | Must be electronic_record |
record.type.value |
Yes | string | Must be population_register |
record.source.name |
Yes | string | Must be Folkeregisteret |
record.personal_number |
No | string | Norwegian National ID (11-digit fødselsnummer or d-nummer) used to look up person in Folkeregisteret. Will be included in response if you request evidence from Folkeregisteret and we find a match using data from the document. |
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¶
{
"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": "K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U",
"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": {
"country_code": null,
"name": null
},
"personal_number": null,
"active_authentication_result": null,
"issuer_check": null
}
}
]
},
"claims": {
"given_name": { "essential": true },
"family_name": { "essential": true },
"picture": { "essential": true },
"gender": { "essential": true },
"birthdate": { "essential": true },
"nationalities": { "essential": true }
}
}
}
}
}
Complete Request Object Example with Folkeregisteret¶
This example shows how to request both document evidence and Folkeregisteret (population register) verification:
{
"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": "K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U",
"code_challenge_method": "S256",
"claims": {
"id_token": {
"verified_claims": {
"verification": {
"trust_framework": { "value": "stoe_etsi" },
"evidence": [
{
"type": {
"value": "document"
},
"document_details": {
"type": null,
"document_number": null,
"date_of_expiry": null,
"issuer": {
"country_code": null,
"name": null
},
"active_authentication_result": null,
"issuer_check": null
}
},
{
"type": {
"value": "electronic_record"
},
"record": {
"type": {
"value": "population_register"
},
"source": {
"name": "Folkeregisteret"
},
"personal_number": "12345678901"
}
}
]
},
"claims": {
"given_name": { "essential": true },
"family_name": { "essential": true },
"birthdate": { "essential": true },
"nationalities": { "essential": false }
}
}
}
}
}
Response¶
Success Response (201 Created)¶
{
"request_uri": "urn:ietf:params:oauth:request_uri:550e8400-e29b-41d4-a716-446655440000",
"expires_in": 600
}
| Field | Type | Description |
|---|---|---|
request_uri |
string | URI to use in authorization request |
expires_in |
number | Lifetime in seconds (typically 600) |
Error Response¶
Error Codes¶
| Error | HTTP Status | Description |
|---|---|---|
invalid_request |
400 | Missing or invalid parameters |
invalid_client |
401 | Client authentication failed |
unauthorized_client |
403 | Client not authorized for this request |
invalid_scope |
400 | Invalid scope value |
server_error |
500 | Internal server error |
temporarily_unavailable |
503 | Service temporarily unavailable |
Using the Request URI¶
After receiving the request_uri, redirect the user to the authorization endpoint:
GET https://{dip-flow-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 - Exchange authorization code for tokens
- Authentication - JWT requirements
- ID Token - ID token structure