diff --git a/content/api/dialogporten/_index.en.md b/content/api/dialogporten/_index.en.md new file mode 100644 index 0000000000..490499f5c1 --- /dev/null +++ b/content/api/dialogporten/_index.en.md @@ -0,0 +1,11 @@ +--- +title: Dialogporten API +linktitle: Dialogporten +description: API for Dialogporten functionality +--- + +Please refer to the following sections for Dialogporten API reference information + +* [OpenAPI specifications]({{}}) +* [GraphQL specifications]({{}}) + \ No newline at end of file diff --git a/content/dialogporten/getting-started/authorization/_index.md b/content/dialogporten/getting-started/authorization/_index.md index 78b8e1681d..887685e215 100644 --- a/content/dialogporten/getting-started/authorization/_index.md +++ b/content/dialogporten/getting-started/authorization/_index.md @@ -4,5 +4,12 @@ description: 'Learn how Dialogporten uses Altinn Authorization and provides its weight: 20 --- +## Introduction + +Dialogporten is fully integrated with ID-porten, Maskinporten and Altinn Authorization. Access to all dialogs are subject to the same access policy as the service they represent, which is fully manageable via roles, access packages and service rights in [Altinn Access Management]({{}}). + +**Read more** +* {{}} + {{}} diff --git a/content/dialogporten/getting-started/authorization/attributes/_index.md b/content/dialogporten/getting-started/authorization/attributes/_index.md index f28fc8d2cd..a47a886f65 100644 --- a/content/dialogporten/getting-started/authorization/attributes/_index.md +++ b/content/dialogporten/getting-started/authorization/attributes/_index.md @@ -1,7 +1,7 @@ --- title: 'Authorization Attributes' description: 'Learn how dialogs in Dialogporten implements fine-grained access control using Altinn Authorization' -weight: 10 +weight: 20 --- ## Introduction diff --git a/content/dialogporten/getting-started/authorization/dialog-tokens/_index.md b/content/dialogporten/getting-started/authorization/dialog-tokens/_index.md index c2bb5956a3..f208f47803 100644 --- a/content/dialogporten/getting-started/authorization/dialog-tokens/_index.md +++ b/content/dialogporten/getting-started/authorization/dialog-tokens/_index.md @@ -1,7 +1,7 @@ --- title: 'Dialog Tokens' description: 'Learn how dialog tokens can be used to simplify authorization and enable higher confidentiality' -weight: 20 +weight: 30 --- ## Introduction diff --git a/content/dialogporten/getting-started/authorization/service-resource/_index.md b/content/dialogporten/getting-started/authorization/service-resource/_index.md index c875241d86..2700a4c86e 100644 --- a/content/dialogporten/getting-started/authorization/service-resource/_index.md +++ b/content/dialogporten/getting-started/authorization/service-resource/_index.md @@ -8,9 +8,9 @@ weight: 10 All dialogs must refer to a main _service resource_. A service resource describes a particular digital service, and contains metadata such as a name, a description, what public actor owns and - most importantly - the authorization policy governing the use of that service. -Service resources reside in [Altinn Resource Registry]({{}}), alongside other types of resources which utilize Altinn Authorization for access management and control. The authorization policies are expressed in [XACML]({{}}), which describes the access rules that governs all dialogs that refer to it. Dialogporten is integrated with Altinn Authorization, and will consult it for every request made to Dialogporten and enforce its decisions. The main service resource policy is thus used to control what information a given user can retrieve from Dialogporten. Access managers within organizations use these service resources, or groups of related service resources, when handling who should have access to do what on behalf of an organization. +Service resources reside in [Altinn Resource Registry]({{}}), alongside other types of resources which utilize Altinn Authorization for access management and control. The authorization policies are expressed in [XACML]({{}}), which describes the access rules that governs all dialogs that refer to it. Dialogporten is integrated with Altinn Authorization, and will consult it for every request made to Dialogporten and enforce its decisions. The main service resource policy is thus used to control what information a given user can retrieve from Dialogporten. Access managers within organizations use these service resources, or groups of related service resources, when handling who should have access to do what on behalf of an organization. -For example, an action named "Go to signing" might refer to an _action_ called "sign" in the XACML policy for the main service resource. If the user does not posess this permission, the button may be grayed out and disabled. +For example, an action named "Go to signing" might refer to an _action_ called "sign" in the [XACML]({{}}) policy for the main service resource. If the user does not posess this permission, the button may be grayed out and disabled. ## Advanced usage XACML offers great flexibility in how coarse or fine-grained the access control should be, and dialogs can contain actions and transmissions that can be matched by different rules defined within the policy of the service resource. Transmissions and actions can even refer to different service resources, giving the service owner more options in how the various parts of a dialog should be governed. This is enabled through the use of [authorization attributes]({{}}) diff --git a/content/dialogporten/getting-started/dialogs/_index.md b/content/dialogporten/getting-started/dialogs/_index.md index df4d687945..baf51a9f15 100644 --- a/content/dialogporten/getting-started/dialogs/_index.md +++ b/content/dialogporten/getting-started/dialogs/_index.md @@ -41,7 +41,7 @@ Attachments can be used on both transmission and dialog level. An _action_ describes an interaction that users can perform with or related to a dialog. Examples of actions are "Open", "Start signing", "Pay", "Confirm", "Learn more", "Cancel", etc. The list of relevant actions is part of the structured description of a dialog and can be changed at any time by the service provider through the API. -An action is either a _"GUI" action_ or an _"API" action_. All actions - both GUI and API - have an identifier that maps to an _action_ (and optionally an [authorization attribute]({{}})) in the authorization policy (XACML) associated with a [service resource]({{}}). +An action is either a _"GUI" action_ or an _"API" action_. All actions - both GUI and API - have an identifier that maps to an _action_ (and optionally an [authorization attribute]({{}})) in the authorization policy ([XACML]({{}})) associated with a [service resource]({{}}). ### GUI Actions diff --git a/content/dialogporten/reference/authorization/_index.md b/content/dialogporten/reference/authorization/_index.md index 7e853be699..beba032835 100644 --- a/content/dialogporten/reference/authorization/_index.md +++ b/content/dialogporten/reference/authorization/_index.md @@ -4,5 +4,9 @@ description: 'Reference information about Dialogporten authorization mechanisms' weight: 30 --- +## Introduction + +See [getting started with authorization]({{}}) for a functional overview of how Dialogporten implements authorization. + {{}} diff --git a/content/dialogporten/reference/authorization/altinn-authorization/_index.md b/content/dialogporten/reference/authorization/altinn-authorization/_index.md new file mode 100644 index 0000000000..ed9ab84d0a --- /dev/null +++ b/content/dialogporten/reference/authorization/altinn-authorization/_index.md @@ -0,0 +1,41 @@ +--- +title: 'Altinn Authorization' +description: 'Technical overview of how Dialogporten integrates with Altinn Authorization' +weight: 1 +--- + +## Introduction + +Dialogporten is fully integrated with Altinn Authorization, which is used for all authorization decisions made in Dialogporten. + +For performance reasons, there are two different ways that Altinn Authorization is utilized. + +## Authentication and coarse-grained authorization + +Dialogporten performs basic authentication and scope-based authorization via self-contained access tokens issued by Maskinporten and ID-porten, and optionally exhanged at Altinn Token Exchange. + +**See also** +* {{}} + + +## Dialog list authorization + +All list views in Dialogporten utilizes the [Authorized Parties API]({{}}), that yields a list of all parties the authenticated user can represent along with all roles/access packages and service/instance rights that user has been granted for each party. + +Dialogporten maintains a map of which roles/access packages grant rights to each resource in the resource registry, and uses that to fetch only dialogs referring to service resources that the user has some kind of access to. Which actions (read, write, etc) are not considered - any right for the given party for the given resource is sufficient to see the dialog in the dialog list. + +As only one request (for a given party/service resource tuple) will have to be performed within a cache TTL window, re-sorting/filtering and pagination does not require additional requests to Altinn Authorization, and can therefor be performed quickly. + +## Dialog details authorization + +For dialog details, the [PDP API]({{}}) is utilized, allow for fine-grained authorization of the various actions and transmissions defined within the dialog. + +All actions and transmissions are decorated with a `IsAuthorized` flag, which indicates to the end-user system whether or not the user has access. If not, all URLs are removed. + +{{}} +While Dialogporten indicates that the action is unauthorized, and removes the URLs, the endpoint should still always perform authentication/authorization on incoming requests and not rely on Dialogporten simply obscuring access to the endpoints +{{}} + + +{{}} + diff --git a/content/dialogporten/reference/authorization/attributes/_index.md b/content/dialogporten/reference/authorization/attributes/_index.md index d4d267a263..e99e333bae 100644 --- a/content/dialogporten/reference/authorization/attributes/_index.md +++ b/content/dialogporten/reference/authorization/attributes/_index.md @@ -1,12 +1,298 @@ --- title: 'Authorization Attributes' description: 'Reference information about authorization attributes' -weight: 1 +weight: 10 --- -{{}} +## Introduction + +See [getting started with authorization attributes]({{}}) for a functional overview of authorization attributes and what they can be used for. + +Authorization attributes are a way to control how the XACML request is constructed for a given dialog, making it possible to have more fine grained rules and even refer to several distinct resource policies. + +{{}} +Authorization attributes are only considered in single dialog endpoints, ie. when requesting a dialog by ID. For dialog search/lists, the authorization attributes are not considered. +{{}} + +## Usage + +Authorization attributes can be supplied on: + +* GUI actions +* API actions +* Transmissions + +## Basic format + +The value of the authorization attribute will be mapped to a XACML resource that Altinn Authorization can understand, ie. a URN. Valid examples: + +``` +urn:altinn:subresource:mysubresource +urn:altinn:task:Task_1 +urn:altinn:resource:someotherresource +``` + +{{}} +In addition, a bare non-URN string like `foobar` can be supplied as a shorthand for `urn:altinn:subresource:foobar` +{{}} + +The authorization attribute is split at the last segment, and the first part is used as the *attribute id* and the second part as the *attribute value*. + +## Mapping to XACML + +Eg. given a dialog that has `ServiceResource` set to `urn:altinn:resource:myfirstservice` and a GUI/API action shaped like this on a dialog : + +```json +{ + "action": "sign", + "authorizationAttribute": "urn:altinn:task:gm_signing_task", + ... +} +``` + +will result in a XACML request like this: + +```json +{ + "Request": { + "AccessSubject": [ /* information about the user omitted */ ], + "Action": [ + { + "Attribute": [ + { + "AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "Value": "sign" + } + ] + } + ], + "Resource": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:resource", + "Value": "myfirstservice" + }, + { + "AttributeId": "urn:altinn:task", + "Value": "gm_signing_task" + } + /* information about the party owning the dialog omitted */ + ] + } + ] + } +} +``` + +This can be governed by a policy rule like this: + +```xml + +A rule giving user with role DAGL to "sign" within the task named "gm_signing_task" + + + + + DAGL + + + + + + + + myfirstservice + + + + gm_signing_task + + + + + + + + sign + + + + + + +``` + +If the request fails, Dialogporten will flag the GUI/API-action or transmission with `isAuthorized: false` and remove the associated URLs. This allows for end user systems to indicate to the user that access to the given action is denied. + +{{}} +While Dialogporten indicates that the action is unauthorized, and removes the URLs, the endpoint should still always perform authentication/authorization on incoming requests and not rely on Dialogporten simply obscuring access to the endpoints +{{}} + +## Using authorization attributes on transmissions + +For transmissions, the mechanics are the same, but there are no explicit actions associated with transmission. Therefore, either `read` or `transmissionread` actions are inferred and used in the XACML requests. + +If a authorization attribute is supplied that refers to a separate resource/policy in Resource Registry (see below), `read` will be used as the action in the authorization check. `read` is also used if no authorization attribute is supplied at all. However, if a authorization attribute that does NOT refer to a separate resource/policy i Resource Registry is supplied, then `transmissionread` will be used as the action in the authorization check. + +The reason for this is that the `read` action is usually defined for the entire resource, which will include all subresources due to the matching nature of XACML authorization "permit"-rules used in Altinn Authorization (a XACML rule defines constraints, ie. attributes that must be present in the request; an empty XACML rule will thus match - and return "permit" - any request). So in order to use authorization attributes that refer to rules within the same policy that should define separate access requirements, using something else than `read` is required, ie `transmissionread`. + +Example: + +```xml + +A rule giving user with role UTINN or DAGL to read the dialog + + + + + UTINN + + + + + + DAGL + + + + + + + + myfirstservice + + + + + + + + read + + + + + + + +A rule giving users with DAGL to read a particular transmission + + + + + DAGL + + + + + + + + myfirstservice + + + + sometransmission + + + + + + + + transmissionread + + + + + + +``` + +In the above example, the following XACML request: + +```json +{ + "Request": { + "AccessSubject": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:rolecode", + "Value": "UTINN" + } + ] + } + ], + "Action": [ + { + "Attribute": [ + { + "AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id", + "Value": "read" + } + ] + } + ], + "Resource": [ + { + "Attribute": [ + { + "AttributeId": "urn:altinn:resource", + "Value": "myfirstservice" + }, + { + "AttributeId": "urn:altinn:subresource", + "Value": "sometransmission" + } + ] + } + ] + } +} +``` + +Will result in `Permit`, because the request satisfies all the constraints defined in the first rule, which is not what we want. Using a different action, ie `transmissionread`, it will no longer match the first rule, and because UTINN is not part of the subject in the second rule, a `Permit` response will not be given and the transmission will be flagged as unaccessible by Dialogporten. + +## Refer to separate resource/policy in Resource Registry + +If the authorization attribute value starts with either `urn:altinn:resource` or `urn:altinn:app`, and the full value differs from what `ServiceResource` for the given dialog is set to, the authorization attribute is considered as referring to different resources in the Resource Registry. This way, access to the various part of a dialog might be governed by different policies. + +A typical use case is having dialogs that all refer to different resources/policies, but within them contain [transmissions]({{}}) representing a shared kind of communication (ie. notice of coercive fine) that are governed by the same authorization policy, regardless of the dialog in which it is used. + +Example: +```json +// First dialog +{ + "id": "019275d2-1b5d-7b82-b436-4b74e5cbd02b", + "serviceResource": "urn:altinn:resource:some-service", + "transmissions": [ + { + "id": "019275d3-41d5-743c-be44-aa729cf95acf", + "authorizationAttribute": "urn:altinn:resource:notice-of-coervice-fine", + ... + } + ] + ... +} +// Second dialog +{ + "id": "019275d4-d550-7e93-9819-1e40579f243a", + "serviceResource": "urn:altinn:resource:other-service", + "transmissions": [ + { + "id": "019275d5-0044-7b10-803a-fa5e6ac3f593", + "authorizationAttribute": "urn:altinn:resource:notice-of-coervice-fine", + ... + } + ] + ... +} +``` + +This allows for having fine-grained control over what parts of dialogs a given role is given access to, whilst avoiding duplicating policy rules across the policies governing access to various dialog types. -For now, refer to the [OpenAPI specification]({{}}). {{}} diff --git a/content/dialogporten/reference/authorization/dialog-tokens/_index.md b/content/dialogporten/reference/authorization/dialog-tokens/_index.md index f167c0e227..85e347f7e8 100644 --- a/content/dialogporten/reference/authorization/dialog-tokens/_index.md +++ b/content/dialogporten/reference/authorization/dialog-tokens/_index.md @@ -1,12 +1,83 @@ --- title: 'Dialog Tokens' description: 'Reference information about dialog tokens' -weight: 1 +weight: 20 --- -{{}} +## Introduction + +See [getting started with dialog tokens]({{}}) for a functional overview of dialog tokens and what they can be used for. + +Dialog tokens allows for unproxied frontend requests to endpoints requiring authentication and authorization, without having to rely on ID-porten SSO and redirects. + +## Usage for end-user systems (OAuth clients) + +Dialog tokens are embedded withing the [single dialog response model]({{}}) (see `dialogToken`), and is a self-contained, signed JWT containing claims from the authenticated user and the dialog itself, including what actions and authorization attributes the user is authorized for. + +The dialog tokens should be transferred as-is as a bearer token in a `Authorization` HTTP header. The contents of the dialog token should normally not be considered by the clients, ie. the token should be treated as an opaque string. + +The altinn.no-portal will be using dialog tokens on all URLs associated with [write actions]({{}}) and [front channel embeds]({{}}). Other end user systems might also use the dialog token for API actions, subject to service specific protocols defined by the respective service owner. + +## Receving and verifying dialog tokens (OAuth resource servers) + +The resource server will with the help of dialog tokens be able to fully authenticate and authorize requests that are otherwise unauthenticated (ie. without cookies or any other state). The dialog tokens should be transferred as a bearer token using a `Authorization` HTTP header. + +Note that for clients that are browser-based, including the Altinn.no-portal, the resource server will also have to implement the [CORS-protocol](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) in order to handle requests + +### List of Dialogporten specific claims + +| Claim | Description | Example | +|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------| +| c | Authenticated as a consumer of Dialogporten. The prefix for either individuals (typically ID-porten), organizations (typically Maskinporten), or self-registered users. | `"urn:altinn:person:identifier-no::12018212345` `"urn:altinn:organization:identifier-no::991825827"` `"urn:altinn:party-identifier:username::someemail@example.com"` | +| l | Security level of authentication (4) | `4` | +| u | Optional. If a provider token in Maskinporten has been used, the authenticated provider's organization number will be given here. | `"urn:altinn:organization:identifier-no::991825827"` | +| p | Whom the consumer is acting on behalf of (if not themselves), i.e., who owns the relevant dialogue. | `"urn:altinn:person:identifier-no::12018212345"` `"urn:altinn:organization:identifier-no::991825827"` `"urn:altinn:party-identifier:username::someemail@example.com"` | +| i | Unique identifier of the dialogue. | `"e0300961-85fb-4ef2-abff-681d77f9960e"` | +| s | The service resource that the dialogue refers to. | `"urn:altinn:resource:super-simple-service"` | +| a | Authorized actions/authorization attributes. | `"read;write;sign;elementread,urn:altinn:subresource:authorizationattribute1"` | + +#### Example of decoded token + +```json +{ + "alg": "EdDSA", + "typ": "JWT", + "kid" : "dp-2023-01" +} +// . +{ + "c": "urn:altinn:person:identifier-no::12018212345", + "l": 4, + "u": "urn:altinn:organization:identifier-no::825827991", + "p": "urn:altinn:organization:identifier-no::991825827", + "i": "e0300961-85fb-4ef2-abff-681d77f9960e", + "s": "urn:altinn:resource:super-simple-service", + "a": "read;write;sign;elementread,urn:altinn:subresource:autorisasjonsattributt1", + "exp": 1672772834, + "iss": "https://dialogporten.no", + "nbf": 1672771934, + "iat": 1672771934 +} + +// . +// +``` +### Token signature cipher + +Dialog tokens utilizes a [Edwards-Curve Digital Signature Algorithm (EdDSA)](https://datatracker.ietf.org/doc/html/rfc8032) using the Ed25519 curve to sign the dialog tokens, making it possible to consumers to verify that the token has been issued by Dialogporten and trust the information in the claims. Also see [RFC 8037](https://datatracker.ietf.org/doc/html/rfc8037) for information about using EdDSA in JOSE contexts. + +### Well-known endpoints + +Dialogporten provides [OAuth 2.0 Authorization Server Metadata (RFC8414)](https://datatracker.ietf.org/doc/html/rfc8414) allowing for runtime key discovery, rotation and token validation. Consult the [OpenAPI specification]({{}}) (tag "Metadata") for the well-known URLs for the given environment. + +### Key sets and rotations +The JSON Web Key sets published on the well-known-endpoints will always contain at least two JWKs. All endpoints that accepts and verifies dialog tokens issued by Dialogporten, should allow tokens signed by any of the keys present in the key set for the given environment. + +The key set should be cached and refreshed with a frequency no more than 24 hours. Dialogporten will at any point introduce new keys into the key set, but will not sign any dialog tokens until the key has been published and available at the well-known endpoint for at least 48 hours. This will allow for consumers to refresh their caches and verify the signature of any token issued by Dialogporten. + +### Token validation recommendations +Please consult [RFC 8725](https://datatracker.ietf.org/doc/html/rfc8725) and the aforementioned RFCs for information about best practices for JWS signature validation. -For now, refer to the [OpenAPI specification]({{}}). {{}}