Directory
Directory
Section titled “Directory”Defines an external directory for account authentication and lookups.
This object can be configured from the WebUI under Settings › Authentication › Directories
Fields
Section titled “Fields”Directory is a multi-variant object: each instance has an @type discriminator selecting one of the variants below, and each variant carries its own set of fields.
@type: "Ldap"
Section titled “@type: "Ldap"”LDAP Directory
description
Section titled “description”Type:
String· requiredShort description of this directory
Type:
Uri· default:"ldap://localhost:389"URL of the LDAP server
timeout
Section titled “timeout”Type:
Duration· default:"30s"Connection timeout to the server
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseAllow invalid TLS certificates when connecting to the server
useTls
Section titled “useTls”Type:
Boolean· default:falseUse TLS to connect to the remote server
baseDn
Section titled “baseDn”Type:
String· requiredThe base distinguished name (DN) from where searches should begin
bindDn
Section titled “bindDn”Type:
String?The distinguished name of the account that the server will bind as to connect to the LDAP directory
bindSecret
Section titled “bindSecret”Type:
SecretKeyOptional· requiredThe password or secret for the bind DN account
bindAuthentication
Section titled “bindAuthentication”Type:
Boolean· default:trueWhether to use bind authentication. When enabled, the server will use the filterLogin to search for the user account and then attempt to bind as that account using the provided password. When disabled, the server will use the bind DN and secret to connect to the LDAP server and obtain the secret from the account entry using the attrSecret attribute.
filterLogin
Section titled “filterLogin”Type:
String· default:"(&(objectClass=inetOrgPerson)(mail=?))"Searches for user accounts by e-mail address during authentication
filterMailbox
Section titled “filterMailbox”Type:
String· default:"(|(&(objectClass=inetOrgPerson)(|(mail=?)(mailAlias=?)))(&(objectClass=groupOfNames)(|(mail=?)(mailAlias=?))))"Searches for users or groups matching a recipient e-mail address or alias
filterMemberOf
Section titled “filterMemberOf”Type:
String?· default:"(&(objectClass=groupOfNames)(member=?))"Searches for groups that an account is member of. Use when the group membership is not provided in the account entry. The ? in the filter will be replaced with the account DN.
attrClass
Section titled “attrClass”Type:
String[]· default:["objectClass"]LDAP attribute for the user’s account type, if missing defaults to individual.
attrDescription
Section titled “attrDescription”Type:
String[]· default:["description"]LDAP attributes used to store the user’s description
attrEmail
Section titled “attrEmail”Type:
String[]· default:["mail"]LDAP attribute for the user’s primary email address
attrEmailAlias
Section titled “attrEmailAlias”Type:
String[]· default:["mailAlias"]LDAP attribute for the user’s email alias(es)
attrMemberOf
Section titled “attrMemberOf”Type:
String[]· default:["memberOf"]LDAP attributes for the groups that a user belongs to. Used when filterMemberOf is not configured or when the group membership is also provided in the account entry.
attrSecret
Section titled “attrSecret”Type:
String[]· default:["userPassword"]LDAP attribute for the user’s password hash. This setting is required when binding as a service user. When using bind authentication, configure the secret-changed attribute instead.
attrSecretChanged
Section titled “attrSecretChanged”Type:
String[]· default:["pwdChangeTime"]LDAP attribute that provides a password change hash or a timestamp indicating when the password was last changed. When using bind authentication, this attribute is used to determine when to invalidate OAuth tokens.
groupClass
Section titled “groupClass”Type:
String· default:"groupOfNames"LDAP object class used to identify group entries
poolMaxConnections
Section titled “poolMaxConnections”Type:
UnsignedInt· default:10· max: 8192Maximum number of connections that can be maintained simultaneously in the connection pool
poolTimeoutCreate
Section titled “poolTimeoutCreate”Type:
Duration· default:"30s"Maximum amount of time that the connection pool will wait for a new connection to be created
poolTimeoutRecycle
Section titled “poolTimeoutRecycle”Type:
Duration· default:"30s"Maximum amount of time that the connection pool manager will wait for a connection to be recycled
poolTimeoutWait
Section titled “poolTimeoutWait”Type:
Duration· default:"30s"Maximum amount of time that the connection pool will wait for a connection to become available
memberTenantId
Section titled “memberTenantId”Type:
Id<Tenant>?· enterpriseIdentifier for the tenant this directory belongs to
@type: "Sql"
Section titled “@type: "Sql"”SQL Database
description
Section titled “description”Type:
String· requiredShort description of this directory
Type:
SqlAuthStore· requiredStorage backend where accounts and groups are stored
columnEmail
Section titled “columnEmail”Type:
String· default:"name"Column name for e-mail address. Optional, you can use instead a query to obtain the account’s addresses.
columnSecret
Section titled “columnSecret”Type:
String· default:"secret"Column name for the account password.
columnClass
Section titled “columnClass”Type:
String?· default:"type"Column name for account type
columnDescription
Section titled “columnDescription”Type:
String?· default:"description"Column name for account full name or description
queryLogin
Section titled “queryLogin”Type:
String· default:"SELECT name, secret, description, type FROM accounts WHERE name = $1"Query to obtain the account details by login e-mail address.
queryRecipient
Section titled “queryRecipient”Type:
String· default:"SELECT name, secret, description, type FROM accounts WHERE name = $1 AND active = true"Query to obtain the account details by recipient e-mail address or alias.
queryMemberOf
Section titled “queryMemberOf”Type:
String?· default:"SELECT member_of FROM group_members WHERE name = $1"Query to obtain the groups an account is member of.
queryEmailAliases
Section titled “queryEmailAliases”Type:
String?· default:"SELECT address FROM emails WHERE name = $1"Query to obtain the e-mail aliases of an account.
memberTenantId
Section titled “memberTenantId”Type:
Id<Tenant>?· enterpriseIdentifier for the tenant this directory belongs to
@type: "Oidc"
Section titled “@type: "Oidc"”OpenID Connect
description
Section titled “description”Type:
String· requiredShort description of this directory
issuerUrl
Section titled “issuerUrl”Type:
Uri· requiredThe base URL of the OpenID Connect provider (e.g. https://sso.example.com/realms/myrealm). Stalwart will use this URL to automatically discover the provider’s endpoints, including the token validation and user info endpoints.
requireAudience
Section titled “requireAudience”Type:
String?· default:"stalwart"If set, Stalwart will reject any token whose aud (audience) claim does not include this value. Set this to the client ID or resource identifier registered for Stalwart in your identity provider to ensure tokens issued for other applications are not accepted.
requireScopes
Section titled “requireScopes”Type:
String[]· default:["openid","email"]If set, Stalwart will reject any token that does not include all of the specified scopes. Useful for ensuring that only tokens explicitly granted access to the mail server are accepted.
claimUsername
Section titled “claimUsername”Type:
String· default:"preferred_username"The claim name used to retrieve the user’s login name from the token or user info response. Common values are preferred_username, email, or sub depending on your provider’s configuration. If the claim value is not an email address and usernameDomain is set, the domain will be appended automatically (e.g. john becomes [email protected]). If the claim value already contains an @, it is used as-is. If the claim value is not an email address and no usernameDomain is configured, Stalwart will fall back to the email claim. If neither yields a valid email address, authentication will be rejected.
usernameDomain
Section titled “usernameDomain”Type:
String?The domain name to append to the username when the value of claimUsername does not contain an @ symbol (e.g. setting this to example.com will turn john into [email protected]). If not set, Stalwart will fall back to the email claim when the username claim does not contain a valid email address.
claimName
Section titled “claimName”Type:
String?· default:"name"The claim name used to retrieve the user’s display name from the token or user info response. Common values are name or display_name. If not set, the display name will not be populated.
claimGroups
Section titled “claimGroups”Type:
String?The claim name used to retrieve the user’s group memberships from the token or user info response. Common values are groups or roles depending on your provider’s configuration. If not set, group information will not be populated. Note that some providers omit group claims from the token to keep its size small and only return them via the user info endpoint, if group information is missing, ensure your provider is configured to include it.
memberTenantId
Section titled “memberTenantId”Type:
Id<Tenant>?· enterpriseIdentifier for the tenant this directory belongs to
JMAP API
Section titled “JMAP API”The Directory object is available via the urn:stalwart:jmap capability.
x:Directory/get
Section titled “x:Directory/get”This is a standard Foo/get method as defined in RFC 8620, Section 5.1.
This method requires the sysDirectoryGet permission.
curl -X POST https://mail.example.com/api \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:Directory/get", { "ids": [ "id1" ] }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'x:Directory/set
Section titled “x:Directory/set”This is a standard Foo/set method as defined in RFC 8620, Section 5.3.
Supports create, update, and destroy operations in a single call.
Create
Section titled “Create”This operation requires the sysDirectoryCreate permission.
curl -X POST https://mail.example.com/api \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:Directory/set", { "create": { "new1": { "@type": "Ldap", "baseDn": "Example", "bindSecret": { "@type": "None" }, "description": "Example" } } }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'Update
Section titled “Update”This operation requires the sysDirectoryUpdate permission.
curl -X POST https://mail.example.com/api \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:Directory/set", { "update": { "id1": { "description": "updated value" } } }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'Destroy
Section titled “Destroy”This operation requires the sysDirectoryDestroy permission.
curl -X POST https://mail.example.com/api \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:Directory/set", { "destroy": [ "id1" ] }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'x:Directory/query
Section titled “x:Directory/query”This is a standard Foo/query method as defined in RFC 8620, Section 5.5.
This method requires the sysDirectoryQuery permission.
curl -X POST https://mail.example.com/api \ -H 'Authorization: Bearer $TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "methodCalls": [ [ "x:Directory/query", { "filter": { "memberTenantId": "id1" } }, "c1" ] ], "using": [ "urn:ietf:params:jmap:core", "urn:stalwart:jmap" ] }'The x:Directory/query filter argument accepts the following conditions (combinable with AnyOf / AllOf / Not per RFC 8620):
| Condition | Kind |
|---|---|
memberTenantId | id of Tenant |
stalwart-cli wraps the same JMAP calls. See the CLI reference for installation, authentication, and general usage.
stalwart-cli get Directory id1Create
Section titled “Create”stalwart-cli create Directory/Ldap \ --field description=Example \ --field baseDn=Example \ --field 'bindSecret={"@type":"None"}'stalwart-cli query Directorystalwart-cli query Directory --where memberTenantId=id1Update
Section titled “Update”stalwart-cli update Directory id1 --field description='updated value'Delete
Section titled “Delete”stalwart-cli delete Directory --ids id1Nested types
Section titled “Nested types”SecretKeyOptional
Section titled “SecretKeyOptional”An optional secret value, or none.
None: No secret. No additional fields.Value: Secret value. Carries the fields ofSecretKeyValue.EnvironmentVariable: Secret read from environment variable. Carries the fields ofSecretKeyEnvironmentVariable.File: Secret read from file. Carries the fields ofSecretKeyFile.
SecretKeyValue
Section titled “SecretKeyValue”A secret value provided directly.
secret
Section titled “secret”Type:
String· required · secretPassword or secret value
SecretKeyEnvironmentVariable
Section titled “SecretKeyEnvironmentVariable”A secret value read from an environment variable.
variableName
Section titled “variableName”Type:
String· requiredEnvironment variable name to read the secret from
SecretKeyFile
Section titled “SecretKeyFile”A secret value read from a file.
filePath
Section titled “filePath”Type:
String· requiredFile path to read the secret from
SqlAuthStore
Section titled “SqlAuthStore”Defines the SQL database used to store account and group information for SQL directories.
Default: Use data store (SQL only). No additional fields.PostgreSql: PostgreSQL. Carries the fields ofPostgreSqlStore.MySql: mySQL. Carries the fields ofMySqlStore.Sqlite: SQLite. Carries the fields ofSqliteStore.
PostgreSqlStore
Section titled “PostgreSqlStore”PostgreSQL data store.
timeout
Section titled “timeout”Type:
Duration?· default:"15s"Connection timeout to the database
useTls
Section titled “useTls”Type:
Boolean· default:falseUse TLS to connect to the store
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseAllow invalid TLS certificates when connecting to the store
poolMaxConnections
Section titled “poolMaxConnections”Type:
UnsignedInt?· default:10· max: 8192 · min: 1Maximum number of connections to the store
poolRecyclingMethod
Section titled “poolRecyclingMethod”Type:
PostgreSqlRecyclingMethod· default:"fast"Method to use when recycling connections in the pool
readReplicas
Section titled “readReplicas”Type:
PostgreSqlSettings[]· enterpriseList of read replicas for the store
Type:
String· requiredHostname of the database server
Type:
UnsignedInt· default:5432· max: 65535 · min: 1Port of the database server
database
Section titled “database”Type:
String· default:"stalwart"Name of the database
authUsername
Section titled “authUsername”Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Section titled “authSecret”Type:
SecretKeyOptional· requiredPassword to connect to the store
options
Section titled “options”Type:
String?Additional connection options
PostgreSqlSettings
Section titled “PostgreSqlSettings”PostgreSQL connection settings.
Type:
String· requiredHostname of the database server
Type:
UnsignedInt· default:5432· max: 65535 · min: 1Port of the database server
database
Section titled “database”Type:
String· default:"stalwart"Name of the database
authUsername
Section titled “authUsername”Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Section titled “authSecret”Type:
SecretKeyOptional· requiredPassword to connect to the store
options
Section titled “options”Type:
String?Additional connection options
MySqlStore
Section titled “MySqlStore”MySQL data store.
timeout
Section titled “timeout”Type:
Duration?· default:"15s"Connection timeout to the database
useTls
Section titled “useTls”Type:
Boolean· default:falseUse TLS to connect to the store
allowInvalidCerts
Section titled “allowInvalidCerts”Type:
Boolean· default:falseAllow invalid TLS certificates when connecting to the store
maxAllowedPacket
Section titled “maxAllowedPacket”Type:
UnsignedInt?· max: 1073741824 · min: 1024Maximum size of a packet in bytes
poolMaxConnections
Section titled “poolMaxConnections”Type:
UnsignedInt?· default:10· max: 8192 · min: 1Maximum number of connections to the store
poolMinConnections
Section titled “poolMinConnections”Type:
UnsignedInt?· default:5· max: 8192 · min: 1Minimum number of connections to the store
readReplicas
Section titled “readReplicas”Type:
MySqlSettings[]· enterpriseList of read replicas for the store
Type:
String· requiredHostname of the database server
Type:
UnsignedInt· default:3306· max: 65535 · min: 1Port of the database server
database
Section titled “database”Type:
String· default:"stalwart"Name of the database
authUsername
Section titled “authUsername”Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Section titled “authSecret”Type:
SecretKeyOptional· requiredPassword to connect to the store
MySqlSettings
Section titled “MySqlSettings”MySQL connection settings.
Type:
String· requiredHostname of the database server
Type:
UnsignedInt· default:3306· max: 65535 · min: 1Port of the database server
database
Section titled “database”Type:
String· default:"stalwart"Name of the database
authUsername
Section titled “authUsername”Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Section titled “authSecret”Type:
SecretKeyOptional· requiredPassword to connect to the store
SqliteStore
Section titled “SqliteStore”SQLite embedded data store.
Type:
String· requiredPath to the SQLite data directory
poolWorkers
Section titled “poolWorkers”Type:
UnsignedInt?· max: 64 · min: 1Number of worker threads to use for the store, defaults to the number of cores
poolMaxConnections
Section titled “poolMaxConnections”Type:
UnsignedInt· default:10· max: 8192 · min: 1Maximum number of connections to the store
PostgreSqlRecyclingMethod
Section titled “PostgreSqlRecyclingMethod”| Value | Label |
|---|---|
fast | Fast recycling method |
verified | Verified recycling method |
clean | Clean recycling method |