Using the Resource Management API
The Resource Management API adds information to the response of the /userinfo endpoint, and adds a new endpoint /resources. This enhances a user's ability to manage resources, some of which may belong to other users. This level of authorization is governed at the Resource Server level. In some cases, the Resource Server may provide users with the required permissions to manage their resources and the delegation of their resources.
Prerequisites
In order to use this functionality, the following conditions must be met:
- The user has logged in at the RSA to acquire a valid access token to use at the Resource Server.
- The internal access token in the RSA is still valid.
Operations
Creating authorizations
Authorizations to resources are created via the Admin API in order to establish the authorizations for resources owned by users.
Depending on different implementations and extensions of the RSA's functionality, the tables involved in holding user resources and their authorizations can be modified via other means. In these implementations, the RSA is expected to update these tables when access to user resources change, in order to maintain them as a source of truth. However, in the base implementation, only the Admin API may modify these tables.
Retrieval of Authorized Resources
In the standard flow, a user will usually visit the /userinfo endpoint first in order to access their own information. As part of this feature, a new field related
is present amongst the standard OIDC claims within:
{
"sub": "sally-id",
...
"related": [
{
"sub": "ethan-id"
"firstname": "Ethan"
},
{
"sub": "alice-id"
"firstname": "Alice"
}
]
}
...
This example demonstrates what a related
claim would look like when a user has authorizations for two other users' resources (Ethan and Alice).
This related
claim is an array of JSON objects that return a list of parties that are authorized to use some resources from the calling user or where the calling user has some authorization to use resources from these parties.
Next, the user would attempt to call the /resources endpoint after seeing that they have authorizations intertwined with other parties. The /resources endpoint would list out all the resources which the user may access based on the authorizations they were given by other parties, as well as resources owned by the user. An example response is provided below:
[
{
"sub": "sally-id",
"id": "string",
"type": "string",
"location": "string",
"description": "FHIR Record",
"name": "FHIR Record",
"as_uri": "string",
"resource_scopes": [
"user/*.*"
],
"content_types_supported": [
"string"
]
},
{
"sub": "ethan-id",
"id": "string",
"type": "string",
"location": "string",
"description": "FHIR Patient",
"name": "Ethan's FHIR Record",
"as_uri": "string",
"resource_scopes": [
"user/Patient.read"
],
"content_types_supported": [
"string"
]
},
{
"sub": "alice-id",
"id": "string",
"type": "string",
"location": "string",
"description": "FHIR Patient",
"name": "string",
"as_uri": "string",
"resource_scopes": [
"user/Patient.read"
],
"content_types_supported": [
"string"
]
}
]
This example demonstrates the response of the /resources endpoint for a user (Sally) who has authorizations for two other users' resources (Ethan and Alice).
If the related
field is empty, the flow will continue to check the /resources endpoint and list available resources.
User's Owned Resources
The Resource Management API can return the user's owned resources listed in the fpx_resource table. This functionality is managed using the application.yml value fpx.resourcemanagement.include_owned_resources
. When set to true, the /resources endpoint will also include entries for resources in the fpx_resource table owned by the user calling the endpoint.
Configuring a Resource to always be available
There can be situations where certain resources, such as the base profile of the logged in user (the userinfo response), would need to be configured so that they always show up in the /resources response even when there is no entry in the fpx_resource table. For this purpose, the resources table which defines the resources that the RSA provides, has a column is_available_by_default. When set, an entry for the resource (with the owner set to the calling user) will be added to the Resource Management API response even when the calling user does not have an entry for it in the fpx_resource table.
The is_available_by_default
column comes into effect only when the fpx.resourcemanagement.include_owned_resources
parameter is set to 'true' in the application.yml file.
Wallet as a Consumer of the Resource Management API
While the Resource Management API can be consumed by any calling application, IDENTOS recommends the usage of this API with the FPX Wallet Server for a seamless, highly integrated user experience.
The Wallet Server implements functionality that allows it to interface with the Resource Management API in order to learn of a user's authorizations to access certain resources belonging to other users. It also contains functionality that allows users to use these authorizations in place of their own resources in an FPX flow when requested by a service provider.
Prerequisites
In order to use the Resource Management features within the Wallet, the following conditions must be met:
- The Wallet Server must have a Resource Server registered.
- The Resource Server must be configured to enable Resource Management API functionality.
- The user must be logged into the Wallet Server.
- The user must be able to log into the Resource Server where the authorizations have been configured.
Using the Resource Management API Functionality
Authorized access to resources are represented as additional datasource accounts (DSA) which are created alongside the datasource account normally created when connecting to a datasource.
In order for the Wallet Server to acquire data from an RSA's Resource Management API, first start the datasource connection flow. Using the webUI or mobile app, this would be done by clicking "Connect", "Reconnect", or "Renew" on a datasource on either the screen which displays connections, or the screen in the consent flow where a client asks the user to share data.
Once you have passed through the RSA's mechanisms for logging in, the Wallet Server will attempt to create the datasource account for it as usual. Then, the Wallet Server will look at the userinfo response- specifically the related
array to see if the user has additional resources available to them in addition to their own. If so, the Wallet Server will attempt to access the /resources endpoint on the RSA, which provides a list of the resources that the user has access to (include ones owned by them).
From the RSA's /resources endpoint, the Wallet Server expects a response that looks like this:
[
{
"sub": "sally-id",
"id": "string",
"type": "string",
"location": "string",
"description": "FHIR Record",
"name": "FHIR Record",
"as_uri": "string",
"resource_scopes": [
"user/*.*"
],
"content_types_supported": [
"string"
]
},
{
"sub": "ethan-id",
"id": "string",
"type": "string",
"location": "string",
"description": "FHIR Patient",
"name": "Ethan's FHIR Record",
"as_uri": "string",
"resource_scopes": [
"user/Patient.read"
],
"content_types_supported": [
"string"
]
},
{
"sub": "alice-id",
"id": "string",
"type": "string",
"location": "string",
"description": "FHIR Patient",
"name": "string",
"as_uri": "string",
"resource_scopes": [
"user/Patient.read"
],
"content_types_supported": [
"string"
]
}
]
For each of the resources in the response not including the one representing the user's own userinfo, the Wallet Server will create a datasource account. These datasource accounts are different in that they are not tied to the user's OpenID account, but are tied to the user's own datasource account which was just created. When access to the main datasource account is revoked, the additional datasource accounts are also revoked.
Datasource Accounts created for Related Users
The additional datasource accounts each represent a different related user found in the response of the /resources endpoint at the RSA. At the moment, this API is only used to facilitate access delegation- where other users may delegate access to resources owned by them to other users. In a consent flow, using one of these datasource accounts instead of the main one will cause the access to another user's resources to be shared, which in turn allows the service provider to acquire the other user's delegated data instead of the user's own data.
Using these different datasource accounts in a consent flow result in permissions being created like when using a normal DSA, but there are a few differences:
- The resource owner tokens in the permissions contain a resource_owner field which denotes that the resource referenced is owned by someone else.
- This allows the RS/RSA during token introspection to handle the PEP needed where the client is acting on behalf of the relying part who is granting access / acting on behalf of a different user.
- Using the tokens in the permissions at the RSA results in the other user's information being returned instead of the calling user's own information.
Datasource Account Relations Endpoint
As part of this feature, the Wallet Server also exposes an endpoint that allows a consumer of the Wallet Server's API to distinguish which DSAs represent the user, and which DSAs represent other parties at the Resource Server who have delegated access to their resources to the user.
The endpoint is exposed as GET /me/data-sources/{datasource_id}/relations, and returns a response of this format:
[
{
"sub":"sally-id",
"name":"FHIR Record",
"related":[
"ethan-id"
]
},
{
"sub":"ethan-id",
"name":"Ethan's FHIR Record",
"related":[]
}
]
This endpoint's response denotes the relationships between the different subs found on the user's DSAs from a particular datasource. It allows the API consumers to distinguish which DSAs are related to other DSAs, which UI applications can use to figure out which DSAs are the primary DSAs representing the user, and which DSAs are representing delegated access.
In the above example, the sub "ethan-id" belongs to a related user, and the sub "sally-id" represents the user calling the endpoint. Each of these subs would be found on two different DSAs which were created from the Resource Server that exposed the Resource Management API.
Resource Synchronization
Datasources can be configured to synchronize the datasource account resources of users in a number of different ways, using the resource_managament_api_mode
column.
This column is an enumeration of the values DELEGATED_ONLY, and ALL_RESOURCES.
- When a datasource is set to DELEGATED_ONLY, datasource accounts from that datasource will only synchronize the resources of delegated accounts found in the Resource Management API response. Datasource accounts which are not RS-delegated (aka belong to the user creating it) will be assumed to have access to all resources registered on the data source within the wallet server. This was the behaviour of all datasources prior to this particular piece of functionality added, and so all datasources will be set to this mode by default.
- When a datasource is set to ALL_RESOURCES, datasource accounts from that datasource will synchronize all resources, including the user's owned resources. In doing this, it will also expect the user's own resource to appear in the Resource Management API response. If they are missing, the datasource account will be treated as if it had no resources.
With this feature, datasource accounts also disable themselves if they have no active resources on them remaining.
When Synchronization Occurs
The Resource Management API of resource servers are checked when any of the following conditions are met:
- The user attempts to connect or renew a connection to a datasource
- The user attempts to push permissions using a datasource account
Upon using a datasource account to push permissions, the Wallet Server attempts to access the Resource Management API in order to update the resources on the data source accounts involved.
On a failed fetch and update, the permission pushing flow may still proceed as normal, but a warning will be included with the response of the permission creation endpoint request, and the service provider may find themselves unable to fetch the resources later during the flow if resource availability has changed. On a successful fetch and update, no warnings will appear in the response, and the flow can proceed as normal.