Altinn / Altinn/app-lib-dotnet

Maskinporten integration for Studio and Apps to enable server-to-server communication

Open
#492 1 comment 0 reactions 2 assignees Claimed by @HauklandJ View on GitHub
Epic status/draft
Dominant language
C#
Stars
8
Forks
27
Avg merge
1h 21m
Merged PRs (30d)
7

Description

### Description

More and more apps in Altinn 3 need server-to-server integration with other apps and services,
and the primary mechanism for authn/authz is Maskinporten (the server-to-server variant of ID-porten).

It is possible to setup today, but is not straight forward and requires support and (too much) technical competence.

We want server-to-server integration in the Altinn (and adjacent) ecosystem to be seamless and simple for application developers.

### In scope

Letting app developers easily create Maskinporten client/scopes to integrate with apps

### Out of scope

_No response_

### Additional Information

### User stories

> As [a user persona], I want [to perform this action] so that [I can accomplish this goal].

* As an app developer in Altinn Studio, I want to find the docs related to maskinporten integration, to see the necessary steps I need to take to configure my app, and gain a mental model for the architecture, communication structure etc
* As an app developer in Altinn Studio, I want to add eFormidling scopes to my apps Maskinporten client through Studio, so that I can integrate my app with services such as eFormidling
* As an app developer, I want to easily fetch access token from Maskin porten in my app code, so that I can call the external APIs I need
* As an app developer, I want to revoke or delete scopes that I no longer need, so that I follow the principle of least privilege and the configuration of the app reflects what is currently in use/needed
* As an app developer, I want to see which scopes are currently being used/fetched tokens for, so that I have visibility into the boundaries of my app
* As an app developer, I don't want to manually manage JWKS, because I will forget and cause an outage
* As an app developer, I want to see the current status of active and expired JWKS, to make sure they are being rotated properly and my configuration is secure

### Acceptance criteria

> Scenario: (explain scenario). Given (how things begin), when (action taken), then (outcome of taking action)

* Scenario: developer is creating an app that needs to publish events to Altinn Events
* Given I'm logged in to Altinn Studio with my ID-porten/Ansattporten-user, when I enter the app Maskinporten client page and add a 'publish' scope for Altinn events, the scope is added to the list of active scopes, and I'm instructed and given some example code on how to make use of the scope from Altinn app/library code
* Given I'm developing locally, when I run my app locally with maskinporten client configured in Altinn studio, I should be able to use the Maskinporten client from lib with personal credentials/JWKS

#### Non-functional

* JWKS should be rotated automatically (transparently for app developers)
* New keys every week
* Old keys removed every month

### Prior work/inspiration

Docs:
* https://docs.altinn.studio//nb/app/guides/maskinporten-app-integration/
* https://docs.altinn.studio//notifications/send-notifications/get-started/maskinporten-integration/

Code:
* https://github.com/nais/digdirator
* https://github.com/Altinn/altinn-apiclient-maskinporten

### Challenges and discussion

* Altinn Studio - login, authn/authz management
* Need secure login (account issued by ID-porten/Ansattporten or similar) to have better security posture?
* Need secure access in the context of an org to be able to list available scopes
* There may be some scopes that need further security that may reveal secret/sensitive information - maybe some scopes requires special approval?
* Some users might not find a scope they want to use - how is access management to scopes handled?
* ID-porten/Maskinporten team are working on system users. Current tokens are scoped to the organization
* How to provide a nice local development story
* Extend localtest to be able to create developer-specific Maskinporten-client and create short-lived JWKS? Would need to authenticate local user and call Maskinporten APIs
* Alternatively let user manually provide client/keys information, e.g. on filesystem
* Proposal: let the operator/Studio (Maskinporten only needs pub key in the end) generate secondary set of keys for local use, when the environment being configured is used for test/dev. The secondary set of keys can be exposed to the developer through Altinn Studio. The keys are generated once, and the developer can copy paste these into some local configuration for `app-localtest`
* We will probably be asked to provide easier ways of testing integration based on Maskinporten auth - testing requests straight from the portal?
* Will the architecture proposed impose too much coupling to Kubernetes or Azure infra?
gitt ansattporten-tilgang til studio
* Given ansattporten-login to access altinn studio, then there is still the possibility of a dishonest actor - with access to the relevant organisation in Gitea and NOT via ansattporten - being able to change the requested scopes by editing the file. The additional requested scopes would have to be registered as accessible by the organisation.

### Architecture

Diagram: https://raw.githubusercontent.com/Altinn/altinn-k8s-operator/main/docs/maskinporten.drawio.svg

#### ADR

Per-app infrastructure provisioning: https://github.com/Altinn/architecture-decision-log/issues/8


### Deployment

Plan?

### Operational

#### Telemetry

* altinn_maskinporten_clients_created
* Labels/attrs: te, app,
* Purpose: Tracks the number of clients registered to use the service. An increasing count indicates new user adoption or existing users scaling their integration.
* altinn_maskinporten_jwks_created - counter metric
* Labels/attrs: te, app,
* Purpose: Monitors the number of JSON Web Key Sets (JWKS) created. This metric can signal the setup of new secure connections or the rotation of keys for security purposes.
* altinn_maskinporten_tokens_request - counter metric
* Labels/attrs: te, app, response (success | fail)
* Purpose: Measures the number of token requests, categorized by their success or failure. This can help in identifying the reliability of the token service and potential issues in the authentication process.

#### SLIs

* altinn_maskinporten_clients_created, altinn_maskinporten_tokens_request
* Using these as SLIs should give us some indication that the feature is utilized and worthwhile
* altinn_maskinporten_tokens_request
* If we get significant numbers of failed token requests, that might indicate
* Buggy implementation on our side
* Weak abstractions that leads to misconfiguration/misuse
* Weak documentation that leads to misconfiguration/misuse

### Tasks

- [x] Build user stories/acceptance criteria
- [x] Design and architecture
- [ ] Decide on test-process
- [x] Decide on local dev process
- [x] Build development issues/tasks and estimate
- [x] Deployment plan with maskinporten and studio
- [x] #544

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.