Entitlements Service
Table of contents
Introduction
Entitlements service is used to enable authorization in Data Ecosystem. It relies on Google groups as an infrastructure that ties into Google IAM making native authorization a possibility. The service allows for the creation of Google groups. A group name defines a permission. Users who are added to that group obtain that permission. The main motivation for entitlements service is data authorization but the functionality enables three use cases:
- Data groups used for data authorization e.g. data.welldb.viewer, data.welldb.owner
- Service groups used for service authorization e.g. service.storage.user, service.storage.admin
- User groups used for hierarchical grouping of user and service identities e.g. users.datalake.viewers, users.datalake.editors
For each group you can either be added as an OWNER or a MEMBER. The only difference being if you are an OWNER of a group, then you can manage the members of that group.
Group naming strategy
All group identifiers (emails) will be of form {groupType}.{serviceName|resourceName}.{permission}@{slb-data-partition-id}.{domain}.com with:
- groupType ∈ {'data', 'service', 'users'}
- serviceName ∈ {'storage', 'search', 'entitlements', ...}
- resourceName ∈ {'welldb', 'npd', 'ihs', 'datalake', 'public', ...}
- permission ∈ {'viewers', 'editors', 'admins' ...}
- slb-data-partition-id ∈ {'slb', 'common', ...}
- domain ∈ {'instance.osdu.opengroup.org', ...}
As shown, a group is unique to each data partition. This means that access is defined on a per data partition basis i.e. giving a service permission in one data partition does not give that user service permission in another data partition. See below for more information on data partitions.
Group naming convention
Due to some limitations on the Google Cloud Identity, a group naming convention has been adopted, such that the group's name should start with the word "data." for data groups; "service." for service groups; and "users." for user groups. The group's name is case-insensitive. Please refer to group creation guideline under the API section for more details.
Basic concepts
Domain
A domain is the top level online address that Schlumberger operates DELFI on e.g. delfi.slb.com.
Data partition
Data Ecosystem is a multi-tenant solution with two layers of isolation: data partition isolation and data access isolation. A data partition represents a strong separation of all data between clients. Data access isolation is achieved with dedicated ACL (access control list) per object within a given data partition.
All groups and permissions are unique at the data partition level, meaning granting permissions in one data partition has no affect on any other data partitions.
Elementary data partition groups
When a data partition is provisioned, corresponding group is created: users (e.g., users@instance.osdu.opengroup.org).
Group named users contains all the identities that are allowed access to the data partition in question. When a contract is created in DELFI, we create the corresponding data partition in the Data Ecosystem and all user identities are added to the users group of the corresponding data partition.
Relevant Data Ecosystem headers
To deal with data partitions and to be able to track user identities, Data Ecosystem introduces two headers:
- slb-data-partition-id - required header for all Data Ecosystem APIs used to determine the data partition context for the call.
- slb-correlation-id - optional header for all Data Ecosystem APIs used to trace the API call. If slb-correlation-id value is provided in the request, the same value is used in the response. If no slb-correlation-id header is provided, then entitlements service generates a GUID for this field in the response.
Applicable slb-data-partition-id values are:
Environment | slb-data-partition-id |
---|---|
ProD | slb, customer, common |
Authentication and Authorization
Authentication
Both AppKey and SAuth token are required to be provided when calling Entitlements APIs.
Authorization
The SAuth app or client needs to be granted authorization through developer portal to the requested data partition, if the provided token is issued by the SAuth app or client. Note: common data partition is public to all SAuth app and client. The user encoded in the JWT needs to be added into the proper contract, to be granted permission to the requested data partition.
Entitlements service also requires users or services to have the following authorization to access the APIs. Users' authorization is automatically granted if they are added to the proper contract. For new users, authorization is granted instantly.
- Valid data partition member - Entitlements service checks whether the member ID from the Authorization header consisting of JWT belongs to users@{data-partition-id}.instance.osdu.opengroup.org, where {data-partition-id} information is received from slb-data-partition-id header.
- Valid entitlements service user - Entitlements service checks whether the member ID from Authorization header consisting of JWT belongs to service.entitlements.user@{data-partition-id}.instance.osdu.opengroup.org, where {data-partition-id} information is received from slb-data-partition-id header.
Service authorization
Service authorization is used to establish if the client or service calling another service has a proper permission to invoke the service. This means that the clients or services must provide JWT to identify itself to the Data Ecosystem API it is calling. This token should be provided in the Authorization header. Specifically, if service is calling another service that service must provide valid SAuth token for the service account it uses to identify itself to the Data Ecosystem API it is calling.
In each data partition that the service is used, the group corresponding to the permission that the service supports should be created. For example, given a service named my_service, where user and admin permissions are desired, then groups called service.my_service.user and service.my_service.admin should be created in all relevant data partitions.
Service that wants to authorize access that one makes to it should call Entitlements service GET /entitlements/v1/groups API by providing its JWT in Authorization header and required data partition identifier in Slb-Data_Partition_Id header.
Entitlements service will return all the groups of the user if:
- the service is a member of specified data partition;
- the user is a member of specified data partition;
- service is a member of service.entitlements.user group in specified data partition.
If one of the above conditions is not met, Entitlements service will return Unauthorized error. If multiple data partitions are used in the slb-data-partition-id header, but the user does not belong to at least one of them, Entitlements service will also return Unauthorized. On success, calling service can inspect returned groups to determine if required group (e.g., service.my_service.user) is returned and depending on result, can authorize access.
More information on how to use service level authorization can be found here.
Data authorization
Once the client or service has the storage service authorization, the data authorization will use the Google group on the data. The ACL provided in the record to be ingested is directly applied on GCP Cloud Storage object ACL. Storage service will leverage Google Cloud Storage authorization mechanism to determine if the user has access to the record.
Cross partition data authorization
In most cases, data authorization happens within one data partition, but there is use case (e.g. data marketplace) requires cross partition data authorization. Cross partition data authorization allows data group OWNER of the vendor partition to grant access to an user group from a primary partition.
primary data partition: is a private data partition, where only its members are allowed to access the data, i.e. client or slb.
vendor data partition: is a sharable data partition, where members from other non-vendor data partitions are allowed to access the data, i.e. common.
Entitlement Service API
All the API's can be found here
-
GET /entitlements/v1/groups - Retrieves all the groups for the user or service extracted from JWT (email claim) in Authorization header for the data partition provided in slb-data-partition-id header. This API gives the flat list of the groups (including all hierarchical groups) that user belongs to. This API requires the authorization specified here. Service that wants to authorize access that one makes to it should call Entitlements service GET /entitlements/v1/groups API by providing SAuth token in Authorization header and required data partition identifier in slb-data-partition-id header. Calling service can inspect returned groups to determine if required group (e.g., service.my_service.user) is returned and depending on result can authorize access.
In cross partition scenario, slb-data-partition-id header could be set as multiple values with one primary data partition plus many vendor data partitions, then it returns the merged group results in one response.
curl --request GET \
--url '/entitlements/v1/groups' \
--header 'authorization: Bearer <JWT>' \
--header 'content-type: application/json' \
--header 'slb-data-partition-id: slb, common'
-
POST /entitlements/v1/groups - Creates the group within the data partition provided in slb-data-partition-id header. This api will create a group with following email {name}@{data-partition-id}.{domain}.com, where {data-partition-id} is received from Slb-Data-Partition_Id header. The user or service extracted from JWT (email claim) in Authorization header is made OWNER of the group. In addition to the authorization specified here, the user or service must belong to service.entitlements.admin@{data-partition-id}.{domain}.com group. This API will be mainly used to create service and data groups.
- Data groups used for data authorization e.g. of group name is : data.{resourceName}.{permission}@{data-partition-id}.{domain}.com
- Service groups used for service authorization e.g. of group name is : service.{serviceName}.{permission}@{data-partition-id}.{domain}.com
- User groups used for hierarchical grouping of user and service identities e.g. of group name is : users.{serviceName}.{permission}@{data-partition-id}.{domain}.com
curl --request POST \
--url '/entitlements/v1/groups' \
--header 'authorization: Bearer <JWT>' \
--header 'content-type: application/json' \
--header 'slb-data-partition-id: slb' \
--data '{
"name": "service.example.viewers",
"description": "This is an service group for example service which has viewer permission."
}'
- GET /entitlements/v1/groups/{group_email}/members - Retrieves members that belong to a group_email within the data partition provided in slb-data-partition-id header. E.g. group_email value is {name}@{data-partition-id}.{domain}.com. Query parameter role can be specified to filter group members by role of OWNER or MEMBER. In addition to the authorization specified here. The user or service extracted from JWT (email claim) in Authorization header is checked for membership within group_email as the MEMBER or OWNER. This API lists the direct members of the group (excluding hierarchical groups).
curl --request GET \
--url '/entitlements/v1/groups/service.example.viewers@slb.delfi.slb.com/members' \
--header 'authorization: Bearer <JWT>' \
--header 'content-type: application/json' \
--header 'slb-data-partition-id: slb'
- POST /entitlements/v1/groups/{group_email}/members - Adds members to a group with group_email within the data partition provided in slb-data-partition-id header. The member being added can either be a user or a group. E.g. group_email value is {name}@{data-partitionn-id}.{domain}.com. Member body needs to have an email and role for a member. Member role can be OWNER or MEMBER. In addition to the authorization specified here. The user or service extracted from JWT (email claim) in Authorization header is checked for OWNER role membership within group_email.
curl --request POST \
--url '/entitlements/v1/groups/service.example.viewers@slb.delfi.slb.com/members' \
--header 'authorization: Bearer <JWT>' \
--header 'content-type: application/json' \
--header 'slb-data-partition-id: slb' \
--data '{
"email": "member@domain.com",
"role": "MEMBER"
}'
- POST /entitlements/v1/groups/data/{group_email}/members - Adds user group (refer to Introduction about what is a user group) of a primary partition to a data group (refer to Introduction about what is a data group) of a vendor partition. The given group_email must be a data group which is within the vendor data partition provided in slb-data-partition-id header. The member must a user group. E.g. group_email value is {data.xxx.viewers}@{vendor-data-partitionn-id}.{domain}.com. Member body needs to have an email and role for a member. Member role can only be MEMBER. In addition to the authorization specified here. The user or service extracted from JWT (email claim) in Authorization header is checked for OWNER role membership within group_email.
curl --request POST \
--url '/entitlements/v1/groups/data/data.example.viewers@common.delfi.slb.com/members' \
--header 'authorization: Bearer <JWT>' \
--header 'content-type: application/json' \
--header 'slb-data-partition-id: common' \
--data '{
"email": "users.example@slb.delfi.slb.com",
"role": "MEMBER"
}'
- DELETE /entitlements/v1/groups/{group_email}/members - Deletes members from a group with email group_email within the data partition provided in slb-data-partition-id header. The member being deleted can either be an user or a group. E.g. group_email value is {name}@{data-partition-id}.{domain}.com. Path parameter member_email needs an email of a member. In addition to the authorization specified here. The user or service extracted from JWT (email claim) in Authorization header is checked for OWNER role membership within group_email.
curl --request DELETE \
--url '/entitlements/v1/groups/service.example.viewers@slb.delfi.slb.com/members/member@domain.com' \
--header 'authorization: Bearer <JWT>' \
--header 'content-type: application/json' \
--header 'slb-data-partition-id: slb'
Data Ecosystem user groups
Data Ecosystem user groups provides an abstraction from permission and user management. Clients or services can be directly added to the user groups to gain the permissions associated with that user group. The following user groups exists by default:
-
users.datalake.viewers used for viewer level authorization for Data Ecosystem services.
-
users.datalake.editors used for editor level authorization for Data Ecosystem services and authorization to create the data using Data Ecosystem storage service.
-
users.datalake.admins used for admin level authorization for Data Ecosystem services.
Migrating to Entitlements service from Identity service
Comparison between Identity and Entitlements
Identity | Entitlements |
---|---|
No Service level authorization | Service level authorization is based on the users group with the email users@{data-partition-id}.{domain}.com |
User management | No User management. Users are created/onboarded via CFS and added to the group |
Group management - Create group etc., Add members to groups etc. | Group management - Create group etc., Add members to groups etc. |
Roles - Roles can be associated with the users and groups | Roles - Roles can be associated with the users and groups |
Authorizing calls to service/API/backend
1. Ensuring service identity and corresponding token
Authorization with Identity service did not care about the identity of the service making the call but relied on just passing the token received in the Authorization header. This opens door for an attacker who could steal user's token and use it to gain access to our services. To reduce this attack surface, we will require that services need to be authorized as well.
This means that service must provide SAuth token for the service account it uses to identify itself to the Data Ecosystem API it is calling. This token should be provided in the Authorization header.
2. Ensuring service is a member in desired data partition
Service account email for the service making the calls to Data Ecosystem APIs in specific data partition, should be added to users of the data partition in question. For example, storage@p4d-ddl-us-services.iam.gserviceaccount.com should be added to users@instance.osdu.opengroup.org.
3. Ensuring service can use Entitlements service
Service account email for the service using Entitlements service to perform service authorization in specific data partition, should be added to users of the entitlements service (group named service.entitlements.user). For example, storage@p4d-ddl-us-services.iam.gserviceaccount.com should be added to service.entitlements.user@instance.osdu.opengroup.org.
4. Authorizing calls to your service/API/backend
a. Creating required service group
In each data partition that the service should be used, group corresponding to the permission the service supports should be created. For example, if one is creating a service called my_service and wants to have specific permission with roles user and admin, groups called service.my_service.user and service.my_service.admin should be created in all relevant data partitions.
b. Adding users
All users that are authorized to call a specific API should be added to the group representing desired role on the service. For example, if one wants to give user role on my_service in data partition my_data_partition to joe@customer.com, one would add joe@customer.com to service.my_service.user@my_data_partition.{domain}.com. Groups grouping the roles will be created for the standard end user profiles (e.g., users.datalake.users will have all the default roles).
c. Authorizing the access
Refer to Service Authorization
Data Ecosystem user groups
Data Ecosystem user groups provides an abstraction from Data Ecosystem service level permission groups. Data Ecosystem users groups hierarchically groups the various service groups. Client or service can be directly added to the user groups to get access to various services. Following Data Ecosystem user groups exists in Data Ecosystem per data partition:
- users.datalake.viewers used for viewer level authorization for Data Ecosystem services.
- users.datalake.editors used for viewer level authorization for Data Ecosystem services and authorization to create the data using Data Ecosystem storage service.
- users.datalake.admins used for admin level authorization for Data Ecosystem services.
Permissions
Endpoint URL | Method | Minimum Permissions Required |
---|---|---|
/entitlements/v1/groups | GET | users.datalake.viewers |
/entitlements/v1/groups | POST | users.datalake.admins |
/entitlements/v1/groups/{group_email}/members | GET | users.datalake.viewers |
/entitlements/v1/groups/{group_email}/members | POST | users.datalake.admins |
/entitlements/v1/groups/{group_email}/members | DELETE | users.datalake.admins |