Search
K

Attribute providers

Attribute Providers enables the Maverics Orchestrator to act as a source of user attributes. Attribute Providers can be leveraged to enhance a user's profile with metadata from multiple sources to provide a richer user experience.
This feature is experimental and hence requires a feature flag to be enabled in order to leverage Attribute Providers in the Maverics Orchestrator. The feature flag name is attrproviders.

Available types of Attribute Providers

LDAP Attribute Provider

LDAP Attribute Provider creates an LDAP server allowing client connections via TLS. This is different from the LDAP connector which acts as a client to query external LDAP sources.
The LDAP Attribute Provider supports the following LDAP requests:

StartTLS

StartTLS upgrades the TCP connection to TLS using the provided tls config. LDAP clients may leverage StartTLS to secure their connection in case the LDAP provider has been configured with ldap:// vs ldaps://.

Bind

Bind uses the authenticateSE Service Extension to authenticate the LDAP connection. Currently, the Bind operation only supports Simple Authentication method.

Unbind

Unbind signals to close the session's connection.
Search uses the query Service Extension to consolidate and filter data sources, returning results back to the client.

Service Extensions for Attribute Providers

Use the authenticateSE Service Extension to determine if the provided credentials are valid and authorize a new session.
Use the query Service Extension to query the attribute provider. A series of responses may be sent back to the client finishing up with a SearchDoneResponse.

Configuration

Required

The attrproviders configuration must define authenticateSE and query Service Extensions.
uri is required and must start with either ldap:// or ldaps://. If using ldaps then the configuration must define and use tls.

Defaults

Default ports will be used if unspecified in uri: ldap:// defaulting to 389 or ldaps:// defaulting to 636.

Optional

anonymousBind is a boolean field which should be set to true if LDAP search is performed without binding.

Defining an LDAP Attribute Provider in config

tls:
ldapTLS:
certFile: /etc/maverics/certs/ldap.crt
keyFile: /etc/maverics/certs/ldap.key
maverics:
certFile: /etc/maverics/certs/maverics.crt
keyFile: /etc/maverics/certs/maverics.key
http:
address: :443
tls: maverics
features:
attrproviders: true
connectors:
- name: azure
type: azure
graphURL: https://graph.microsoft.com
authType: oidc
oidcWellKnownURL: https://login.microsoftonline.com/<tenantID>/v2.0/.well-known/openid-configuration
oauthClientID: client-id
oauthClientSecret: <client-secret>
oauthRedirectURL: https://example.com/oidc
attrproviders:
- name: LDAPAttrProvider
type: ldap
uri: ldaps://ldap.example.com:636
tls: ldapTLS
anonymousBind: false
authenticate:
funcName: Authenticate
file: /etc/maverics/extensions/authenticate.go
query:
funcName: Query
file: /etc/maverics/extensions/query.go
/etc/maverics/extensions/authenticate.go
package main
import (
"fmt"
"strings"
"maverics/log"
)
func Authenticate(username, password string) (bool, error) {
log.Info("LDAPAttrProvider authenticating")
if strings.HasPrefix(username, "admin") {
log.Info(fmt.Sprintf("'%s' has been authenticated", username))
return true, nil
}
return false, nil
}
/etc/maverics/extensions/query.go
package main
import (
"fmt"
"strings"
"maverics/attr"
)
func Query(lap *attr.LDAPProvider, dn string, filter string, reqAttrs []string) (map[string]map[string]interface{}, error) {
// Parse out the username in filter, e.g. "([email protected])".
filter = strings.Trim(filter, "()")
filterV := strings.Split(filter, "=")
filters := make(map[string]string)
filters["username"] = filterV[1]
// Request attributes from the Azure IDP using a provided username filter.
azureAttrs, err := lap.IDPs["azure"].Query(filters, reqAttrs)
if err != nil {
return nil, fmt.Errorf("unable to query attributes from azure: %w", err)
}
// Convert from map[string]string to map[string]interface{}.
vv := make(map[string]interface{})
for k, v := range azureAttrs {
vv[k] = v
}
result := make(map[string]map[string]interface{})
result["[email protected]"] = vv
return result, nil
}

Additional LDAP Resources

  1. 1.
    https://datatracker.ietf.org/doc/html/rfc4513
  2. 2.
    https://datatracker.ietf.org/doc/html/rfc4511