Single sign-on (SSO) lets users log in to Stronghold with their corporate account and lets administrators manage access through groups in the identity provider (IdP). Stronghold supports any OpenID Connect-compatible IdP.

Goal

After the setup:

  • Users log in to the Stronghold web UI and CLI through the corporate IdP.
  • Policies are assigned by IdP groups through external Identity groups.
  • Only members of specific groups are allowed to log in.

General flow

OIDC login flow

What to configure in any IdP:

  1. An OIDC client (application) of the confidential type with a client secret.
  2. Redirect URIs: for the web UI, https://<STRONGHOLD_ADDRESS>/ui/stronghold/auth/<METHOD_PATH>/oidc/callback; for the CLI, http://localhost:8250/oidc/callback. Here <STRONGHOLD_ADDRESS> is the address at which users open Stronghold, and <METHOD_PATH> is the path at which the OIDC method is enabled.
  3. A claim with the list of the user’s groups in the ID token.

Choosing a provider

Choose the provider by where user accounts are managed:

ProviderWhen to useGuide
Dex in DPStronghold is installed in DP, and users already log in to the cluster through the user-authn moduleLogin through Dex in DP on this page
KeycloakA corporate IdP based on Keycloak, including federation from LDAP or ADKeycloak OIDC provider, example below
GitLabDeveloper accounts and groups are managed in GitLabGitLab OIDC provider
Another OIDC providerAny IdP with a /.well-known/openid-configuration discovery documentOIDC method

Prerequisites

Before you start, prepare the following:

  • Stronghold is available to users over HTTPS, for example https://stronghold.example.com.
  • The IdP is available to Stronghold nodes over HTTPS, and its certificate is issued by a trusted CA.
  • A Stronghold token with permissions to configure auth methods, policies, and Identity.
  • Prepared break-glass access in case the IdP is unavailable.

Example: Keycloak

In this example, users from the Keycloak group stronghold-admins get the admin policy, and users from stronghold-users get the user-read policy.

Step 1. Configure the client in Keycloak

Create an OIDC client for Stronghold in Keycloak.

  1. In the corp realm, create a stronghold client with the openid-connect protocol, and enable Client authentication and Standard flow.

  2. In Valid Redirect URIs, specify:

    https://stronghold.example.com/ui/stronghold/auth/oidc/oidc/callback
    http://localhost:8250/oidc/callback
  3. Add a Group Membership mapper with the groups claim name to the client and disable Full group path.

  4. On the Credentials tab, copy the client secret.

For details, see Keycloak OIDC provider.

Step 2. Configure the OIDC method

Enable the OIDC method in Stronghold and create a role for login.

  1. Enable the method and configure the connection to the realm:

    d8 stronghold auth enable oidc
    d8 stronghold write auth/oidc/config oidc_discovery_url="https://keycloak.example.com/realms/corp" oidc_client_id="stronghold" oidc_client_secret="<CLIENT_SECRET>" default_role="corp"

    <CLIENT_SECRET> is the client secret copied in step 1.

  2. Create a role. bound_claims admits only members of the two groups, and groups_claim passes the groups to Identity:

    d8 stronghold write auth/oidc/role/corp -<<EOF
    {
      "role_type": "oidc",
      "allowed_redirect_uris": [
        "https://stronghold.example.com/ui/stronghold/auth/oidc/oidc/callback",
        "http://localhost:8250/oidc/callback"
      ],
      "oidc_scopes": ["openid", "profile", "email"],
      "user_claim": "preferred_username",
      "groups_claim": "groups",
      "bound_claims": { "groups": ["stronghold-users", "stronghold-admins"] },
      "token_policies": ["default"],
      "token_ttl": "1h",
      "token_max_ttl": "8h"
    }
    EOF

Step 3. Map groups to policies

For each group, create an external Identity group and an alias. The alias name must match the group name in the groups claim:

OIDC_ACCESSOR=$(d8 stronghold auth list -format=json | jq -r '."oidc/".accessor')

ADMINS_ID=$(d8 stronghold write -field=id identity/group name="corp-admins" type="external" policies="admin")
d8 stronghold write identity/group-alias name="stronghold-admins" mount_accessor="$OIDC_ACCESSOR" canonical_id="$ADMINS_ID"

USERS_ID=$(d8 stronghold write -field=id identity/group name="corp-users" type="external" policies="user-read")
d8 stronghold write identity/group-alias name="stronghold-users" mount_accessor="$OIDC_ACCESSOR" canonical_id="$USERS_ID"

The admin and user-read policies must exist beforehand. See Policy examples.

Step 4. Check login

Check login through the CLI and the web UI.

  1. Log in through the CLI; a browser opens the Keycloak login page:

    d8 stronghold login -method=oidc role=corp
  2. Check the token policies:

    d8 stronghold token lookup

    For a member of stronghold-admins, identity_policies must contain the admin policy.

  3. In the web UI, select the OIDC method, enter the corp role, and log in.

Login through Dex in DP

If Stronghold is installed as a DP module in Automatic mode, after Stronghold is initialized the module itself configures login through Dex, the DP authentication provider that gets users and groups from a connected external IdP or LDAP.

  • The OIDC method is enabled at the oidc_deckhouse path, the default role deckhouse_dex_authenticated (the groups claim is groups) is created for login, and the deckhouse_administrators policy (full access) is assigned to administrators.
  • Administrators are set in the settings.management.administrators parameter of the stronghold ModuleConfig, as groups (type: Group) or individual users (type: User). A user must belong to at least one group.
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: stronghold
spec:
  enabled: true
  version: 1
  settings:
    management:
      mode: Automatic
      administrators:
      - type: Group
        name: admins

User login:

d8 stronghold login -path=oidc_deckhouse -method=oidc -no-print

To grant permissions to users other than administrators, create external Identity groups with aliases on the oidc_deckhouse/ method accessor, as in step 3 of the Keycloak example. Alias names must match the group names that Dex passes.

The module re-applies the configuration periodically (every 60 seconds by default), so manual changes in auth/oidc_deckhouse are overwritten:

  • the OIDC configuration of the method (discovery URL, client ID and secret, default role) and the deckhouse_dex_authenticated role (audience, redirect URIs, email and groups claims, scopes) are rewritten unconditionally; make your own changes in a separate role or at a separate path;
  • the method description and the unauth listing visibility are restored if you change them;
  • the deckhouse_administrators policy is removed from entities and groups on the oidc_deckhouse/ accessor that are not listed in settings.management.administrators; other policies are not touched.

All users log in with the same deckhouse_dex_authenticated role. The module creates no other roles for them: their permissions come from policies of Identity groups (see above).

For details, see Stronghold configuration and Configuring access and first login.

Troubleshooting

Common errors and how to fix them:

SymptomLikely causeWhat to do
The IdP or Stronghold rejects redirect_uriThe URIs in the IdP client and in the role’s allowed_redirect_uris differSpecify identical URIs in both places, including the method path.
Login is denied because of bound_claims, or the group list is emptyThe IdP does not include groups in the ID tokenCheck the group mapper in the IdP and the groups_claim value.
Login succeeds but group policies are missingThe alias name does not match the group name in the claim (for example, the full path /stronghold-admins is passed)Compare groups in the ID token with the alias names. In Keycloak, disable Full group path.
x509: certificate signed by unknown authority when writing auth/oidc/configStronghold does not trust the IdP certificatePass the CA chain in the oidc_discovery_ca_pem parameter.
The IdP is unavailable and nobody can log inIdP outage or configuration errorUse break-glass access.

Cleanup

Disable the OIDC method:

d8 stronghold auth disable oidc

Delete the corp-admins and corp-users external groups via identity/group/name/<GROUP_NAME> and the stronghold client in Keycloak.

Additional resources