You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For a long time we've anticipated the need for making requests not in the context of a user, but in the context of the app itself. This issue will detail why and when/where we need it from the current state of the library and to support future work around the process engine
In scope
Mechanisms to support authorization against other services inside and outside Altinn 3 without a users token
Out of scope
No response
Additional Information
In a meeting with members from Core and Authorization, we landed on 2 possible solutions that we need to investigate.
Idea 1
Authorization/Authentication has an endpoint for creating an app-specific token
The token is contextualized with instance ID and possibly other claims (e.g. to make it possible to implement something like CausedBy in InstanceEvents in Storage)
Issued as a normal Altinn token
Would require XACML policy changes and would therefore require a major bump for app-lib
Unless a special case fallback policy is implemented in Authorization
Or Studio changes the policy upon deploy
This token would hopefully be usable from Storage, Correspondence, Dialogporten, Register, Profile etc
Create a default/built in MaskinportenClient per app with some default scopes (e.g. instance.write)
Authorization would not be based on XACML policy
For Storage: send both Maskinporten token and Platform Access Token (PAT), so that InstanceEvents can be populated from PAT?
Idea 3
Create a MaskinportenClient + System user per app with some default scopes
Actions taken by this system user would then be better reflected in instance events/activity log, since we would solve this for system users in general
Would require XACML policy changes in apps
Idea 4
Custom Rich Authorization Request (RAR) flow for apps
Authorization would not be based on XACML policy
We can enforce JWKS access through k8s using ServiceAccounts
Analysis
Reasons for requiring an app-user/token:
Reliability
The process engine in Altinn.App.Core is the core component driving an instance forward. As of now, all tasks, transitions and therefore integrations are driven by the users request, and so practically anything that fails inside an app is returned to the client. In principle, the client request should only be concerned with wether or not the instance is in a valid state to transition to the next task of the process. Before initializing the next task (which may be an IServiceTask), we should be able to return a 200 OK to the client so that they can either wait for the next user-task or wait until a service task is complete (in practice we might just hold onto the client request if the next task also is process task requiring the users interaction, but the principle should hold). This naturally leads to errors in background processing, cleanup and service tasks being decoupled from clients (more work become async, and will require robust and configurable error handling). That however also means that we can't use the users token for example when writing to Storage as it may expire. In the future, process/next might even be triggered from background threads across reboots etc.
User-controlled/parallel signing
We need to delegate permissions that the instance owner doesn't have (we will be using the PlatformAccessToken for the Delegation API)
We need internal state related to the signing process that is owned by the app (strictly for bookeeping/reliability, and the user should not see this data directly)
We need to create Correspondence messages for each signee. Ideally the user shouldn't receive/see these messages before (technical requirement is that this type of process task needs to be implemented as a saga/state machine. Reliable, ordered execution of steps with atleast once delivery and idempotent handlers)
Read/sign permissions are delegated
The instance process has advanced to the signing task
When every signee has signed, we should be able to advance the process to the next task automatically and in the background (the last signee shouldn't necessarily be involved in the next task at all)
IServiceTask - BPMN Service Tasks
A few built-in ones: PdfServiceTask, EFormidlingServiceTask
Dialogporten future (phase 2?) implementation is likely to be implemented as a service TASK
Users can define their own service tasks. When they do, we need to have abstractions or configuration which they can use to express failure handling like retries. This implies that these tasks may run in the background irrespective of client activity (in the future). Therefore we will also need a way for the Execute function of these service tasks to access credentials and/or clients that can be used in the background, when an authorized client isn't present
Misc cleanup and bookkeeping
When creating datalements for signatures and PDFs, we need to make sure there is only one. There is cleanup logic present to handle cases where the users navigates back and forth between the signing and form tasks in which these dataelements have to be recreated. We should be able to do this bookeeping irrespective of the logged in users' permissions.
EFormidling and other features requiring Maskinporten integration (eFormidling itself does not require Maskinporten, but the dependency on Altinn Events does)
The eFormidling feature built into the app currently requires the user to also setup and configure Maskinporten auth. Ideally there was a simpler path to enabling eFormidling. Is eFormidling is supposed to be a built in feature/capability of Altinn 3, maybe apps should be authorized to integrate by default.
For eFormidling there is also code for sending a "reminder" event to Altinn Events, notifying back to the app itself that we need to check the status for the message order. The events client also requires the current users token (e.g. runtime cookie). If we were to support reliable async delivery in the process engine, we need to be able to do more in the background, and thus can't use the users token. The Altinn Events integration currently both uses the user-token and the PlatformAccessToken.
Other platform API such as Notification, Profile, Register could possibly also be useful for implementing service tasks, although they are not the primary drivers for us atm
Permissions needed for builtin functionality
altinn/instances.read altinn/instances.write
altinn/correspondence.write (for signing)
digdir:dialogporten
Slightly related:
Service owners need to build receiver systems that interact with the app/storage APIs. Large service owner orgs maybe have different teams maintaining different apps, in which case the org-scope becomes too broad in terms of auth. Ideally a service owner team could create client/resource to do more granular app level authorization aside from org-level. The app user/token scenario described in the issue is different (the app is the caller), but for receiver systems the caller will run outside Altinn/app clusters.
Conclusion
Initially we will go with idea 1 - custom/in-house solution using Altinn Authentication.
The text was updated successfully, but these errors were encountered:
Description
For a long time we've anticipated the need for making requests not in the context of a user, but in the context of the app itself. This issue will detail why and when/where we need it from the current state of the library and to support future work around the process engine
In scope
Out of scope
No response
Additional Information
In a meeting with members from Core and Authorization, we landed on 2 possible solutions that we need to investigate.
CausedBy
in InstanceEvents in Storage)Analysis
Reasons for requiring an app-user/token:
IServiceTask
), we should be able to return a 200 OK to the client so that they can either wait for the next user-task or wait until a service task is complete (in practice we might just hold onto the client request if the next task also is process task requiring the users interaction, but the principle should hold). This naturally leads to errors in background processing, cleanup and service tasks being decoupled from clients (more work become async, and will require robust and configurable error handling). That however also means that we can't use the users token for example when writing to Storage as it may expire. In the future, process/next might even be triggered from background threads across reboots etc.IServiceTask
- BPMN Service TasksPdfServiceTask
,EFormidlingServiceTask
Execute
function of these service tasks to access credentials and/or clients that can be used in the background, when an authorized client isn't presentPermissions needed for builtin functionality
Slightly related:
Conclusion
Initially we will go with idea 1 - custom/in-house solution using Altinn Authentication.
The text was updated successfully, but these errors were encountered: