Authentication

Perses has various authentication flows configurable. You can choose to authenticate from a native provider that will allow you to create some users, or else rely on an external identity provider.

In both cases

  • each new user will be saved in the Perses database.
  • at login time, a Perses session (access_token/refresh_token) will be created

Please note that the number of identity providers is not limited.

authentication:
  providers:
    # Enable or not the native Perses identity provider
    enable_native: true/false
    # Register one or several OIDC provider(s)
    oidc: []
    # Register one or several OAuth provider(s)
    oauth: []

Native provider

In case a native provider is used, the users and their password are stored in the Perses database.

Login is done through http POST on /api/auth/providers/native/login.

External OIDC/OAuth provider(s)

It is possible to configure Perses to sign in user with an external identity provider supporting OIDC/Oauth. For both of these provider’s types, the flow is quite similar:

When a user sign in with an external provider (e.g. Github) the Perses backend will then use the information collected (email, firstname, lastname, picture) to sync the user in database. Then the backend takes in charge the creation of the access_token/refresh_token that will be used to authenticate this user in the subsequent requests.

The user synchronization can possibly be used to update also its permissions, based on some roles/groups present in the external idp’s token.

At the time we write this documentation, there is nothing implemented yet. User have to login first and ask specific permissions to an admin.

=> Configuration example

  authentication:
    providers:
      oidc:
      # Example with an Azure AD OIDC configuration
      - slug_id: azure
        name: "Azure AD"
        client_id: "<secret>"
        client_secret: "<secret>"
        issuer: "https://login.microsoftonline.com/<tenant-id>/v2.0"
        redirect_uri: "http://localhost:3000/api/auth/providers/oidc-azure/callback"
        scopes: ["openid", "profile", "email", "User.read"]
      oauth:
      - slug_id: github
        name: "Github"
        client_id: "<secret>"
        client_secret: "<secret>"
        auth_url: "https://github.com/login/oauth/authorize"
        token_url: "https://github.com/login/oauth/access_token"
        logout_url: "https://github.com/login/oauth/logout"
        redirect_uri: "http://localhost:3000/api/auth/providers/oauth-github/callback"
        user_infos_url: "https://api.github.com/user"

=> Login from external OIDC or OAuth2.0 provider with interactive flow, through WEB UI. (authorization_code)

sequenceDiagram actor hu as John #actor ro as Robot participant br as Perses Frontend participant rp as Perses Backend participant op as External Identity Provider hu->>br: Login with OIDC provider (e.g Azure AD) activate br br->>rp: GET /api/auth/providers/{oidc|oauth}/{slug_id}/login activate rp rp->>br: 302: redirect to Provider deactivate rp br->>op: /oauth/authorize activate op op->>br: 302: redirect to Perses deactivate op br->>rp: GET /api/auth/providers/{oidc|oauth}/{slug_id}/callback?code=... activate rp alt OIDC rp->>op: GET /oauth/token activate op op->>rp: 200: id_token & access_token deactivate op rp->>op: GET /api/userinfo
(endpoint from .well-known URL) activate op op->>rp: 200: User Info deactivate op Note right of rp: User Info + id token are
used to sync user in database rp->>rp: Create or Update user in DB else OAUTH 2.0 rp->>op: GET /oauth/token activate op op->>rp: 200: access_token deactivate op rp->>op: GET /api/userinfo
(endpoint from Perses Config) activate op op->>rp: 200: User Info deactivate op Note right of rp: Only User Info is
used to sync user in database rp->>rp: Create or Update user in DB end Note right of rp: A new session is created
with a new signed access_token+refresh_token rp->>br: 200: save session in cookie deactivate rp br->>hu: Home Page deactivate br hu->>br: Click on Projects activate br br->>rp: GET /api/v1/projects activate rp rp->>rp: Verify token and permissions rp->>br: 200: projects list deactivate rp br->>hu: Projects Page deactivate br

=> Login from external OIDC or OAuth2.0 provider with interactive flow, through percli command line. (device_code)

sequenceDiagram actor hu as John #actor ro as Robot participant pc as percli Command Line participant rp as Perses Backend participant op as External Identity Provider hu->>pc: EXEC: percli login activate pc pc->>rp: GET /api/config activate rp rp->>pc: 200: Config
(containing Providers List) deactivate rp pc->>hu: PROMPT: which provider? deactivate pc hu->>pc: select provider activate pc pc->>rp: GET /api/auth/providers/{oidc|oauth}/{slug_id}/device/code activate rp rp->>op: GET /oauth/device/code activate op op->>rp: 200: Device Code + User Code + Verification URL deactivate op rp->>pc: 200: Device Code + User Code + Verification URL pc->>hu: PRINT: User Code + Verification URL (clickable) rect rgba(66, 95, 237, 0.2) Note over hu, op: Through the browser hu->>op: Go to Verification URL + enter User Code activate op op->>hu: 302: Redirect to Authorization prompt hu->>op: Consent op->>op: Mark device as authorized op->>hu: 200: Invite to close browser deactivate op end Note over hu, op: Meanwhile, percli is polling the following endpoint, until it succeed. pc->>rp: GET /api/auth/providers/{oidc|oauth}/{slug_id}/token activate rp alt OIDC rp->>op: GET /oauth/token activate op op->>rp: 200: id_token & access_token deactivate op rp->>op: GET /api/userinfo
(endpoint from .well-known URL) activate op op->>rp: 200: User Info deactivate op Note right of rp: User Info + id token are
used to sync user in database rp->>rp: Create or Update user in DB else OAUTH 2.0 rp->>op: GET /oauth/token activate op op->>rp: 200: access_token deactivate op rp->>op: GET /api/userinfo
(endpoint from Perses Config) activate op op->>rp: 200: User Info deactivate op Note right of rp: Only User Info is
used to sync user in database rp->>rp: Create or Update user in DB end Note right of rp: A new session is created
with a new signed acces_token+refresh_token rp->>pc: 200: access_token + refresh_token deactivate rp pc->>pc: WRITE: session into config file pc->>hu: PRINT: Successfully authenticated! deactivate pc hu->>pc: EXEC: percli get projects activate pc pc->>rp: GET /api/v1/projects activate rp rp->>rp: Verify token and permissions rp->>pc: 200: Projects list deactivate rp pc->>hu: PRINT: Projects list deactivate pc

=> Login from external OIDC or OAuth2.0 provider with non-interactive flow. (client_credentials)

Note: it can be done exactly the same way using directly the backend API. Then one would have to manage the access_token and refresh_token by itself, and send access_token as an Authorization header in the subsequent requests.

sequenceDiagram participant ro as Robot #actor ro as Robot participant pc as percli Command Line participant rp as Perses Backend participant op as External Identity Provider ro->>pc: EXEC: percli login --provider --client-id --client-secret activate pc pc->>rp: GET /api/config activate rp rp->>pc: 200: Config
(containing Providers List) deactivate rp pc->>rp: GET /api/auth/providers/{oidc|oauth}/{slug_id}/token activate rp rp->>op: GET /oauth/token activate op op->>rp: 200: access_token deactivate op rp->>op: GET /api/userinfo
(endpoint from Perses Config or .well-known URL) activate op op->>rp: 200: User Info deactivate op Note right of rp: Only User Info is
used to sync user in database rp->>rp: Create or Update user in DB Note right of rp: A new session is created
with a new signed acces_token+refresh_token rp->>pc: 200: access_token + refresh_token deactivate rp pc->>pc: WRITE: session into config file pc->>ro: PRINT: Successfully authenticated! deactivate pc ro->>pc: EXEC: percli get projects activate pc pc->>rp: GET /api/v1/projects activate rp rp->>rp: Verify token and permissions rp->>pc: 200: Projects list deactivate rp pc->>ro: PRINT: Projects list deactivate pc