-
Notifications
You must be signed in to change notification settings - Fork 0
Workflows
For the authentication of the user with his pension fund and the granting of consent for data access, there is a standardised process that is to be implemented by the common API applications.
To retrieve data from a pension fund, a typical common API pension app needs to implement four steps:
- Pension Fund Selection: A list of pension funds is presented, and the user picks his/her pension fund.
- Authentication: The pension fund presents a login page, and the user provides the credentials for his/her pension fund account.
- Consent Granting: The pension fund presents a page asking for the user's consent (app is allowed to access user's pension fund data), and the user grants the consent.
- Data Access: The app retrieves pension fund data and displays it to the user.
The UI flow is controlled by the app even though the UI for step 2 and 3 and implemented by the pension fund.
The app will likely save the selected pension fund, and the granted consent is saved by the pension fund. So on subsequent uses of the app, these steps are no longer needed.
The app can optionally request a refresh token in step 2 so it can access the user's pension fund data at any time without requiring his/her presenence. Thus after the first use, step 2 can be replaced by a simpler step without user interaction.
The differences between the first and subsequent uses are shown in the table below:
Step | First Use | Subsequent Uses |
---|---|---|
Pension Fund Selection | The app retrieves a list of all pension funds from the directory serivce and presents it to the user. The user select his/her pension fund. | The step is skipped as the user's selection has been saved. |
Authentication | The pension fund displays the login page and the user logs in. | The pension fund displays the login page and the user logs in. Or: The app requested a refresh token on first use. The refresh token can now be used to request an access token. |
Consent Granting | The pension fund asks if the app may access his/her pension fund data, and the user grants it. | The step can be skipped as the granted consent has been saved by the pension fund. It is required again if the user revokes the consent. |
Data Access | The app accesses the user's pension fund data. | The app accesses the user's pension fund data. |
The security setup is based on the authentication and authorization framework OpenID Connect (OIDC), a layer on top of the OAuth 2.0 protocol.
The pension fund APIs are provided by servers that require an access token for access. They act in the role of resource servers. The app can get an access token by either initiating and completing the OIDC/OAuth 2.0 authentication flow, or by requesting an access token using an earlier provided refresh token. The authentication flow (login) is implemented by the identity provider (IdP) of each pension fund.
To initiate and complete the authentication flow, the app needs a client ID and client secret from the pension fund (in addition to the user authentication/consent). Currently, they have to be requested in a manual process (from Acrea).
Whenever the app requests pension fund data, the request is executed on behalf of a single insured person. In order to access data from several persons (e.g. for a couple or for offline batch processing), seperate access tokens (and possibly request tokens) are needed.
In an OIDC setup, the consent granting step is often integrated into the authentication flow. No so for Pension Common API. It's a separate flow that must be initiated after the authentication flow has been completed.
The entire flow is shown in the diagram below and described in detail in the following chapters.
The pension fund selection is fully implemented by the application. It can implement a suitable UI, supporting text search or auto-completion.
The list of pension funds can be retrieved via an API from the directory service (see API description). No authentication is needed to access the service.
The selection result are details about the pension fund:
- Fund ID
- Fund name
- Technical details:
- URLs for authentication flow
- URL for consent granting flow
- Base URLs for the different APIs
In JSON, it look like the folowing:
{
"id": "SR-215541",
"name": "Fondation des Fabriques de Tabac Réunies SA",
"nameFr": "Fondation des Fabriques de Tabac Réunies SA",
"address": "Quai Jeanrenaud 3, 2000 Neuchâtel",
"openpkStatus": "active",
"openpkServices": {
"authorizeUrl": "https://iam.openpk.acrea.com/auth/realms/pensionfund/protocol/openid-connect/auth",
"tokenEndpoint": "https://iam.openpk.acrea.com/auth/realms/pensionfund/protocol/openid-connect/token",
"identityProvider": "https://iam.openpk.acrea.com/auth/realms/pensionfund",
"grantUrl": "https://star-fund-dot-acrea-openpk.appspot.com/consents/grant?fund_name=Fondation+des+Fabriques+de+Tabac+R%C3%A9unies+SA",
"policyEndpoint": "https://star-fund-dot-acrea-openpk.appspot.com/v1",
"consentEndpoint": "https://star-fund-dot-acrea-openpk.appspot.com/v1"
}
}
The fund ID can be stored indefinitely. The other attributes should be regularly refreshed by retrieving the latest data from the directory service.
This part of the flow is only required on the first use. On subsequent uses of the app, the stored data can be used.
The authentication flow is mainly controlled by the pension fund's IdP. It must be run in a browser or web view. It starts by opening the authorization URL. Then the IdP takes control. It may show several HTML pages to the user for entering the username, entering the password, requesting a second factor etc. When the user interaction has been completed, the previously provided redirect URI is opened to hand control back to the application and to pass an authorization code. Using the authorization code and the client secret, the application can then retrieve the access token from the IdP.
This flow is a standard OpenID Connect / OAuth 2.0 flow and therefore not described in detail here. The IdPs currently support two flow variants:
- Authorization Code Flow
- Authorization Code Flow with PKCE
The required URLs are provided by the directory service. There are two options:
-
OpenID Connect (recommended): Use the IdP issuer (identityProvider element, e.g. https://iam.openpk.acrea.com/auth/realms/pensionfund) to configure a OpenID Connect library. Based on this issuer URL, the library will query the OIDC configuration (e.g. https://iam.openpk.acrea.com/auth/realms/pensionfund/.well-known/openid-configuration), which provides the URLs to endpoints, certificates etc.
-
OAuth 2.0: Use the authorizeUrl attribute to start the flow and the tokenEndpoint attribute to retrieve the access token.
This part of the flow is always needed unless refresh tokens are used. Refresh tokens are also part of OpenID Connect and OAuth 2.0 and documented in the respective standards.
Note:
- If the authentication flow is executed several times within a few minutes and from the same browser, the IdP might regard the user as already logged in and immediately hand back the control to the application without showing any web pages to the user.
- The authentication flow cannot be run in an IFRAME. Most IdPs will prevent this for security reasons.
The consent granting flow is similar to the authentication flow in that it is run in a browser or web view, shows HTML pages to the user and finally hands back control to the application by opening a previously specified redirect URI.
To initiate it, the grantURL (provided by the directory service) is opened with the following additional query parameters:
Parameter | Required | Purpose |
---|---|---|
redirect_uri |
Required | The URL to open at the end of the consent granting to pass control back to the application |
client_name |
Optional | The application name (displayed when asking for consent). Ignored in a fully productive setup. |
When the consent granting is complete, the provided redirect URL is opened to pass control back to the application. An additional query parameter is appended to the URL:
Parameter | Value |
---|---|
result |
success if the user has granted the consent, fail if the user has cancelled the flow |
This part of the flow is required if the user has not yet granted the consent to the application for accessing the pension fund data.
With a valid acces token, the application can always query if the user has granted consent and what objects for (person, policies). See Consent API, endpoint /users/me
. So the application can first test if this flow is required or not. It certainly is required the first time but it might also be required later as the user can revoke the consent at any time.
The same endpoint is also needed to learn the person and policy IDs of the current user. They are needed for most subsequent APIs.
Note:
- The grantURL attribute may already contain query parameters. So care must be taken when appending the additional parameters.
In the current sandbox environment, a user can grant or revoke a consent at any time and without using a specific application by visiting a web site. The URLs are:
- Grant consent: https://star-fund-dot-acrea-openpk.appspot.com/consents/grant (required parameters see below)
- View and optionally revoke consent: https://star-fund-dot-acrea-openpk.appspot.com/consents
The parameters for granting consent are:
Parameter | Required | Purpose |
---|---|---|
redirect_uri |
Required | The URL to open at the end of the consent granting to pass control back to the application |
client_id |
Required | The client ID assigned to the application. The same ID is used in OIDC/Auth 2.0 requests. |
client_name |
Required | The application name (displayed when asking for consent). Ignored in a fully productive setup. |
In the real world, a user can at least revoke a consent at any time. To do so, he/she logs in to his/her pension fund's portal, goes to the consent management page and revokes the consent for one or more applications.
Once the application has a valid access token and the user has granted access to the application, it can retrieve pension fund data using the Policy API, Purchase API etc.
In order to do so, the application must add the access token (aka bearer token) to the HTTP heaeder of each request:
Authorization: Bearer VGhpcyBpcyBqdXN0IGFuIGV4YW1wbGUgYW5kIG5vdCBhIHZhbGlkIEpXVCBhY2Nlc3MgdG9rZW4u
Several tools exist that can take the YAML file of an API and generate the client code for the API. They support a variety of programming languages and frameworks. And they usually support bearer tokens out of the box.
- In the sandbox, all pension funds point to the same API implementation (called ABC Fund). Therefore, the granted consent is valid for all pension funds (but just a single user and single application).
- Any valid login will result in valid pension fund data. In a repeatable process, each user is automatically assigned one of about 40 datasets.
- In addition to the provided logins, it is also possible to login via SwissID. To do so, a user must first open an identity/account in SwissID's integration environment https://login.int.swissid.ch/. When the pension fund login page is presented, the user must then click "SwissID" and will be redircted to the SwissID login page.
- Initially, skip the pension fund selection. Instead, pick a single pension fund from https://directory-dot-acrea-openpk.appspot.com/v1/pension-funds and work with it until the other steps have been successfully implemented. Then implement the pension fund selection.
- For the authentication, use a tried and tested OpenID Connect client for your programming language and framework, e.g. from the list on https://openid.net/developers/certified/. Don't try to implement it yourself.
- For single page apps (UI is implemented in Javascript running in the user's browser) and for mobile apps, use the Authorization Code Flow with PKCE. That way, the app can retrieve and use the access token directly. For apps with an extensive backend or with server-side HTML rendering, the Authorization Code Flow (without PKCE) can be used. It is more secure and supports refresh tokens for offline access. But the backend will have to make the Pension Common API requests on behalf of the client application.
- Initially, don't implement the consent granting. Instead, have the user visit the consent granting UI in advance (see URLs for Consent Management UI). It is a one-time action for the user.
- Use a generator to generate the code for the API access (e.g. https://github.com/OpenAPITools/openapi-generator).
SFTI | ca-pension
Wiki
API specific Information
Version Management
Common Implementation Guidelines