Skip to content
Snippets Groups Projects
architecture.rst 5.69 KiB
Newer Older
Architecture
============

The single sign on system consists of a few components:

1. The *Oauth2* and *OpenID Connect (OIDC) provider*, `Hydra`_
2. The *Identity provider*, `Kratos`_
3. The `Login application`_ which serves as a login panel, consent application
   and a settings screen for the Kratos settings (mostly used for password
   reset).

.. _Hydra: https://www.ory.sh/hydra/docs/
.. _Kratos: https://www.ory.sh/kratos/docs/
.. _Login application: https://open.greenhost.net/stackspin/single-sign-on/-/tree/main/login

Overview
--------

The single sign on application as a whole stores your users and helps them
authenticate to applications. Its users are stored inside Kratos's database.
Kratos also serves an API that helps us generate interfaces for many
user-related tasks, such as:

1. Setting your name and username
2. The whole password reset flow
3. The login form
4. 2FA (not implemented in the login application yet)

The Login application is mostly a front-end that uses the Kratos API to generate
the views for logging in, resetting the password and setting some user data.


Flows
-----

Logging in
~~~~~~~~~~

The Kratos login flow is documented `in the Kratos documentation
<https://www.ory.sh/kratos/docs/self-service/flows/user-login#login-for-client-side-ajax-browser-clients>`__.
Our implementation is slightly different from what you see there:

.. mermaid::

   sequenceDiagram
      participant B as Browser
      participant L as Login application
      participant K as Kratos

      B->>L: User clicks "Login with Stackspin"
      L->L: Check if cookie for current session exists
      alt Cookie does not exist
        L-->>+K: Start `/self-service/login/browser` flow
        K-->>-B: At end of login flow, sets session cookie
      else Cookie exists
        L->>B: Shows "you are already logged in" screen
        B->B: If cookie has `flow_state == auth`, redirect to Cookie's `auth_url` and remove `flow_state`.
      end

User creation
~~~~~~~~~~~~~

We have not implemented Kratos's *Registration* flow, because users cannot
self-register with a Stackspin cluster. An administrator can make new users
using the Dashboard application. When a user is created, an email address always
needs to be provided.

Once a user has been created, they can start the `Account Recovery and Password
Reset flow
<https://www.ory.sh/kratos/docs/self-service/flows/account-recovery>`__ in order
to set or reset their password. We use the "Recovery ``link`` Method" described
in the Kratos documentation.

User settings
~~~~~~~~~~~~~

Although users can change their settings through the `Dashboard application
<https://open.greenhost.net/stackspin/dashboard>`__, the login application also
has a version of the `user-settings Kratos flow
<https://www.ory.sh/kratos/docs/next/self-service/flows/user-settings/>`__.

Authentication
~~~~~~~~~~~~~~

The following is an adaptation of the sequence diagram provided in the `Hydra
documentation <https://www.ory.sh/docs/hydra/concepts/login>`__

.. mermaid::

   sequenceDiagram
      OAuth2 Client->>Ory Hydra: Initiates OAuth2 Authorize Code or Implicit Flow
      Ory Hydra-->>Ory Hydra: No end user session available (not authenticated)
      opt Login Application as Login Provider
        Ory Hydra->>Login Application: Redirects end user with login challenge
        Login Application-->Ory Hydra: Fetches login info
        Login Application-->>Login Application: Authenticates user w/ Kratos
        Login Application-->Ory Hydra: Transmits login info and receives redirect url with login verifier
        Login Application->>Ory Hydra: Redirects end user to redirect url with login verifier
      end
      Ory Hydra-->>Ory Hydra: First time that client asks user for permissions
      opt Login Application as Consent Provider
        Ory Hydra->>Login Application: Redirects end user with consent challenge
        Login Application-->Ory Hydra: Fetches consent info (which user, what app, what scopes)
        Note over Ory Hydra, Login Application: Not implemented: user is asked to grant app access<br />default: access granted
        Login Application-->Ory Hydra: Transmits consent result and receives redirect url with consent verifier
        Login Application->>Ory Hydra: Redirects to redirect url with consent verifier
      end
      Ory Hydra-->>Ory Hydra: Verifies grant
      Ory Hydra->>OAuth2 Client: Transmits authorization code/token`

Configuring OIDC clients
------------------------

If you have installed the SSO system using the Helm chart, following this
documentation, these are the settings that you usually need to for setting up
new OIDC clients:

- OAuth 2 server URL: ``https://sso.stackspin.example.org``
- OAuth 2 Auth Endpoint: ``https://sso.stackspin.example.org/oauth2/auth``
- OAuth 2 Userinfo endpoint: ``https://sso.stackspin.example.org/userinfo``
- OAuth 2 Token endpoint: ``https://sso.stackspin.example.org/oauth2/token``

In addition you'll need to add the client to Hydra. This happens with `Hydra
Maester
<https://www.ory.sh/hydra/docs/guides/kubernetes-helm-chart/#hydra-maester>`__,
a helper application that reads ``oauth2clients.hydra.ory.sh`` Kubernetes
objects and synchronises them with Hydra.

An example ``oauth2client``:

.. code:: yaml

   apiVersion: hydra.ory.sh/v1alpha1
   kind: OAuth2Client
   metadata:
     name: dashboard-oauth-client
   spec:
     grantTypes:
       - authorization_code
       - refresh_token
       - client_credentials
       - implicit
     hydraAdmin: {}
     metadata: null
     redirectUris:
     - https://dashboard.stackspin.example.org/login-callback
     responseTypes:
     - id_token
     - code
     scope: openid profile email stackspin_roles
     secretName: stackspin-dashboard-oauth-variables
     tokenEndpointAuthMethod: client_secret_post