Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional and Configurable LDAP User/Session Management Support and Reworked Pluggable Auth Driver Interface #9750

Merged
merged 52 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5b61b2e
Initial commit of LDAP Auth driver support with toml config docs and …
CL-Andrew Jul 8, 2023
dd3d93a
'orm sessions.UserManager' to 'um sessions.UserManager'
CL-Andrew Aug 9, 2023
1d15f8a
Add missing checks for the UserApiTokenEnabled config field for token…
CL-Andrew Aug 10, 2023
80d783a
Update docs toml LDAP section to clarify how the fields are used and …
CL-Andrew Aug 10, 2023
06395bb
Clarify LDAP 'cn' in toml docs for LDAP
CL-Andrew Aug 10, 2023
759e3b6
Fix WebServer TOML and config definitions, split types for WebServerL…
CL-Andrew Aug 10, 2023
2fd1bb2
Error application startup if authentication method is not one of the …
CL-Andrew Aug 10, 2023
0fca853
Don't export unneeded ldapGroupMembersListToUser in ldap module
CL-Andrew Aug 10, 2023
3f67e60
Bugfixes for LDAP find user when no results of passed email, address …
CL-Andrew Aug 10, 2023
6c600cf
Rework LDAP function to check if list of provided query emails posses…
CL-Andrew Aug 10, 2023
d745e13
Update LDAP field naming for Cn, Dn to Go convention CN, DN in toml a…
CL-Andrew Aug 10, 2023
0011ec2
Post merge toml module rename LDAP model fixes
CL-Andrew Aug 11, 2023
ffa0f93
Update top level application struct to accomodate new sibling AuthPro…
CL-Andrew Aug 15, 2023
b5c5aed
Update all err comparison checks for ErrNotSupported to errors.Is
CL-Andrew Aug 15, 2023
91498ff
go generate mocks
CL-Andrew Aug 15, 2023
9d08afb
Tidy unecessary string cast, bump ldap library to latest and use v3, …
CL-Andrew Aug 17, 2023
04d6c78
Clean up auth provider config switch statement
CL-Andrew Aug 17, 2023
5bcd962
Update checked in test txtar output
CL-Andrew Aug 17, 2023
e7725b6
Update gql test and mocks with new authprovider mock, updated in mock…
CL-Andrew Aug 18, 2023
6ef83c0
Update remaining test config toml files with new WebServer LDAP field…
CL-Andrew Aug 18, 2023
eec0e72
Update LDAP module with missing API token implementation - creation, …
CL-Andrew Sep 7, 2023
9ed16f2
Add missing support for local CLI user and auth when using LDAP Authe…
CL-Andrew Sep 22, 2023
284cce8
Update config UpstreamSyncInterval and UpstreamSyncRateLimit function…
CL-Andrew Oct 18, 2023
c27bf9a
LDAP Fix for checks of optional isactive property on group query, fin…
CL-Andrew Oct 19, 2023
2c86a0c
bump migration file index
CL-Andrew Oct 20, 2023
4be1c87
remove incorrect rebased merge resolution for Explorer removal
CL-Andrew Oct 20, 2023
5f07bc0
Change default config definitions for LDAP 'Is Active' attribute chec…
CL-Andrew Oct 20, 2023
7c7ded9
Simplify sessions purge sql exec using pq.Array instead of manually g…
CL-Andrew Oct 20, 2023
fe05307
Merge go mod require groups, gotidy
CL-Andrew Oct 20, 2023
d33cc91
Rename changed authentication provider session ORM in test files, fix…
CL-Andrew Oct 20, 2023
355f6bc
Add mock value for one test case of config ldap is active attribute, …
CL-Andrew Oct 20, 2023
9cea92e
Factor out unsupported action error message in user controller with n…
CL-Andrew Oct 21, 2023
7c8af47
Rebase, update migration index
CL-Andrew Oct 21, 2023
7003f6f
Update config_test full case, error case for missing fields
CL-Andrew Oct 25, 2023
7832e94
Fix tests with missing Mocks for cmd shell, config resolver, and sess…
CL-Andrew Nov 2, 2023
00fca56
Bump migration file index for ldap tables
CL-Andrew Nov 2, 2023
a0f9965
Linter fixes - application.go localAdminUsersORM in initialized one line
CL-Andrew Nov 2, 2023
9b5fdbb
Add missing ldap fields to warnings.txtar, fix err shadowing linter e…
CL-Andrew Nov 2, 2023
dcd4a1d
Fix linter import order and groupings
CL-Andrew Nov 2, 2023
32479d4
More import ordering lint
CL-Andrew Nov 2, 2023
2f48b66
Rebase, bump sql migraiton index
CL-Andrew Nov 2, 2023
ebe7ea3
use correct guregu/null.v4 version
CL-Andrew Nov 2, 2023
ca6f16d
Implement test cases for ldap module, create LDAP client and LDAPConn…
CL-Andrew Nov 3, 2023
476c05c
Updated CHANGELOG.md
CL-Andrew Nov 3, 2023
996694a
Update go.mod
CL-Andrew Nov 3, 2023
98796e9
Linter fixes UserNoLDAPGroups -> ErrUserNoLDAPGroups, shadowing
CL-Andrew Nov 3, 2023
5486fdf
module -> package, format package docstring properly for ldapauth to …
CL-Andrew Nov 3, 2023
878d6eb
Remove rebased gomod line
CL-Andrew Nov 3, 2023
4a9ada5
define const NodeAdmins* for mocked tests in helpers_test, reference …
CL-Andrew Nov 3, 2023
3e6ef56
Add missing returns in sync Work call when failed to establish LDAP c…
CL-Andrew Nov 3, 2023
619cf1d
Updating naming and address nits
CL-Andrew Nov 3, 2023
1970f2b
Add missed go generate Application change for BasicAdminUsersORM rename
CL-Andrew Nov 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/cmd/admin_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestShell_ChangeRole(t *testing.T) {
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
require.NoError(t, app.SessionORM().CreateUser(&user))
require.NoError(t, app.AuthenticationProvider().CreateUser(&user))

tests := []struct {
name string
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestShell_DeleteUser(t *testing.T) {
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
require.NoError(t, app.SessionORM().CreateUser(&user))
require.NoError(t, app.LocalAdminUsersORM().CreateUser(&user))

tests := []struct {
name string
Expand Down Expand Up @@ -135,7 +135,7 @@ func TestShell_ListUsers(t *testing.T) {
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
require.NoError(t, app.SessionORM().CreateUser(&user))
require.NoError(t, app.AuthenticationProvider().CreateUser(&user))

set := flag.NewFlagSet("test", 0)
cltest.FlagSetApplyFromAction(client.ListUsers, set, "")
Expand Down
1 change: 1 addition & 0 deletions core/cmd/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ func Test_initServerConfig(t *testing.T) {
"../services/chainlink/testdata/mergingsecretsdata/secrets-mercury-split-one.toml",
"../services/chainlink/testdata/mergingsecretsdata/secrets-mercury-split-two.toml",
"../services/chainlink/testdata/mergingsecretsdata/secrets-threshold.toml",
"../services/chainlink/testdata/mergingsecretsdata/secrets-webserver-ldap.toml",
},
},
wantErr: false,
Expand Down
12 changes: 6 additions & 6 deletions core/cmd/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,8 @@ func (f *fileSessionRequestBuilder) Build(file string) (sessions.SessionRequest,
// APIInitializer is the interface used to create the API User credentials
// needed to access the API. Does nothing if API user already exists.
type APIInitializer interface {
// Initialize creates a new user for API access, or does nothing if one exists.
Initialize(orm sessions.ORM, lggr logger.Logger) (sessions.User, error)
// Initialize creates a new local Admin user for API access, or does nothing if one exists.
Initialize(orm sessions.LocalAdminUsersORM, lggr logger.Logger) (sessions.User, error)
}

type promptingAPIInitializer struct {
Expand All @@ -791,11 +791,11 @@ func NewPromptingAPIInitializer(prompter Prompter) APIInitializer {
}

// Initialize uses the terminal to get credentials that it then saves in the store.
func (t *promptingAPIInitializer) Initialize(orm sessions.ORM, lggr logger.Logger) (sessions.User, error) {
func (t *promptingAPIInitializer) Initialize(orm sessions.LocalAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
// Load list of users to determine which to assume, or if a user needs to be created
dbUsers, err := orm.ListUsers()
if err != nil {
return sessions.User{}, err
return sessions.User{}, errors.Wrap(err, "Unable to List users for initialization")
}

// If there are no users in the database, prompt for initial admin user creation
Expand Down Expand Up @@ -845,7 +845,7 @@ func NewFileAPIInitializer(file string) APIInitializer {
return fileAPIInitializer{file: file}
}

func (f fileAPIInitializer) Initialize(orm sessions.ORM, lggr logger.Logger) (sessions.User, error) {
func (f fileAPIInitializer) Initialize(orm sessions.LocalAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
request, err := credentialsFromFile(f.file, lggr)
if err != nil {
return sessions.User{}, err
Expand All @@ -854,7 +854,7 @@ func (f fileAPIInitializer) Initialize(orm sessions.ORM, lggr logger.Logger) (se
// Load list of users to determine which to assume, or if a user needs to be created
dbUsers, err := orm.ListUsers()
if err != nil {
return sessions.User{}, err
return sessions.User{}, errors.Wrap(err, "Unable to List users for initialization")
}

// If there are no users in the database, create initial admin user from session request from file creds
Expand Down
7 changes: 4 additions & 3 deletions core/cmd/shell_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@ func (s *Shell) runNode(c *cli.Context) error {
return s.errorOut(errors.Wrap(err, "fatal error instantiating application"))
}

sessionORM := app.SessionORM()
// Local shell initialization always uses local auth users table for admin auth
authProviderORM := app.LocalAdminUsersORM()
keyStore := app.GetKeyStore()
err = s.KeyStoreAuthenticator.authenticate(keyStore, s.Config.Password())
if err != nil {
Expand Down Expand Up @@ -449,11 +450,11 @@ func (s *Shell) runNode(c *cli.Context) error {
}

var user sessions.User
if user, err = NewFileAPIInitializer(c.String("api")).Initialize(sessionORM, lggr); err != nil {
if user, err = NewFileAPIInitializer(c.String("api")).Initialize(authProviderORM, lggr); err != nil {
if !errors.Is(err, ErrNoCredentialFile) {
return errors.Wrap(err, "error creating api initializer")
}
if user, err = s.FallbackAPIInitializer.Initialize(sessionORM, lggr); err != nil {
if user, err = s.FallbackAPIInitializer.Initialize(authProviderORM, lggr); err != nil {
if errors.Is(err, ErrorNoAPICredentialsAvailable) {
return errors.WithStack(err)
}
Expand Down
11 changes: 6 additions & 5 deletions core/cmd/shell_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
evmrelayer "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/sessions"
"github.com/smartcontractkit/chainlink/v2/core/sessions/localauth"
"github.com/smartcontractkit/chainlink/v2/core/store/dialects"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/v2/core/utils"
Expand Down Expand Up @@ -79,7 +79,7 @@ func TestShell_RunNodeWithPasswords(t *testing.T) {
})
db := pgtest.NewSqlxDB(t)
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
sessionORM := sessions.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)

lggr := logger.TestLogger(t)

Expand All @@ -100,7 +100,8 @@ func TestShell_RunNodeWithPasswords(t *testing.T) {
pgtest.MustExec(t, db, "DELETE FROM users;")

app := mocks.NewApplication(t)
app.On("SessionORM").Return(sessionORM).Maybe()
app.On("AuthenticationProvider").Return(authProviderORM).Maybe()
app.On("LocalAdminUsersORM").Return(authProviderORM).Maybe()
app.On("GetKeyStore").Return(keyStore).Maybe()
app.On("GetRelayers").Return(testRelayers).Maybe()
app.On("Start", mock.Anything).Maybe().Return(nil)
Expand Down Expand Up @@ -171,7 +172,7 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) {
c.Insecure.OCRDevelopmentMode = nil
})
db := pgtest.NewSqlxDB(t)
sessionORM := sessions.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)

// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
Expand Down Expand Up @@ -199,7 +200,7 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) {
}
testRelayers := genTestEVMRelayers(t, opts, keyStore)
app := mocks.NewApplication(t)
app.On("SessionORM").Return(sessionORM)
app.On("LocalAdminUsersORM").Return(authProviderORM)
app.On("GetKeyStore").Return(keyStore)
app.On("GetRelayers").Return(testRelayers).Maybe()
app.On("Start", mock.Anything).Maybe().Return(nil)
Expand Down
16 changes: 8 additions & 8 deletions core/cmd/shell_remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ func TestShell_DestroyExternalInitiator_NotFound(t *testing.T) {
func TestShell_RemoteLogin(t *testing.T) {

app := startNewApplicationV2(t, nil)
orm := app.SessionORM()
orm := app.AuthenticationProvider()

u := cltest.NewUserWithSession(t, orm)

Expand Down Expand Up @@ -301,7 +301,7 @@ func TestShell_RemoteBuildCompatibility(t *testing.T) {
t.Parallel()

app := startNewApplicationV2(t, nil)
u := cltest.NewUserWithSession(t, app.SessionORM())
u := cltest.NewUserWithSession(t, app.AuthenticationProvider())
enteredStrings := []string{u.Email, cltest.Password}
prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: append(enteredStrings, enteredStrings...)}
client := app.NewAuthenticatingShell(prompter)
Expand Down Expand Up @@ -340,7 +340,7 @@ func TestShell_CheckRemoteBuildCompatibility(t *testing.T) {
t.Parallel()

app := startNewApplicationV2(t, nil)
u := cltest.NewUserWithSession(t, app.SessionORM())
u := cltest.NewUserWithSession(t, app.AuthenticationProvider())
tests := []struct {
name string
remoteVersion, remoteSha string
Expand Down Expand Up @@ -416,7 +416,7 @@ func TestShell_ChangePassword(t *testing.T) {
t.Parallel()

app := startNewApplicationV2(t, nil)
u := cltest.NewUserWithSession(t, app.SessionORM())
u := cltest.NewUserWithSession(t, app.AuthenticationProvider())

enteredStrings := []string{u.Email, cltest.Password}
prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: enteredStrings}
Expand Down Expand Up @@ -466,7 +466,7 @@ func TestShell_Profile_InvalidSecondsParam(t *testing.T) {
t.Parallel()

app := startNewApplicationV2(t, nil)
u := cltest.NewUserWithSession(t, app.SessionORM())
u := cltest.NewUserWithSession(t, app.AuthenticationProvider())
enteredStrings := []string{u.Email, cltest.Password}
prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: enteredStrings}

Expand Down Expand Up @@ -497,7 +497,7 @@ func TestShell_Profile(t *testing.T) {
t.Parallel()

app := startNewApplicationV2(t, nil)
u := cltest.NewUserWithSession(t, app.SessionORM())
u := cltest.NewUserWithSession(t, app.AuthenticationProvider())
enteredStrings := []string{u.Email, cltest.Password}
prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: enteredStrings}

Expand Down Expand Up @@ -648,7 +648,7 @@ func TestShell_AutoLogin(t *testing.T) {
app := startNewApplicationV2(t, nil)

user := cltest.MustRandomUser(t)
require.NoError(t, app.SessionORM().CreateUser(&user))
require.NoError(t, app.LocalAdminUsersORM().CreateUser(&user))

sr := sessions.SessionRequest{
Email: user.Email,
Expand Down Expand Up @@ -676,7 +676,7 @@ func TestShell_AutoLogin_AuthFails(t *testing.T) {
app := startNewApplicationV2(t, nil)

user := cltest.MustRandomUser(t)
require.NoError(t, app.SessionORM().CreateUser(&user))
require.NoError(t, app.LocalAdminUsersORM().CreateUser(&user))

sr := sessions.SessionRequest{
Email: user.Email,
Expand Down
13 changes: 7 additions & 6 deletions core/cmd/shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks"
"github.com/smartcontractkit/chainlink/v2/core/sessions"
"github.com/smartcontractkit/chainlink/v2/core/sessions/localauth"
"github.com/smartcontractkit/chainlink/v2/plugins"
)

func TestTerminalCookieAuthenticator_AuthenticateWithoutSession(t *testing.T) {
t.Parallel()

app := cltest.NewApplicationEVMDisabled(t)
u := cltest.NewUserWithSession(t, app.SessionORM())
u := cltest.NewUserWithSession(t, app.AuthenticationProvider())

tests := []struct {
name, email, pwd string
Expand Down Expand Up @@ -65,7 +66,7 @@ func TestTerminalCookieAuthenticator_AuthenticateWithSession(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))

u := cltest.NewUserWithSession(t, app.SessionORM())
u := cltest.NewUserWithSession(t, app.AuthenticationProvider())

tests := []struct {
name, email, pwd string
Expand Down Expand Up @@ -155,7 +156,7 @@ func TestTerminalAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
db := pgtest.NewSqlxDB(t)
lggr := logger.TestLogger(t)
orm := sessions.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)

mock := &cltest.MockCountingPrompter{T: t, EnteredStrings: test.enteredStrings, NotTerminal: !test.isTerminal}
tai := cmd.NewPromptingAPIInitializer(mock)
Expand Down Expand Up @@ -186,7 +187,7 @@ func TestTerminalAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
lggr := logger.TestLogger(t)
orm := sessions.NewORM(db, time.Minute, lggr, cfg.Database(), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, lggr, cfg.Database(), audit.NoopLogger)

// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
Expand Down Expand Up @@ -223,7 +224,7 @@ func TestFileAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
db := pgtest.NewSqlxDB(t)
lggr := logger.TestLogger(t)
orm := sessions.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)

// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
Expand All @@ -248,7 +249,7 @@ func TestFileAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
func TestFileAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
orm := sessions.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)

tests := []struct {
name string
Expand Down
40 changes: 40 additions & 0 deletions core/config/docs/core.toml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ MaxAgeDays = 0 # Default
MaxBackups = 1 # Default

[WebServer]
# AuthenticationMethod defines which pluggable auth interface to use for user login and role assumption. Options include 'local' and 'ldap'. See docs for more details
AuthenticationMethod = 'local' # Default
# AllowOrigins controls the URLs Chainlink nodes emit in the `Allow-Origins` header of its API responses. The setting can be a comma-separated list with no spaces. You might experience CORS issues if this is not set correctly.
#
# You should set this to the external URL that you use to access the Chainlink UI.
Expand Down Expand Up @@ -191,6 +193,44 @@ StartTimeout = '15s' # Default
# ListenIP specifies the IP to bind the HTTP server to
ListenIP = '0.0.0.0' # Default

# Optional LDAP config if WebServer.AuthenticationMethod is set to 'ldap'
# LDAP queries are all parameterized to support custom LDAP 'dn', 'cn', and attributes
[WebServer.LDAP]
# ServerTLS defines the option to require the secure ldaps
ServerTLS = true # Default
# SessionTimeout determines the amount of idle time to elapse before session cookies expire. This signs out GUI users from their sessions.
SessionTimeout = '15m0s' # Default
# QueryTimeout defines how long queries should wait before timing out, defined in seconds
QueryTimeout = '2m0s' # Default
# BaseUserAttr defines the base attribute used to populate LDAP queries such as "uid=$", default is example
BaseUserAttr = 'uid' # Default
# BaseDN defines the base LDAP 'dn' search filter to apply to every LDAP query, replace example,com with the appropriate LDAP server's structure
BaseDN = 'dc=custom,dc=example,dc=com' # Example
# UsersDN defines the 'dn' query to use when querying for the 'users' 'ou' group
UsersDN = 'ou=users' # Default
# GroupsDN defines the 'dn' query to use when querying for the 'groups' 'ou' group
GroupsDN = 'ou=groups' # Default
# ActiveAttribute is an optional user field to check truthiness for if a user is valid/active. This is only required if the LDAP provider lists inactive users as members of groups
ActiveAttribute = '' # Default
# ActiveAttributeAllowedValue is the value to check against for the above optional user attribute
ActiveAttributeAllowedValue = '' # Default
# AdminUserGroupCN is the LDAP 'cn' of the LDAP group that maps the core node's 'Admin' role
AdminUserGroupCN = 'NodeAdmins' # Default
# EditUserGroupCN is the LDAP 'cn' of the LDAP group that maps the core node's 'Edit' role
EditUserGroupCN = 'NodeEditors' # Default
# RunUserGroupCN is the LDAP 'cn' of the LDAP group that maps the core node's 'Run' role
RunUserGroupCN = 'NodeRunners' # Default
# ReadUserGroupCN is the LDAP 'cn' of the LDAP group that maps the core node's 'Read' role
ReadUserGroupCN = 'NodeReadOnly' # Default
# UserApiTokenEnabled enables the users to issue API tokens with the same access of their role
UserApiTokenEnabled = false # Default
# UserAPITokenDuration is the duration of time an API token is active for before expiring
UserAPITokenDuration = '240h0m0s' # Default
# UpstreamSyncInterval is the interval at which the background LDAP sync task will be called. A '0s' value disables the background sync being run on an interval. This check is already performed during login/logout actions, all sessions and API tokens stored in the local ldap tables are updated to match the remote server
UpstreamSyncInterval = '0s' # Default
CL-Andrew marked this conversation as resolved.
Show resolved Hide resolved
# UpstreamSyncRateLimit defines a duration to limit the number of query/API calls to the upstream LDAP provider. It prevents the sync functionality from being called multiple times within the defined duration
UpstreamSyncRateLimit = '2m0s' # Default
CL-Andrew marked this conversation as resolved.
Show resolved Hide resolved

[WebServer.RateLimit]
# Authenticated defines the threshold to which authenticated requests get limited. More than this many authenticated requests per `AuthenticatedRateLimitPeriod` will be rejected.
Authenticated = 1000 # Default
Expand Down
9 changes: 9 additions & 0 deletions core/config/docs/secrets.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ BackupURL = "postgresql://user:pass@read-replica.example.com:5432/dbname?sslmode
# Environment variable: `CL_DATABASE_ALLOW_SIMPLE_PASSWORDS`
AllowSimplePasswords = false # Default

# Optional LDAP config
[WebServer.LDAP]
# ServerAddress is the full ldaps:// address of the ldap server to authenticate with and query
ServerAddress = 'ldaps://127.0.0.1' # Example
# ReadOnlyUserLogin is the username of the read only root user used to authenticate the requested LDAP queries
ReadOnlyUserLogin = 'viewer@example.com' # Example
# ReadOnlyUserPass is the password for the above account
ReadOnlyUserPass = 'password' # Example

[Password]
# Keystore is the password for the node's account.
#
Expand Down
Loading
Loading