Setting up SSO
The YTsaurus web interface offers two types of user authentication: password-based authentication and single sign-on (SSO). To learn more about using passwords, see the User manual. This article explains how to configure SSO.
Warning
YTsaurus supports SSO authentication exclusively through the OAuth 2.0 protocol. When configuring SSO, choose an identity server that supports OAuth.
Configuration
To implement proper authentication, you need to configure two components: a proxy and a web interface.
-
To set up a proxy, fill in the
oauthServicefield in the ytsaurus resource specification. -
To configure the web interface, set the ytOAuthSettings parameter in the web interface config file. You can do this via ui-helm-chart by filling in the
settings.oauthfield invalues.yaml.
Example
Microsoft Identity Platform
Below is an example demonstrating how to set up SSO authentication in YTsaurus using Microsoft Identity Platform.
-
First, create an OAuth app in MS Identity Platform. For RedirectURIs, specify
https://<HOST_NAME_OF_YOUR_YT_CLUSTER>/api/oauth/callback.When creating the app, you'll receive a
CLIENT_IDand aCLIENT_SECRET. You'll also need to specify theTENANT_ID. You can get it from your OAuth server administrator. You'll need to enter the received parameters in the web interface specification. -
Next, configure the server:
# ytsaurus.yaml apiVersion: cluster.ytsaurus.tech/v1 kind: Ytsaurus metadata: name: ytdemo spec: oauthService: host: graph.microsoft.com port: 443 secure: true userInfoHandler: endpoint: oidc/userinfo loginField: email # ... -
Your web interface settings should look like this:
# ui-helm.values.yaml ui: image: repository: ghcr.io/ytsaurus/ui # ... settings: oauth: enabled: false baseURL: "https://login.microsoftonline.com/mycompany.onmicrosoft.com/oauth2/v2.0/" # mycompany.onmicrosoft.com is a tenant ID example authPath: "authorize" logoutPath: "logout" tokenPath: "token" clientIdEnvName: "CLIENT_ID" clientSecretEnvName: "CLIENT_SECRET" scope: "openid offline_access" # offline_access scope is required for api to respond with refresh_token buttonLabel: "Login via SSO"
Keycloak
Here's an example showing how to configure SSO authentication using Keycloak.
In this example, we use the realm ytsaurus.tech, the Keycloak address https://keycloak.example.com, and the web interface address https://ui.example.com. Keycloak must be accessible both from the user's browser and from the HTTP proxy.
-
Create an OpenID Connect client in Keycloak. Enable Client authentication and Standard flow, and set the following parameters:
Valid redirect URIs: https://ui.example.com/api/oauth/callback Valid post logout redirect URIs: https://ui.example.com/api/oauth/logout/callback Web origins: https://ui.example.comSave the obtained
CLIENT_IDandCLIENT_SECRETin a Kubernetes Secret:kubectl create secret generic ytsaurus-ui-keycloak \ --from-literal=client-id='<CLIENT_ID>' \ --from-literal=client-secret='<CLIENT_SECRET>' -
Configure the server:
# ytsaurus.yaml apiVersion: cluster.ytsaurus.tech/v1 kind: Ytsaurus metadata: name: ytdemo spec: oauthService: host: keycloak.example.com port: 443 secure: true userInfoHandler: endpoint: "realms/ytsaurus.tech/protocol/openid-connect/userinfo" loginField: "preferred_username" errorField: "error" disableUserCreation: false # ...With
disableUserCreation: false, the system automatically creates a user in//sys/usersafter their first successful login. You need to assign permissions to the user separately. -
Configure the web interface:
# ui-helm.values.yaml ui: clusterConfig: clusters: - id: my-cluster # Other cluster parameters are omitted. authentication: basic env: - name: KEYCLOAK_CLIENT_ID valueFrom: secretKeyRef: name: ytsaurus-ui-keycloak key: client-id - name: KEYCLOAK_CLIENT_SECRET valueFrom: secretKeyRef: name: ytsaurus-ui-keycloak key: client-secret settings: oauth: enabled: true baseURL: "https://keycloak.example.com" authPath: "realms/ytsaurus.tech/protocol/openid-connect/auth" logoutPath: "realms/ytsaurus.tech/protocol/openid-connect/logout" tokenPath: "realms/ytsaurus.tech/protocol/openid-connect/token" clientIdEnvName: "KEYCLOAK_CLIENT_ID" clientSecretEnvName: "KEYCLOAK_CLIENT_SECRET" scope: "openid profile" buttonLabel: "Login via Keycloak"The
authentication: basicsetting allows the web interface to pass authentication data to the HTTP proxy and doesn't require enabling password-based login. The secret with the OAuth client secret doesn't replace the interface secret: the interface secret stores the YTsaurus token for the web interface's internal requests. -
Apply the cluster specification and install or update the web interface with the prepared
values.yaml. After logging in, Keycloak will redirect the user to/api/oauth/callback, and the HTTP proxy will requestuserinfoand retrieve the username frompreferred_username.
Implementation details
Below is an overview of the OAuth workflow. Understanding it will help you identify potential issues in your configuration.
- The user opens the YTsaurus web interface and clicks "Login via SSO".
- The YTsaurus web interface redirects them to the URL of a third-party OAuth identity server, forwarding the configured
scopes. The URL of the third-party server is generated frombaseURLandauthPath. - The user agrees to grant the requested permissions, and the OAuth identity server redirects them to the address specified in the OAuth app settings:
https://<HOST_NAME_OF_YOUR_YT_CLUSTER>/api/oauth/callback. The authorization code is passed in thecodequery parameter. - The web interface makes a request to the OAuth identity server using the URL generated from
baseURLandtokenPath. The request passes the authorization code and the app secret. The response containsaccess_tokenandrefresh_token. - The web interface stores the tokens in the user's browser cookies:
yt_oauth_access_tokenandyt_oauth_refresh_token. - When
yt_oauth_access_tokenexpires, the web interface updates it usingyt_oauth_refresh_token. - The web interface sends a request to the proxy, passing the value of the
yt_oauth_access_tokencookie. The proxy makes a request to the OAuth identity server via a URL generated fromoauthService.host,oauthService.port, andoauthService.userInfoHandler.endpoint. - The received response contains the field configured in
oauthService.userInfoHandler.loginField, which is used as the username in YTsaurus.