The module lifecycle stage: General Availability
The module has requirements for installation
OmniAuth Configuration
The spec.appConfig.omniauth section allows configuring external authentication providers in Deckhouse Code. OIDC, SAML, GitHub, GitLab, and other providers are supported.
Parameters
| Parameter | Default | Description |
|---|---|---|
enabled |
false |
Enable OmniAuth |
allowSingleSignOn |
[] |
List of providers whose buttons are displayed on the Code sign-in page. Users will be able to authenticate through the specified providers |
blockAutoCreatedUsers |
true |
Block automatically created OmniAuth users until approved by an administrator |
autoLinkUser |
[] |
If a user already exists in Code with the same email as the account in the specified provider, they will be automatically linked upon sign-in. Without this setting, such a user will not be able to sign in via OmniAuth: if blockAutoCreatedUsers: true — the user will be blocked; if blockAutoCreatedUsers: false — a duplicate account will be created |
autoLinkLdapUser |
false |
Upon OmniAuth sign-in, automatically creates a link between the OmniAuth account and the corresponding LDAP user. Requires a configured LDAP integration. Used rarely, in specific migration or dual-identity scenarios |
autoLinkSamlUser |
false |
Same as autoLinkLdapUser, but for SAML: upon OmniAuth sign-in, creates a link with the corresponding SAML account. Requires a configured SAML integration. Used rarely, in specific scenarios |
autoSignInWithProvider |
— | Automatically redirect users to the specified provider’s sign-in page when opening the login page |
externalProviders |
[] |
Users who sign in through these providers receive “external” status and have no access to internal groups and projects |
syncProfileFromProvider |
[] |
List of providers from which the user profile is synchronized |
syncProfileAttributes |
[name, email] |
Profile attributes to synchronize |
allowBypassTwoFactor |
[] |
Providers for which Code’s built-in two-factor authentication is bypassed. If 2FA is enabled at the Code level, it will be prompted even during SSO sign-in — this setting disables that behavior for the specified providers |
providers |
[] |
List of authentication providers. See provider configuration |
Provider Configuration
Each provider in the providers list is described by the following fields:
| Field | Description |
|---|---|
name |
Provider type. Allowed values: alicloud, atlassioan_oauth2, auth0, cognito, azute_activedirectory_v2, bitbucket, oauth2_generic, github, gitlab, google_oauth2, jwt, kerberos, openid_connect, salesforce, saml, shibboleth |
label |
Display name shown on the sign-in button |
icon |
URL of the icon displayed on the sign-in button (for example, https://example.com/icon.png) |
args |
Provider-specific parameters (depend on type) |
Fields for openid_connect:
args field |
Description |
|---|---|
name |
Must match the provider name field |
scope |
List of OAuth scopes to request from the provider |
response_type |
OAuth response type. For most OIDC providers — code |
issuer |
OIDC provider issuer URL. Used to build endpoint URLs when discovery: false, and to validate tokens |
discovery |
If true — provider endpoints are discovered automatically from <issuer>/.well-known/openid-configuration |
client_auth_method |
Client authentication method used when calling the token endpoint. query — credentials are passed as query parameters |
client_options.identifier |
Client ID issued by the provider |
client_options.secret |
Client Secret issued by the provider |
client_options.redirect_uri |
URI to which the provider redirects the user after authentication. Must match the URI registered with the provider |
Example:
args:
name: openid_connect
scope: ["openid", "profile", "email"]
response_type: "code"
issuer: "https://dex.example.com"
discovery: true
client_auth_method: "query"
client_options:
identifier: "<client-id>"
secret: "<client-secret>"
redirect_uri: "https://code.example.com/users/auth/openid_connect/callback"OpenID Connect (OIDC)
Setting up authentication via Deckhouse (Dex)
-
Configure
DexClient:apiVersion: deckhouse.io/v1 kind: DexClient metadata: name: myname namespace: mynamespace spec: redirectURIs: - https://code.example.com/users/auth/openid_connect/callback allowedGroups: - Everyone - admins -
Retrieve the
DexClientsecret:kubectl -n mynamespace get secret dex-client-myname -o jsonpath='{.data.clientSecret}' | base64 -d -
Add the provider to
CodeInstance:spec: appConfig: omniauth: enabled: true allowSingleSignOn: - openid_connect blockAutoCreatedUsers: false providers: - name: openid_connect label: "Deckhouse" args: name: openid_connect scope: ["openid", "profile", "email"] response_type: "code" issuer: "https://dex.example.com" discovery: true client_auth_method: "query" client_options: identifier: "dex-client-myname@mynamespace" secret: "<clientSecret>" redirect_uri: "https://code.example.com/users/auth/openid_connect/callback" -
Wait for changes to be applied by the operator.
SAML
For SAML integration, the following new parameters have been added:
allowed_groups: An array of groups permitted to log in. Users who do not belong to these groups will be blocked and unable to log in.Default:null(allows all groups).admin_groups: An array of groups permitted to log in as administrators. Users belonging to these groups will be granted an admin role.Default:null(no groups are granted admin privileges).groups_attribute: The attribute name used to retrieve user groups. Default:'Groups'.
Example Configuration
Section is under spec.appConfig.omniauth.
providers:
- name: 'saml'
allowed_groups:
- 'gitlab'
admin_groups:
- 'admin'
groups_attribute: 'gitlab_group'Note: for oidc and SAML If a user belongs to
admin_groupsbut is not present inallowed_groups, they will not be able to log in. In such cases,admin_groupswill not be considered, and the user will not be granted administrative privileges.
LDAP Synchronization
Performs synchronization of users, groups, and group access rights with the LDAP server. By default, it happens once per hour.
You can configure the synchronization schedule via cronJobs param (at spec.appConfig. section):
cronJobs:
ldapSyncWorker:
cron: "0 * * * *"LDAP Server-Side Limits
During synchronization, queries are made for all users and groups specified in the configuration file. The synchronization task automatically uses pagination if needed. However, if the LDAP server has a limit on the maximum number of records returned, it may lead to unexpected user access being blocked or removed.
Example LDAP Provider Configuration
Section is located under spec.appConfig.ldap.servers
main:
label: ldap
host: 127.0.0.1
port: 3389
bindDn: 'uid=viewer,ou=People,dc=example,dc=com'
base: 'ou=People,dc=example,dc=com'
uid: 'cn'
password: 'viewer123'
syncName: true
groupSync:
createGroups: true
base: 'ou=Groups,dc=example,dc=org'
filter: '(objectClass=groupOfNames)'
prefix:
attribute: 'businessCategory'
default: 'default-program'
topLevelGroup: "LdapGroups"
nameMask: "(?<=-)[A-z0-9\_]*$"
owner: "root"
roleMapping:
- byName: '.*-project_manager-.*'
gitlabRole: 'Maintainer'
- byName: '.*-developer-.*'
gitlabRole: 'Developer'
- byName: '.*-participant-.*'
gitlabRole: 'Reporter'Group and Access Rights Synchronization
Creates GitLab groups and assigns user roles based on records retrieved from the LDAP server. Can be configured with the following parameters:
Required Parameters:
- groupSync.base — The base DN from which the search begins.
Optional Parameters:
- groupSync.createGroups — If
true, groups will be created in Deckhouse Code. - groupSync.filter — LDAP filter for groups.
- groupSync.scope — Search scope (0 — Base, 1 — SingleLevel, 2 — WholeSubtree).
- groupSync.prefix — Defines which attribute to use for the parent group name. If the attribute is missing, the default value is used.
- groupSync.topLevelGroup — The name of the top-level group to which all synchronized groups will be added.
- groupSync.nameMask — A regular expression to extract the group name from the
cnattribute. The expression must not contain capturing groups. The result of applying the expression must be exactly the value used as the group name. For strict boundaries, use lookbehind and/or lookahead. - groupSync.owner — The username to be added as the group owner (default is
root).
roleMapping section
Assigns access rights to users based on the group name (cn):
- roleMapping.byName — A regular expression; if the group name matches, the corresponding
gitlabRoleis assigned to the user. - roleMapping.gitlabRole — The Deckhouse Code role name (e.g.,
Guest,Reporter,Developer,Maintainer,Owner).
Deckhouse Code leverages basic roles from Gitlab
How group membership is defined
Group members are determined from the following group attributes. The value of each attribute is expected to be an array of user DNs:
memberuniquemembermemberofmemberuidsubmember
User Synchronization
Locks and unlocks users and updates their name and email based on data from the LDAP server.
Optional parameters:
syncName - if true, the user’s name will be updated from LDAP data
Username Transformation Rule:
| Extensions List |
|---|
html, xhtml, text, txt, js, css, markdown, md, diff, patch, vtt, yaml, yml |
png, jpeg, jpg, jpe, pjpeg, gif, bmp, tiff, tif, svg, webp, ico |
mp3, mp1, mp2, ogg, oga, spx, opus, m4a, aac |
mpeg, mpg, mpe, mpg4, webm, mp4, m4v, mov, ogv |
otf, ttf, woff, woff2 |
pdf |
zip, gzip, gz |
csv, json, xml, rss, atom, vcf, ics |
multipart_form, url_encoded_form |
If an LDAP username contains a dot (.) followed by a file extension that matches an entry in the defined extensions table, the dot (.) preceding the extension is automatically replaced with an underscore (_).
This transformation ensures compatibility with GitLab’s username requirements while preserving the original identity as much as possible.
Examples:
Ldap username: a.ivanov.ini
Gitlab username:a.ivanov_ini
Ldap username: a.k.ivanov
Gitlab username:a.k.ivanov
Ldap username: a.k.ivanov.ini
Gitlab username:a.k.ivanov_ini
Ldap username: a.ini.ivanov
Gitlab username:a.ini.ivanov
Troubleshooting synchronization
If a previous synchronization job did not complete correctly, Redis may retain a record indicating the job is still running. This prevents a new job from starting because concurrency is set to 1.
To fix perform following steps:
- Connect to Redis using the databases specified in
config/redis.shared_state.ymlandconfig/redis.queues.yml. - Delete the following key:
sidekiq:concurrency_limit:throttled_jobs:{ldap/sync_worker}by executing:
keys *ldap*- makes sures the key existsdel "sidekiq:concurrency_limit:throttled_jobs:{ldap/sync_worker}"- deletes the key