SAML 2.0 Authentication

Refresh Tokens

The SAML 2.0 connector in dex does not support refresh tokens "since the SAML 2.0 protocol doesn't provide a way to requery a provider without interaction" (see dex documentation for SAML 2.0).

STEP 1

Choose DEX_HOSTNAME And Configure DNS

Loft uses the CNCF project dex for single sign-on.

The easiest case is this one:

  • $LOFT_HOSTNAME = loft.mycompany.tld (where Loft is running)
  • $DEX_HOSTNAME = dex.mycompany.tld (where dex should be running)
  • Loft and dex should run in the same Kubernetes cluster

Then, you can set a CNAME record with value loft.mycompany.tld in the DNS configuration for dex.mycompany.tld.

STEP 2

Create Dex Config For SAML 2.0

Create the file dex-config.yaml with the following dex configuration:

ingress:
enabled: true
hosts:
- dex.yourcompany.tld # Use $DEX_HOSTNAME
config:
issuer: https://dex.yourcompany.tld # "https://" + $DEX_HOSTNAME
connectors:
- type: saml
id: saml
name: SAML
config:
ssoURL: https://saml.example.com/sso # Your SSO POST URL
# caData: ( base64 encoded PEM file ) # CA to use when validating the signature of the SAML response.
# insecureSkipSignatureValidation: true # Not recommended (testing only)
redirectURI: https://dex.yourcompany.tld/callback # Use https:// + $DEX_HOSTNAME + /callback
# entityIssuer: https://dex.yourcompany.tld/callback # Optional: Use https:// + $DEX_HOSTNAME + /callback
# Name of attributes in the returned assertions to map to ID token claims.
usernameAttr: name
emailAttr: email
groupsAttr: groups # optional
# List of groups to filter access based on membership
# allowedGroups
# - Admins
# Optional: Manually specify dex's Issuer value.
#
# When provided dex will include this as the Issuer value during AuthnRequest.
# It will also override the redirectURI as the required audience when evaluating
# AudienceRestriction elements in the response.
# Optional: Issuer value expected in the SAML response.
# ssoIssuer: https://saml.example.com/sso
# Optional: Delimiter for splitting groups returned as a single string.
#
# By default, multiple groups are assumed to be represented as multiple
# attributes with the same name.
#
# If "groupsDelim" is provided groups are assumed to be represented as a
# single attribute and the delimiter is used to split the attribute's value
# into multiple groups.
groupsDelim: ", "
# Optional: Requested format of the NameID.
#
# The NameID value is is mapped to the user ID of the user. This can be an
# abbreviated form of the full URI with just the last component. For example,
# if this value is set to "emailAddress" the format will resolve to:
#
# urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
#
# If no value is specified, this value defaults to:
#
# urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
#
nameIDPolicyFormat: persistent
staticClients:
- name: Loft
id: loft # Define a $DEX_CLIENT_ID
secret: XXXXXXXXXXXXXX # Define a $DEX_CLIENT_SECRET (can be any secret key)
redirectURIs:
- 'https://loft.mycompany.tld/auth/oidc/callback' # Loft URL + /auth/oidc/callback
oauth2:
skipApprovalScreen: true
web:
http: 0.0.0.0:5556
storage:
type: kubernetes
config:
inCluster: true

For details about configuring dex for SAML 2.0, take a look at the dex documentation for SAML 2.0.

STEP 3

Deploy Dex via Helm

After creating the file dex-config.yaml, you can now install dex via helm:

helm install dex dex --repo https://kubernetes-charts.storage.googleapis.com \
--create-namespace --namespace dex \
-f dex-config.yaml \
--wait
STEP 4

Configure Loft To Use Dex For Authentication

To tell Loft to use dex for SSO, navigate to Admin > Config in Loft and adjust your config as shown below:

auth:
oidc:
issuerUrl: https://dex.mycompany.tld # Use $DEX_HOSTNAME (see above)
clientId: "" # Use $DEX_CLIENT_ID (see above)
clientSecret: "" # Use $DEX_CLIENT_SECRET (see above)
type: "github" # Optional: SSO Login Button Icon ("", github, gitlab, microsoft, google)
usernameClaim: "email" # Optional: Which part of the dex token to use as Loft username (default: email)
usernamePrefix: "" # Optional: Add prefix to usernameClaim for Loft username
groupsClaim: "groups" # Optional: Add Kubernetes groups for this user
groupsPrefix: "loft-" # Optional: Prefix for Kubernetes groups
caFile: "" # Optional: Path to a CA cert of dex within the Loft container (default: '')
STEP 5

Authenticate via Dex + SAML 2.0

After saving the new Loft configuration, Loft will restart itself and you should be able to log in via SAML 2.0 and dex.

STEP 6

Disable Username + Password Authentication (optional)

To disable password-based authentication, navigate to Admin > Config add these two lines to your config:

auth:
oidc: ... # This is your SSO configuration (make sure this is working!)
password:
disabled: true # Disable password-based authentication