This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Authentication Handbook

How to configure and use the authentication backends

    Introduction

    cc-backend supports the following authentication methods:

    • Local login, with credentials stored in SQL database
    • LDAP login, with authentication to a LDAP directory
    • OpenID Connect login, with authentication against a KeyCloak instance
    • JWT login, with authentication via JSON Web Token:
      • With token provided in HTML request header
      • With token provided in cookie

    All above methods create a session cookie that is then used for subsequent authentication of requests. Multiple authentication methods can be configured at the same time. If LDAP is enabled it takes precedence over local authentication. The OpenID Connect method against a KeyCloak instance enables many more authentication methods using the ability of KeyCloak to act as an Identity Broker.

    The REST API uses stateless authentication via a JWT token, which means that every requests must be authenticated.

    Authorization control

    cc-backend uses roles to decide if a user is authorized to access certain information. The roles and their rights are described in more detail here.

    General configuration options

    All configuration is part of the cc-backend configuration file config.json. The primary key for authentication configuration options is auth. All security sensitive options as passwords and tokens are passed in terms of environment variables. cc-backend supports to read an .env file upon startup and set the environment variables contained there.

    Duration of session

    Per default the maximum duration of a session is 7 days. To change this the option main.session-max-age has to be set to a string that can be parsed by the Golang time.ParseDuration() function. For most use cases the largest unit h is the only relevant option.

    To enable unlimited session duration set main.session-max-age either to 0 or empty string.

    Example

    "main": {
      "session-max-age": "24h",
    }
    

    Local authentication

    No configuration is required for local authentication.

    Usage

    You can add an user on the command line using the flag -add-user:

    ./cc-backend -add-user <username>:<roles>:<password>
    

    Example:

    ./cc-backend -add-user fritz:admin,api:myPass
    

    Roles can be admin, support, manager, api, and user.

    Users can be deleted using the flag -del-user:

    ./cc-backend -del-user fritz
    

    LDAP authentication

    Configuration

    To enable LDAP authentication the following set of options are required as attributes of the auth.ldap JSON object:

    • url: URL of the LDAP directory server. This must be a complete URL including the protocol and not only the host name. Example: ldaps://ldsrv.mydomain.com.
    • user-base: Base DN of user tree root. Example: ou=people,ou=users,dc=rz,dc=mydomain,dc=com.
    • search-dn: DN for authenticating an LDAP admin account with general read rights. This is required for the sync on login and the sync options. Example: cn=monitoring,ou=adm,ou=profile,ou=manager,dc=rz,dc=mydomain,dc=com
    • user-bind: Expression used to authenticate users via LDAP bind. Must contain uid={username}. Example: uid={username},ou=people,ou=users,dc=rz,dc=mydomain,dc=com.
    • user-filter: Filter to extract users for syncing. Example: (&(objectclass=posixAccount)).

    Optional configuration options are:

    • username-attr: Attribute with full user name. Defaults to gecos if not provided.
    • sync-interval: Interval used for syncing SQL user table with LDAP directory. Parsed using time.ParseDuration. The sync interval is always relative to the time cc-backend was started. Example: 24h.
    • sync-del-old-users: Type boolean. Delete users in SQL database if not in LDAP directory anymore. This of course only applies to users that were added from LDAP.
    • sync-user-on-login: Type boolean. Add non-existent user to database at login attempt if user exists in LDAP directory. This option enables that users can login at once after they are added to the LDAP directory. Does not update user on recurring LDAP logins.
    • update-user-on-login: Type boolean. Update existent users in DB at login attempt if user exists in LDAP directory. This option updates changed source attributes, for example the name, if the database value differs. Does not add users on first-time LDAP login.

    Example

    "auth": {
      "ldap": {
        "url": "ldaps://ldsrv.mydomain.com",
        "user-base": "ou=people,ou=users,dc=rz,dc=mydomain,dc=com",
        "search-dn": "cn=monitoring,ou=adm,ou=profile,ou=manager,dc=rz,dc=mydomain,dc=com",
        "user-bind": "uid={username},ou=people,ou=users,dc=rz,dc=mydomain,dc=com",
        "user-filter": "(&(objectclass=posixAccount))"
      },
    }
    

    Environment

    The LDAP authentication method requires the environment variable LDAP_ADMIN_PASSWORD for the search-dn account that is used to sync users.

    Usage

    If LDAP is configured it is the first authentication method that is tried if a user logs in using the login form. A sync with the LDAP directory can also be triggered from the command line using the flag -sync-ldap.

    OpenID Connect authentication

    Configuration

    To enable OpenID Connect authentication the following set of options are required below a top-level auth.oidc key:

    • provider: The base URL of your OpenID Connect provider. Example: https://auth.example.com/realms/mycloud.

    Optional configuration options are:

    • sync-user-on-login: Type boolean. Add non-existent user to DB at login attempt if user exists in KeyCloak realm. This option enables that users can login at once after they are added to the KeyCloak realm. Does not update user on recurring OIDC logins.
    • update-user-on-login: Type boolean. Update existent users in DB at login attempt if user exists in KeyCloak realm. This option updates changed source attributes, for example the name, if the database value differs. Does not add users on first-time OIDC login.

    Example

    "oidc": {
      "provider": "https://auth.server.com:8080/realms/nhr-cloud"
    },
    

    Environment

    Furthermore the following environment variables have to be set (in the .env file):

    • OID_CLIENT_ID: Set this to the Client ID you configured in Keycloak (see below).
    • OID_CLIENT_SECRET: Set this to the Client ID secret available in your Keycloak Open ID Client configuration at the Credentials tab (see below).

    Required settings in KeyCloak

    The OpenID Connect implementation was only tested against the KeyCloak provider.

    Steps to setup KeyCloak:

    • Create a new realm. This will determine the provider URL.
    • Create a new OpenID Connect client
      • Set a Client ID
        • The Client ID secret is automatically generated after the client has been created.
      • Enable client authentication
      • For Access settings set:
        • Root URL: This is the base URL of your cc-backend instance.
        • Valid redirect URLs: Set this to oidc-callback.
          • Add an additional URL including the full HTTP path, e.g. http://localhost:8088/oidc-callback
          • If HTTPS is used, also add the HTTPS path, e.g. https://localhost:8088/oidc-callback
        • Web origins: Set this also to the base URL of your cc-backend instance.
    Keycloak Access settings

    Keycloak client Access settings

    • Enable PKCE:
      • Click on Advanced tab. Further click on Advanced Settings on the right side.
      • Set the option Proof Key for Code Exchange Code Challenge Method to S256.
    Set PKCE Keycloak option

    Keycloak advanced client settings for PKCE

    Everything else can be left to the default.

    Do not forget to create users in your realm before testing.

    Usage

    If the auth.oidc config key is correctly set and the required environment variables are available, an additional button for OpenID Connect Login is shown below the login mask. If pressed this button will redirect to the OpenID Connect login.

    OpenID Connect login mask

    Login mask with OpenID Connect enabled

    JWT token authentication

    JSON web tokens are a standardized method for representing encoded claims securely between two parties. In ClusterCockpit they are used for authorization to use REST APIs as well as a method to delegate authentication to a third party. This section only describes JWT based authentication for initiating a user session.

    Two variants exist:

    • [1] Session Authenticator: Passes JWT token in the HTTP header Authorization using the Bearer prefix or using the query key login-token.

    Example for Authorization header:

    Authorization: Bearer S0VLU0UhIExFQ0tFUiEK
    

    Example for query key used as form action in external application:

    <form method="post" action="$CCROOT/jwt-login?login-token=S0VLU0UhIExFQ0tFUiEK" target="_blank">
      <button type="submit">Access CC</button>
    </form>
    
    • [2] Cookie Session Authenticator: Reads the JWT token from a named cookie provided by the request, which is deleted after the session was successfully initiated. This is a more secure alternative to the standard header based solution.

    JWT Configuration

    • [0] Basic required configuration:

    In order to enable JWT based transactions generally, the following has to be true:

    • The jwts JSON object has to exist within config.json, even if no other attribute is set within.
      • We recommend to set max-age attribute: Specifies for how long a JWT token shall be valid, defined as a string parsable by time.ParseDuration().
      • This will only affect JWTs generated by ClusterCockpit, e.g. for the use with REST-API endpoints.

    In addition, the the following environment variables are used:

    • JWT_PRIVATE_KEY: The applications own private key to be used with JWT transactions. Required for cookie based logins and REST-API communication.

    • JWT_PUBLIC: The applications own public key to be used with JWT transactions. Required for cookie based logins and REST-API communication.

    • [1] Configuration for JWT Session Authenticator:

    Compatible signing methods are: HS256, HS512

    Only a shared (symmetric) key saved as environment variable CROSS_LOGIN_JWT_HS512_KEY is required.

    • [2] Configuration for JWT Cookie Session Authenticator:

    Tokens are signed with: Ed25519/EdDSA

    To enable JWT authentication via cookie the following set of options are required as attributes of the jwts JSON object:

    • cookie-name (String): Specifies which cookie should be checked for a JWT token (if no authorization header is present)
    • trusted-issuer (String): Specifies which issuer should be accepted when validating external JWTs (iss-claim)

    In addition, the Cookie Session Authenticator method requires the following environment variable:

    • CROSS_LOGIN_JWT_PUBLIC_KEY: Primary public key for this method, validates identity of tokens received from trusted-issuer and must therefore match accordingly.

    • [3] Optional configuration attributes of the jwts JSON object, valid for both [1] and [2], are:

    • validate-user (Bool): Load user by username encoded in sub-claim from database, including roles, denying login if not matched in database. Ignores all other claims. By design not combinable with both sync-user-on-login and/or update-user-on-login options.

    • sync-user-on-login (Bool): If user encoded in token does not exist in database, add a new user entry. Does not update user on recurring JWT logins.

    • update-user-on-login (Bool): If user encoded in token does exist in database, update the user entry with all encoded information. Does not add users on first-time JWT login.

    JWT Usage

    • [1] Usage for JWT Session Authenticator:

    The endpoint for initiating JWT logins in ClusterCockpit is /jwt-login

    For login with JWT Header, the header has to include the Authorization: Bearer $TOKEN information when accessing this endpoint. For login with JWT request parameter, the external website has to submit an action with the parameter ?login-token=$TOKEN (See example above).

    In both cases, the JWT should contain the following parameters:

    • sub: The subject, in this case this is the username. Will be used for user matching if validate-user is set.

    • exp: Expiration in Unix epoch time. Can be small as the token is only used during login.

    • name: The full name of the person assigned to this account. Will be used to update user table.

    • roles: String array with roles of user.

    • projects: [Optional] String array with projects of user. Relevant if user has manager-role.

    • [2] Usage for JWT Cookie Session Authenticator:

    The token must be set within a cookie with a name matching the configured cookie-name.

    The JWT should then contain the following parameters:

    • sub: The subject, in this case this is the username. Will be used for user matching if validate-user is set.
    • exp: Expiration in Unix epoch time. Can be small as the token is only used during login.
    • name: The full name of the person assigned to this account. Will be used to update user table.
    • roles: String array with roles of user.