Bootstrap
Initial setup shown the first time Stalwart starts. Configures the server's identity, storage, user accounts, logging, and DNS management.
Fields
serverHostname
Type:
HostName· requiredThe public hostname this server answers to, for example mail.example.com. Used in SMTP greetings, outgoing message headers, and TLS certificate requests.
defaultDomain
Type:
String· requiredThe primary email domain this installation will serve, for example example.com. Additional domains can be added at any time after setup.
requestTlsCertificate
Type:
Boolean· default:trueAutomatically obtain a free TLS certificate for the server hostname from Let's Encrypt using the ACME protocol, so clients can connect securely out of the box. Turn this off if you plan to install a certificate manually.
generateDkimKeys
Type:
Boolean· default:trueGenerate DKIM signing keys for the default domain. DKIM cryptographically signs outgoing mail and significantly improves the chances that messages reach the recipient's inbox instead of spam. Turn this off only if you plan to manage DKIM keys yourself.
dataStore
Type:
DataStore· default:{"@type":"RocksDb","path":"/var/lib/stalwart/"}Where structured data is kept: email metadata, calendars, contacts, mailbox state, and server settings. RocksDB is recommended for single-node installations; PostgreSQL, MySQL, SQLite, and FoundationDB are also supported.
blobStore
Type:
BlobStore· default:{"@type":"Default"}Where the raw content of email messages, attachments, and other large files is stored. Leave as default to reuse the data store, or point to an object storage service such as S3 for larger deployments.
searchStore
Type:
SearchStore· default:{"@type":"Default"}Where the full-text search index is kept, so users can search across message bodies and attachments. Leave as default to reuse the data store, or point to a dedicated search backend for larger deployments.
inMemoryStore
Type:
InMemoryStore· default:{"@type":"Default"}Where short-lived data lives: session caches, rate-limit counters, and temporary tokens. Leave as default to reuse the data store, or point to Redis for faster lookups and multi-node deployments.
directory
Type:
DirectoryBootstrap· default:{"@type":"Internal"}Where user accounts and credentials come from. The internal directory is recommended for ease of setup and management through the WebUI, but external OIDC or LDAP directories can be used for single sign-on and user provisioning in larger organizations.
tracer
Type:
Tracer· default:{"@type":"Log","path":"/var/log/stalwart/"}Where the server writes log messages, traces, and diagnostic events. Defaults to log files on disk; remote destinations such as OpenTelemetry or webhooks can be added after setup.
dnsServer
Type:
DnsServerBootstrap· default:{"@type":"Manual"}Optionally automate the DNS records your mail server needs (SPF, DKIM, DMARC, and more) by connecting to your DNS provider's API. Leave as manual unless your DNS is hosted by a supported provider; this can always be enabled later.
JMAP API
The Bootstrap singleton is available via the urn:stalwart:jmap capability.
x:Bootstrap/get
This is a standard Foo/get method as defined in RFC 8620, Section 5.1.
For singletons, the ids argument should be the literal singleton (or null to return the single instance).
This method requires the sysBootstrapGet permission.
curl -X POST https://mail.example.com/api \
-H 'Authorization: Bearer $TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"methodCalls": [
[
"x:Bootstrap/get",
{
"ids": [
"singleton"
]
},
"c1"
]
],
"using": [
"urn:ietf:params:jmap:core",
"urn:stalwart:jmap"
]
}'
x:Bootstrap/set
This is a standard Foo/set method as defined in RFC 8620, Section 5.3.
For singletons, only the update argument with id singleton is accepted; create and destroy arguments are rejected.
This method requires the sysBootstrapUpdate permission.
curl -X POST https://mail.example.com/api \
-H 'Authorization: Bearer $TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"methodCalls": [
[
"x:Bootstrap/set",
{
"update": {
"singleton": {
"defaultDomain": "updated value"
}
}
},
"c1"
]
],
"using": [
"urn:ietf:params:jmap:core",
"urn:stalwart:jmap"
]
}'
CLI
stalwart-cli wraps the same JMAP calls. See the CLI reference for installation, authentication, and general usage.
Fetch
stalwart-cli get bootstrap
Update
stalwart-cli update bootstrap --field description='Updated'
Nested types
DirectoryBootstrap
External directory service configuration for user authentication and lookup.
Internal: Use the internal directory. No additional fields.Ldap: LDAP Directory. Carries the fields ofLdapDirectory.Sql: SQL Database. Carries the fields ofSqlDirectory.Oidc: OpenID Connect. Carries the fields ofOidcDirectory.
LdapDirectory
LDAP directory connection and mapping settings.
description
Type:
String· requiredShort description of this directory
url
Type:
Uri· default:"ldap://localhost:389"URL of the LDAP server
timeout
Type:
Duration· default:"30s"Connection timeout to the server
allowInvalidCerts
Type:
Boolean· default:falseAllow invalid TLS certificates when connecting to the server
useTls
Type:
Boolean· default:falseUse TLS to connect to the remote server
baseDn
Type:
String· requiredThe base distinguished name (DN) from where searches should begin
bindDn
Type:
String?The distinguished name of the account that the server will bind as to connect to the LDAP directory
bindSecret
Type:
SecretKeyOptional· requiredThe password or secret for the bind DN account
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
Type:
String· default:"(&(objectClass=inetOrgPerson)(mail=?))"Searches for user accounts by e-mail address during authentication
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
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
Type:
String[]· default:["objectClass"]LDAP attribute for the user's account type, if missing defaults to individual.
attrDescription
Type:
String[]· default:["description"]LDAP attributes used to store the user's description
attrEmail
Type:
String[]· default:["mail"]LDAP attribute for the user's primary email address
attrEmailAlias
Type:
String[]· default:["mailAlias"]LDAP attribute for the user's email alias(es)
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
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
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
Type:
String· default:"groupOfNames"LDAP object class used to identify group entries
poolMaxConnections
Type:
UnsignedInt· default:10· max: 8192Maximum number of connections that can be maintained simultaneously in the connection pool
poolTimeoutCreate
Type:
Duration· default:"30s"Maximum amount of time that the connection pool will wait for a new connection to be created
poolTimeoutRecycle
Type:
Duration· default:"30s"Maximum amount of time that the connection pool manager will wait for a connection to be recycled
poolTimeoutWait
Type:
Duration· default:"30s"Maximum amount of time that the connection pool will wait for a connection to become available
memberTenantId
Type:
Id<Tenant>?· enterpriseIdentifier for the tenant this directory belongs to
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
A secret value provided directly.
secret
Type:
String· required · secretPassword or secret value
SecretKeyEnvironmentVariable
A secret value read from an environment variable.
variableName
Type:
String· requiredEnvironment variable name to read the secret from
SecretKeyFile
A secret value read from a file.
filePath
Type:
String· requiredFile path to read the secret from
SqlDirectory
SQL database directory settings.
description
Type:
String· requiredShort description of this directory
store
Type:
SqlAuthStore· requiredStorage backend where accounts and groups are stored
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
Type:
String· default:"secret"Column name for the account password.
columnClass
Type:
String?· default:"type"Column name for account type
columnDescription
Type:
String?· default:"description"Column name for account full name or description
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
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
Type:
String?· default:"SELECT member_of FROM group_members WHERE name = $1"Query to obtain the groups an account is member of.
queryEmailAliases
Type:
String?· default:"SELECT address FROM emails WHERE name = $1"Query to obtain the e-mail aliases of an account.
memberTenantId
Type:
Id<Tenant>?· enterpriseIdentifier for the tenant this directory belongs to
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
PostgreSQL data store.
timeout
Type:
Duration?· default:"15s"Connection timeout to the database
useTls
Type:
Boolean· default:falseUse TLS to connect to the store
allowInvalidCerts
Type:
Boolean· default:falseAllow invalid TLS certificates when connecting to the store
poolMaxConnections
Type:
UnsignedInt?· default:10· max: 8192 · min: 1Maximum number of connections to the store
poolRecyclingMethod
Type:
PostgreSqlRecyclingMethod· default:"fast"Method to use when recycling connections in the pool
readReplicas
Type:
PostgreSqlSettings[]· enterpriseList of read replicas for the store
host
Type:
HostName· requiredHostname of the database server
port
Type:
UnsignedInt· default:5432· max: 65535 · min: 1Port of the database server
database
Type:
String· default:"stalwart"Name of the database
authUsername
Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Type:
SecretKeyOptional· requiredPassword to connect to the store
options
Type:
String?Additional connection options
PostgreSqlSettings
PostgreSQL connection settings.
host
Type:
HostName· requiredHostname of the database server
port
Type:
UnsignedInt· default:5432· max: 65535 · min: 1Port of the database server
database
Type:
String· default:"stalwart"Name of the database
authUsername
Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Type:
SecretKeyOptional· requiredPassword to connect to the store
options
Type:
String?Additional connection options
MySqlStore
MySQL data store.
timeout
Type:
Duration?· default:"15s"Connection timeout to the database
useTls
Type:
Boolean· default:falseUse TLS to connect to the store
allowInvalidCerts
Type:
Boolean· default:falseAllow invalid TLS certificates when connecting to the store
maxAllowedPacket
Type:
UnsignedInt?· max: 1073741824 · min: 1024Maximum size of a packet in bytes
poolMaxConnections
Type:
UnsignedInt?· default:10· max: 8192 · min: 1Maximum number of connections to the store
poolMinConnections
Type:
UnsignedInt?· default:5· max: 8192 · min: 1Minimum number of connections to the store
readReplicas
Type:
MySqlSettings[]· enterpriseList of read replicas for the store
host
Type:
HostName· requiredHostname of the database server
port
Type:
UnsignedInt· default:3306· max: 65535 · min: 1Port of the database server
database
Type:
String· default:"stalwart"Name of the database
authUsername
Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Type:
SecretKeyOptional· requiredPassword to connect to the store
MySqlSettings
MySQL connection settings.
host
Type:
HostName· requiredHostname of the database server
port
Type:
UnsignedInt· default:3306· max: 65535 · min: 1Port of the database server
database
Type:
String· default:"stalwart"Name of the database
authUsername
Type:
String?· default:"stalwart"Username to connect to the store
authSecret
Type:
SecretKeyOptional· requiredPassword to connect to the store
SqliteStore
SQLite embedded data store.
path
Type:
String· requiredPath to the SQLite data directory
poolWorkers
Type:
UnsignedInt?· max: 64 · min: 1Number of worker threads to use for the store, defaults to the number of cores
poolMaxConnections
Type:
UnsignedInt· default:10· max: 8192 · min: 1Maximum number of connections to the store
OidcDirectory
OpenID Connect directory settings.
description
Type:
String· requiredShort description of this directory
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
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
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
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
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
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
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
Type:
Id<Tenant>?· enterpriseIdentifier for the tenant this directory belongs to
DnsServerBootstrap
Automatic DNS server management.
Manual: Manual DNS server management. No additional fields.Tsig: RFC2136 (TSIG). Carries the fields ofDnsServerTsig.Sig0: RFC2136 (SIG0). Carries the fields ofDnsServerSig0.Cloudflare: Cloudflare. Carries the fields ofDnsServerCloudflare.DigitalOcean: DigitalOcean. Carries the fields ofDnsServerCloud.DeSEC: DeSEC. Carries the fields ofDnsServerCloud.Ovh: OVH. Carries the fields ofDnsServerOvh.Bunny: BunnyDNS. Carries the fields ofDnsServerCloud.Porkbun: Porkbun. Carries the fields ofDnsServerPorkbun.Dnsimple: DNSimple. Carries the fields ofDnsServerDnsimple.Spaceship: Spaceship. Carries the fields ofDnsServerSpaceship.Route53: AWS Route53. Carries the fields ofDnsServerRoute53.GoogleCloudDns: Google Cloud DNS. Carries the fields ofDnsServerGoogleCloudDns.
DnsServerTsig
RFC2136 TSIG DNS server.
host
Type:
IpAddr· requiredThe IP address of the DNS server
port
Type:
UnsignedInt· default:53· max: 65535 · min: 1The port used to communicate with the DNS server
keyName
Type:
String· requiredThe key used to authenticate with the DNS server
key
Type:
SecretKey· requiredThe secret or token used to authenticate with the DNS server
protocol
Type:
IpProtocol· default:"udp"The protocol used to communicate with the DNS server
tsigAlgorithm
Type:
TsigAlgorithm· default:"hmac-sha512"The TSIG algorithm used to authenticate with the DNS server