maxcembalest's picture
Upload 184 files
ad8da65
raw
history blame
16.4 kB
# Arthur SSO Access Control Overview
In on-prem installations, cluster administrators have the ability to configure their Arthur install to use a 3rd party
identity provider (IdP) to manage Arthur users and access. Arthur can work with any IdP that supports the Open ID
Connect (OIDC) or SAML protocols.
## User and App Authentication
Regardless of if your IdP is using OIDC or SAML, the IdP will be responsible for authenticating users and system access
to Arthur. As a result, applications or downstream systems that need to authenticate with Arthur will require working
with your IdP to get access. Some IdPs provide support for AppID's or service accounts, but it will depend on the
specific IdP and how your organization supports it.
```{warning}
Important! Arthur API keys cannot be used when SSO in enabled.
Instead, users will rely on their own authentication tokens, which are validated by the IdP and enforce the custom
permissions assigned to their roles.
```
## Authorization (RBAC)
Arthur installations with SSO are able to use custom role-based access control policies (RBAC) for
users authenticated via the IdP. Arthur's custom RBAC system uses two kinds of roles. The first kind are organization
level roles, which grant a user the specified permissions within a single Arthur organization. The second kind are
global roles, which grant the specified privileges across all organizations in the system. Global roles are intended for
administrators, so they can perform actions like managing organizations and roles at the global level. They should not
be used to grant non-admin users cross-organization access. Instead, users that need access to more than one
organization should have a distinct role for each organization. Commonly, the global administrator role only has
permissions to create new organizations and to manage custom roles for the platform. All model and data access should
be configured using organization scoped roles. See the {doc}`custom_rbac` for an overview of how to configure
custom roles for your Arthur installation.
### Linking IdP Groups to Arthur Roles
Roles are the link between the IdP's user groups and the Arthur access control system. As shown
in [Set Up an Identity Provider](#set-up-an-identity-provider), when you
configure an IdP, you will tell Arthur how to parse a user's groups out of the IdP response. The group, or list of
groups, returned from your IdP must match the names of custom roles configured in Arthur. For this reason, Arthur
enforces all custom roles to have unique names, so the platform can map a user group from an
external IdP to a specific set of permissions. This means **all roles in the system must have unique names, even across
organizations.**
For example, if using OIDC and the IdP returns a JWT token of the following format, Arthur must be configured with roles
that match the groups listed under the "groups" field in the token. The group names are used to look up the roles that
apply for the user in Arthur. More examples of how to configure the OIDC JWT claim parsing can be found in
{doc}`setting_up_oidc_idp`.
```json
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
// this field in the token corresponds to the user's groups in the IdP
"groups": [
// an "idp-admin" role must be created in Arthur to match this group
"idp-admin",
// an "org-1-user" role must be created in Arthur to match this group
"org-1-user"
]
}
```
```{note}
It is ok if the OIDC token contains extra groups that are not matched to roles in Arthur.
It is not required that every group have a corresponding role, but at least one group must.
```
Similarly if using SAML, the SAML assertion from the IdP must contain some attribute values that contains the user's
groups in the IdP. More examples of how to configure the SAML attribute parsing can be found in
{doc}`Setting Up a SAML IdP <setting_up_saml_idp>`.
```xml
<saml2:AttributeStatement>
<saml2:Attribute Name="email">
<saml2:AttributeValue>[email protected]</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="firstName">
<saml2:AttributeValue>John</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="lastName">
<saml2:AttributeValue>Doe</saml2:AttributeValue>
</saml2:Attribute>
// this field in the assertion corresponds to the user's groups in the IdP
<saml2:Attribute Name="groups">
// an "idp-admin" role must be created in Arthur to match this group
<saml2:AttributeValue>idp-admin</saml2:AttributeValue>
// an "org-1-user" role must be created in Arthur to match this group
<saml2:AttributeValue>org-1-user</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
```
```{note}
It is ok if the SAML assertion contains extra groups that are not matched to roles in Arthur.
It is not required that every group have a corresponding role, but at least one group must.
```
## Set Up an Identity Provider
### {doc}`OIDC <setting_up_oidc_idp>`
See {doc}`Setting Up an OIDC IdP <setting_up_oidc_idp>` for the steps to configure an OIDC IdP with Arthur.
### {doc}`SAML <setting_up_saml_idp>`
See {doc}`Setting Up a SAML IdP <setting_up_saml_idp>` for the steps to configure a SAML IdP with Arthur.
## Creating Custom Roles
As mentioned above, custom roles can be used to grant either permissions within an organization or permissions across
all organizations. This section will first cover how to create global roles, then it will cover how to create roles for
an organization. The steps outlined here are sufficient to get SSO working. For more details about managing custom RBAC
access control, please see the {doc}`custom_rbac` guide.
(creating_global_roles_in_arthur_config)=
### Creating Global Roles for Managing Organizations and RBAC Policies
```{note}
In order to complete this section, you must have access to the Arthur Admin Console config page.
```
Global roles are intended to be used by a cluster administrator to manage organizations and roles in the Arthur
application. Global roles should be scoped with the minimal privileges and should be given out with caution.
**It is not recommended to grant model or data access with global roles as that would give access to every model in the
system.** Global roles can be created in the Arthur installer Admin Console configuration in the "Use a 3rd Party
Global Identity Provider" section where the IdP configuration YAML is set. A list of custom global roles can be provided
in the Identity Provider YAML under the `globalRoleDefs` key. The following
example shows a global role for an Arthur cluster admin to manage organizations and RBAC for the
installation:
```yaml
globalRoleDefs:
# Here we specify a list to define multiple global roles
- name: "idp-admin" # change the name of this role to match the cluster administrator group name in your IdP
# this role grants a user permissions to manage organizations and RBAC policies in Arthur
permissions:
custom_roles:
- read
- write
- delete
organization_global:
- read
- write
organization:
- read
- delete
```
Once you add a role to your config, be sure to click "Save" at the bottom of the page and then deploy the change. After
the update completes, the new global role should be created.
(creating_organization_roles)=
### Creating Organization Scoped Roles for Non-admin Users
Completing this section will require either access to the Arthur superadmin user, or access to a previously created,
custom global role assumable via an IdP
(see [above](#creating-global-roles-for-managing-organizations-and-rbac-policies)).
Additionally, only installations with SSO configured can use custom RBAC policies. If you do not have SSO configured,
please see {doc}`../standard_access_control`.
The section below assumes an organization already exists that you would like to give users access to. If you would like
to create a new Arthur organization, please check out the
{ref}`Managing RBAC and Organizations for SSO users <custom_rbac_managing_orgs_and_roles>`,
then come back here to add roles to that new organization.
Using either the Arthur superadmin user or having assumed a custom RBAC role with global scope to manage RBAC,
organization scoped roles can be created using the Arthur API. The following is an example of a request to create a new
role in an organization. Be sure to fill in the missing values for the hostname,
authorization token (must be a superadmin or your token from a custom global role), organization ID, and change the role
names to match your IdP user groups. See
{ref}`Managing RBAC and Organizations for SSO users <custom_rbac_managing_orgs_and_roles>` for an overview of role
permissions and some example roles.
```shell
curl --location 'https://<YOUR ARTHUR HOST HERE>/api/v3/authorization/custom_roles' \
--header 'Arthur-Organization-ID: <YOUR ORGANIZATION ID HERE>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR AUTH TOKEN HERE>' \
--data '{
"roles": [
{
"role_name": "my-idp-group-1",
"inherited_role_names": [
"Administrator"
]
},
{
"role_name": "my-idp-group-2",
"inherited_role_names": [
"Model Owner"
]
}
]
}'
```
This sample API call will create two custom roles in the `<YOUR ORGANIZATION ID HERE>` organization. These
roles will apply to users in the "my-idp-group-1" or "my-idp-group-2" groups managed by the IdP.
### Granting Users Access to Multiple Organizations
Users can be given access to multiple organizations by creating a unique custom role in each organization, then adding
them to the associated groups in the IdP. For example, if you have two organizations, `org-1` and `org-2`, the Arthur
cluster administrator will need to create a custom role in each organization. Let's call them `role-1` and `role-2`
respectively. As described above, these role names will need to correspond to user groups in the IdP so please name them
according to your group names. With two organizations and a role created in each, the last step is to add your users to
both groups in your IdP, and they will be able to access both organizations.
```{note}
If users have access to more than one organization, they will need to specify one to use during API calls.
See the next section for more information on how to specify an organization when using the Arthur API.
```
## API Authentication with Multiple Organization Users
The Arthur platform separates resources logically by Arthur {ref}`Organizations <glossary_organization>`. When an Arthur
deployment is configured with Arthur's Standard Authentication mechanism, user access is granted to one organization at
a time, so all interactions with the platform are automatically scoped with that organization.
However, when SSO is enabled, SSO tokens can grant access to one or more Arthur organizations at a time. They do this by
listing multiple roles for a user within the token, each with access to a distinct organization. As a result, users can
have access to more than one organization at a time, and Arthur cannot determine which organization the user intends to
take an action in. Therefore, when SSO users have access to more than one organization, they must select a specific
Arthur Organization in each request to the platform via the methods described in this section.
### Alternatives for Selecting an Organization in the Arthur API
1. Request Header
2. Session-Based Organization Tracking
3. Arthur SDK Client
4. Deep Linking to an Organization in the UI
### Request Header
In an API call made by an SSO-authenticated user with access to more than one organization, the platform will first
check for a request header with an `Arthur-Organization-ID` key. If one is found, the platform will parse it and,
assuming the organization exists and the calling user can access it, continue the request with the specified ID as its
target organization. If the header is not found, it will fall back to one of the other methods described below.
If the header is present and the user does not have access to the organization, the API will return a 404 status code.
### Session-Based Organization Tracking
If no organization-specifying request header is included in the request, the platform will then use session information
to determine one.
Sessions enable users to establish a long-lived association with an organization that can be used to automatically scope
all requests to a specific organization. Users can establish a session using the
[PUT /organizations/current](https://docs.arthur.ai/api-documentation/v3-api-docs.html#tag/organizations/paths/~1organizations~1current/put)
endpoint. Similarly, they can retrieve the organization from their current session with the
[GET /organizations/current](https://docs.arthur.ai/api-documentation/v3-api-docs.html#tag/organizations/paths/~1organizations~1current/get)
endpoint.
By calling `PUT /organizations/current` with a target organization specified, a user receives an `_arthur_session`
cookie that associates future requests with the target organization. Any future calls to `PUT /organizations/current`
will return a new `_arthur_session` cookie to track your new session for whichever organization is specified in
the `PUT` call.
By calling `GET /organizations/current` with an `_arthur_session` cookie included in the request, users can retrieve the
organization their current session is associated with.
```{note}
Sessions do not provide any access to Arthur on their own. They only keep track of the user's association with a
specific organization. Users must also have an access token to authenticate with the Arthur APIs.
Since sessions do not grant any access to the Arthur platform, they expire after 30 days to prevent
users from repeatedly having to specify an organization.
```
### Arthur SDK Client
For SSO-authenticated users with access to more than one organization working with the Arthur SDK, the SDK client allows
selecting a specific organization. _Note: SDK users with access to a single Arthur organization will automatically have
their one organization set._
When an SDK user is instantiating the
[`ArthurAI` client](https://docs.arthur.ai/sdk/sdk_v3/apiref/arthurai.client.client.ArthurAI.html#arthurai.client.client.ArthurAI)
, they can first specify which organization they want that client to be associated with by passing in that
organization's ID as the `organization_id` optional parameter.
```python
connection = ArthurAI(organization_id=org_id: str, ...)
```
After the `ArthurAI` client has been instantiated, users can update the client's current organization by calling
the [`set_current_org()`](https://docs.arthur.ai/sdk/sdk_v3/apiref/arthurai.client.client.ArthurAI.html#arthurai.client.client.ArthurAI.set_current_org)
method.
```python
connection.set_current_org(org_id: str)
```
At any point, SDK users can access their `ArthurAI` client's current organization by calling
the [`get_current_org()`](https://docs.arthur.ai/sdk/sdk_v3/apiref/arthurai.client.client.ArthurAI.html#arthurai.client.client.ArthurAI.get_current_org)
method.
```python
current_org = connection.get_current_org()
```
### Deep Linking to an Organization in the UI
If an SSO-authenticated user has access to more than one organization, Arthur allows them to bypass manual organization
selection through deep linking. A user can append the url parameter `?organization_id=<ORG-ID>` to the Arthur
platform host name, where `<ORG-ID>` is equal to one of the organization IDs to which the user has access. This
will tie the users session to that organization ID upon authentication through SSO.
N.B. This will only work when appended to the platform host name.
E.g. `https://[Arthur hostname]/?organization_id=<ORG-ID>` This will not work if you are attempting to apply the
parameter to any other path on the Arthur host. E.g. `https://[Arthur hostname]/login/?organization_id=<ORG-ID>` will
NOT work.
```{toctree}
:maxdepth: 2
:hidden:
OIDC <setting_up_oidc_idp>
SAML <setting_up_saml_idp>
Custom RBAC <custom_rbac>
```