Users API Reference¶
General¶
An OpenAPI Specification is available here.
The subdomain of the Users API is users.
Storage Format¶
The storage format for permissions is crafted in a way that allows all necessary queries to be executed using a DynamoDB index (thus no table scans are necessary).
We use the following attributes:
subject(used as hash key): A user email address, see above. To allow other subject types in the future, we prefix email addresses with “user=”.sort_key(used as range key: Combination ofnamespace,actionandparameters. Together withsubjectthis generates a unique primary key. This primary key can be easily used for permission checks: Just check whether the (subject, action) tuple exists.namespace: see aboveaction: The name of the action, see above.parameters: All key-value parameters as mapping.entity(used as global secondary index): A combination of some of theparametersin the following format (“,” and “=” in values must be escaped with backslashes):<namespace>:<key1>=<value1>,<key2>=<value2>
This attribute is used to query all permissions on a particular entity, for example to render an overview to the admin of a particular account. The list of parameters to be used here is defined by the namespace. For example, the “account” namespace only uses the “id” parameter here, but not the “role” parameter. Thus it is possible to render a list of all permissions assigned within a particular account, regardless of role.
Permission Origin¶
Additionally to the preceding attributes some meta-information regarding the permission origin are stored in the DynamoDB.
Each writing call to the Users API needs to contain exactly one of the headers reason, request_id, portal_reason, source_system.
Currently five permission origin types are supported:
direct: Permissions with this origin type were added directly via API call by a privileged user. For this permission type we store thereasonand information about the person who added the permission (added_by).portal_request: Permissions with this origin type were added by the Data Portal and have a corresponding Portal Request. For this permission type we store the correspondingrequest_id.portal_direct: Permissions with this origin type were added by the Data Portal or the CDH API without a corresponding Portal Request. For this permission type we store theportal_reason.automation: Permissions with this origin type were added by one of our automated services. For this permission type we store the correspondingsource_system.legacy: Permissions with this origin type were added before the permission origin was introduced. This type can not be set for new permissions.
Return values¶
The GET endpoints /namespaces/{namespace}/permissions, /bulk, /users/{user_id}/permissions return a list of
SubjectPermissions. Each SubjectPermission assigns one permission to one subject. An example response of these endpoints
is shown below.
Example response:
{
"permissions": [
{
"subject": { "type": "user", "id": "mail@example.test", "idp": "example-idp" },
"permission": {
"namespace": "account",
"action": "login",
"parameters":{
"id": "123456123456",
"partition": "aws",
"role": "example-role"
}
}
}
]
}
Request objects¶
The endpoints POST /users/{user_id}/permissions and DELETE /users/{user_id}/permissions require a PermissionBody as
part of the request body. The endpoint DELETE /bulk requires a BulkDeletePermissionsBody and the endpoint
POST /bulk a BulkUpdatePermissionsBody. The structure for both objects is shown below.
PermissionBody:
namespace: str
action: str
parameters: Dict[str, str]
BulkDeletePermissionsBody:
deletes: List[{
permission: {
namespace: str
action: Optional[str]
parameters: Dict[str, str]
}
subjects: Optional[List[Subject]]
}]
BulkUpdatePermissionsBody:
permissions: List[{
permission: PermissionBody
subjects: List[Subject]
exclusive: bool
}]
Subject:
type: str
id: str
idp: str
Pagination¶
Certain endpoints will use pagination in their responses, as the response size would be too large for a single request.
Currently, the endpoints are GET /bulk, /users, /namespace/{namespace}/permissions and /resources
(those endpoints are clearly identifiable in the OpenAPI spec).
The approach is similar to the one used in the CDH Core API. A request to one of the endpoints will return a page,
i.e. a limited amount of entries, starting with the entry specified through the query parameter next_page_token.
If this query parameter is None (default), it will start at the beginning of the internal table. If there is more data
left after the last entry returned in a response, the response will set the header x-next-page-token. This token
should then be passed as the query parameter next_page_token to obtain the next page of results. If no further
results are left, the response header will not be set, indicating to the requester that they have obtained all results.
There is also a query parameter page_size for controlling the number of results per page, but this parameter is
mainly intended for testing. Using it in production is discouraged.
A python users API client that respects the pagination may look as follows (Example for /bulk, works analogously
for the other endpoints).
import requests
base_url = "https://users.iam.data.aws.bmwcn.cloud"
auth = ... # suitable auth for accessing the API
next_page_token = None
permissions = []
done = False
while not done:
params = {"next_page_token": next_page_token} if next_page_token else None
response = requests.get(base_url + "/bulk", params=params, auth=auth)
data = response.json()
permissions += data["permissions"]
next_page_token = response.headers.get("x-next-page-token")
if not next_page_token:
done = True