Issue Description
I am trying to configure an LDAP directory with bindAuthentication: true through the JMAP Directory/set API.
The LDAP provider exposes the password-change timestamp as pwdChangedTime. Stalwart documents attrSecretChanged as the LDAP directory field used to configure which LDAP attribute should be used as the password-change marker for token invalidation.
However, when creating the LDAP directory through JMAP Directory/set, Stalwart rejects attrSecretChanged with invalidPatch.
This appears to be a mismatch between the documented LDAP Directory configuration and the JMAP Directory/set validation/schema
Expected Behavior
The following LDAP Directory payload should be accepted:
{
“@type”: “Ldap”,
“url”: “ldap://ldap.example.internal:389”,
“baseDn”: “dc=example,dc=internal”,
“bindDn”: “cn=ldap-service,ou=users,dc=example,dc=internal”,
“bindAuthentication”: true,
“attrSecretChanged”: [“pwdChangedTime”],
“filterLogin”: “(&(objectClass=person)(mail=?))”,
“filterMailbox”: “(&(objectClass=person)(mail=?))”
}
Expected behavior: Stalwart should persist the LDAP directory and use pwdChangedTime as the password-change marker for LDAP bind authentication.
Relevant documentation: the LDAP Directory object documents attrSecretChanged as the configurable password-change marker attribute, with default [“pwdChangeTime”].
Actual Behavior
Actual Behavior
JMAP Directory/set rejects the payload with:
{
“methodResponses”: [
[
“x:Directory/set”,
{
“accountId”: “d333333”,
“notCreated”: {
“new1”: {
“type”: “invalidPatch”,
“description”: “Invalid value for object property”,
“properties”: [“attrSecretChanged”]
}
}
},
“c1”
]
]
}
The deviation is that attrSecretChanged is documented as a valid LDAP Directory field, but the JMAP API rejects it during directory creation.
Reproduction Steps
- Run Stalwart v0.16.7.
- Use an LDAP provider that exposes a password-change timestamp attribute named pwdChangedTime.
- Create an LDAP directory through JMAP Directory/set.
Include the field:
“attrSecretChanged”: [“pwdChangedTime”]
Submit the request. - Observe that the directory is not created and JMAP returns invalidPatch for attrSecretChanged.
Relevant Log Output
Waiting for Stalwart JMAP at https://stalwart.example.internal:443/jmap … API ready (HTTP 200) [auth-ldap] reconciling LDAP directory for ldap://ldap.example.internal:389 baseDn=dc=example,dc=internal … [auth-ldap] creating LDAP directory … {“methodResponses”:[[“x:Directory/set”,{“accountId”:“d333333”,“notCreated”:{“new1”:{“type”:“invalidPatch”,“description”:“Invalid value for object property”,“properties”:[“attrSecretChanged”]}}},“c1”]],“sessionState”:“ca2c46e8”} [auth-ldap] LDAP directory creation failed
Stalwart Version
v0.16.x
Installation Method
Docker
Database Backend
PostgreSQL
Blob Storage
S3-compatible
Search Engine
Internal
Directory Backend
LDAP
Additional Context
The LDAP backend is an Authentik LDAP outpost. With LDAP bind authentication, Stalwart cannot read the user password hash. Therefore it needs a password-change marker attribute to invalidate OAuth/WebUI tokens after password changes.
Stalwart’s documented default is pwdChangeTime, but Authentik LDAP outpost emits the password-change timestamp as pwdChangedTime. This should be configurable through attrSecretChanged.
Currently, since JMAP rejects attrSecretChanged, the only workaround is to make the LDAP provider emit a compatibility alias named pwdChangeTime. It would be cleaner if Stalwart accepted the documented attrSecretChanged field through JMAP Directory/set.
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on