Hide specific accounts from the directory (like "Hide from address lists"), driven by LDAP/AD

The directory exposed to users (JMAP Principal/query, and the CardDAV/WebDAV directory) lists every account in the tenant. There is no way to keep a specific account out of it. As a result, deactivated mailboxes, legacy addresses (such as sector_old@), service accounts and system mailboxes all appear in webmail recipient autocomplete. I’d like a per-account visibility control, ideally driven by LDAP/AD, as Exchange administrators already do with “Hide from address lists”.

A companion idea covers mapping AD groups to Stalwart roles: [link to the first topic].

Current behaviour (checked against main @ af37a23)

  • crates/jmap/src/principal/query.rs returns every account in the caller’s tenant. It is gated only by Sharing.allowDirectoryQueries or the jmapPrincipalQuery permission (with jmapPrincipalGet and davPrincipalList / davPrincipalSearch for the other paths). Both control who may query the directory, not who is listed in it.
  • The Account object (User and Group) has no visibility or “hidden” field.
  • Clients that build autocomplete from the directory (Bulwark, for example) therefore show every account. The only option today is to disable directory queries entirely, which also removes every legitimate entry.

Proposal

  • Native field on Account (User and Group): hideFromDirectory: boolean (default false), for the internal directory and for manual overrides.
  • Directory-driven on the LDAP Directory, using either:
    • attrHideFromDirectory: an attribute read from the entry. On AD, the existing msExchHideFromAddressLists (TRUE/FALSE) is the natural choice, since many AD environments already maintain it.
    • hideFromDirectoryGroup: a group DN whose direct members are hidden.

Suggested semantics:

  • Hidden principals are excluded from Principal/query results and from directory listings over WebDAV/CardDAV, for callers without an administrative permission such as sysAccountQuery. Administrators still see everything.
  • Hiding affects discovery only. It does not change delivery, authentication, sharing already granted, or Principal/get by explicit id. A hidden group still works as a shared mailbox for its members.
  • As with role mapping, a value that comes from the directory should be read-only in the UI and refreshed together with the account’s other directory data.

Use cases

  • Deactivated or legacy mailboxes that must no longer be suggested to users. In our case they are already blocked from receiving mail through filterMailbox, but they still show up in autocomplete.
  • Service accounts, shared system mailboxes and technical addresses.
  • Parity with the Exchange “Hide from address lists” behaviour when migrating from Exchange with an existing AD.

Related

  • Predefined (read-only) address books: staff favoured “a query-only directory, similar to Exchange GAL”. Per-account visibility is the natural companion to a GAL-style directory, since Exchange’s GAL relies on exactly this flag.
  • bulwarkmail/webmail#1010: a client-side request to scope directory autocomplete by domain. It reflects the same need for directory filtering.