JMAP Sharing is incomplete and fails real world use cases

What companies and other large orgs (>1000 users) need are “delegated accounts”, which is either a functional account like info@ or another user like jane@ . john@ wants to give jane@ complete access to all his mail, calendar and address books, and even send-as. John can choose whether the access is read-only or wants Jane to be able to change his calendar, delete spam and mark mails as read. In some cases, e.g. if Jane is John’s assistant, he wants Jane to be able to send mail as John. When John grants Jane access to his mail, he means all his mail - all folders, including folders that will be created later, by either John or Jane. This is called “delegated accounts”.

It’s different from “John gives Jane access to this specific mail folder only”, which is what RFC 9670 seems to be doing. (The spec is very vague and unclear, and in some cases even contracticts itself, so it’s hard to tell definitely.) In any case, only the latter seems to be implemented in Stalwart. John can give Jane access to his mail folders, but has to do it for every folder individually, and most importantly, it won’t apply to folders that John or Jane create later.

There is also no way in JMAP protocol for John himself (not a server or domain admin) to allow Jane to send mail on his behalf as John. There simply isn’t any defined JMAP function for it.

RFC 9670 vaguely says that “Managing … Principals … is out of scope” and leaves it up to the domain admin to set up “groups” for departments and add users to these groups, and then set up such a group as the owner of an account. That might work for functional accounts like info@ or de.sales@ , which are explicitly created by admins. However, if fails in 2 cases:

  • When a John wants to give Jane access
  • On small domains where users want to self-manage the accounts and not involve an server admin

This is a real gap. EWS can do delegation, and it’s done by the users in the email app. John can go to a specific email app dialog, enter Jane, give her access to his mail, calendar and addressbook, and decide the access level (read, write, crate etc.) and then Jane can go to a similar dialog in her email app, add John, and she can use John’s accounts as if they were her own. She can even send mail on his behalf. There is no administrator involved at all. (Or at least not required. Of course, admins can preconfigure these delegations as well.) I can state this with confidence, because Parula implements this for EWS and other protocols. In JMAP with Stalwart, that seems impossible.

Here’s what Claude Opus 5 said:

Prompt:

"I asked whether John himself can grant Jane the right to send as John. [… We had checked JMAP specs] Check the stalwart source code whether there’s indeed no way.

Also, the fact that newly created subfolders don’t inherit the access rights of the parent folder (I confirmed that in my own testing with my own Stalwart server) looks like a bug in Stalwart to me. It makes no sense. As John, I need a way to give Jane access to all my mail folders, current and future."

Answer:

a flat no, and now with source evidence.

Why John cannot grant it

build_account_info() (crates/common/src/cache/principals.rs:700) builds the set of
addresses an account may send from out of exactly two sources:

  1. the account’s own addresses — primary + aliases
  2. the addresses of every group in account.id_member_of

That’s the whole function. ACLs and shareWith contribute nothing. Identity/set then
checks the requested address against that list (crates/jmap/src/identity/set.rs:73 →
“E-mail address not configured for this account.”).

So the only two grants that exist are: put [email protected] on Jane’s account as an
alias, or put Jane in a group. Both are registry writes on Jane’s object, not John’s —
and a plain user is refused outright. Verified live, all three refused with “You are not
authorized to create, update or destroy objects of this type”:

  • Jane adding herself to the group
  • John adding Jane to the group
  • John adding an alias to his own account

Only an admin can do it, and even then not “as John personally” — memberGroupIds → a User
gives invalidForeignKey, so John’s mailbox would have to become a Group account.

The membership/ACL split is a hard dispatch table

crates/jmap/src/api/request.rs — this is why Identity/get will never work over an ACL
share:

  • assert_is_member (ACL can never reach): Identity, EmailSubmission, VacationResponse,
    Sieve, Quota, ShareNotification, ParticipantIdentity, CalendarEventNotification, Blob
    upload/lookup/copy, Registry
  • assert_has_access (ACL suffices): Mailbox, Email, Thread, SearchSnippet, ImportEmail,
    Calendar, CalendarEvent, AddressBook, ContactCard, FileNode

has_access = is_member OR an access_to entry, and access_to is merely the union of
per-document ACL grants (AclQuery::HasAccess, access_token.rs:78). There is no
account-level ACL object to grant once.

You’re right about subfolder inheritance — and it’s missing in two places

Not just a create-time oversight:

  • Mailbox/set create sets changes.acls only from an explicit shareWith in the request;
    nothing copies the parent (crates/jmap/src/mailbox/set.rs).
  • effective_acl() (crates/common/src/sharing/mod.rs:26) is flat — it unions the grants on
    that one object and never walks up the parent chain, so it can’t compensate at check
    time either.

grep -i inherit across mailbox/ and sharing/ finds nothing. So “all my folders, current
and future” is genuinely not expressible on Stalwart today. Worth filing.

[Workaround]
What you can do for “all folders, current and future”

The useful finding: Mailbox/set create accepts shareWith in the same call. I verified it
live — John created a folder with Jane’s rights inline, and Jane had mayReadItems on it
immediately, one call, no extra round trip.

So our client can carry the parent’s shareWith forward whenever it creates a folder. That
closes the gap for folders we create. Folders created via webmail or IMAP would still
miss out until Stalwart inherits properly. A complement is to re-apply the
account-wide ACL during listFolders() when we spot a folder whose shareWith differs from
its parent’s.

[However, these are clearly hacks, because this is the server’s job, not the client’s.]

One aside that may help elsewhere: effective_acl matches grants via
is_member(grant.account_id), so an ACL granted to a group principal covers every member.
That solves “many people at once”, not “future folders”.

Want me to implement the inherit-on-create (and optionally the reconcile-in-listFolders)
on a branch?

result:
Confirmed in Stalwart source: John cannot grant send-as by any means (send-as addresses
come only from own aliases + group membership, both admin-only registry writes), and
mailbox ACLs never inherit — no copy at create, no parent walk in effective_acl — but
Mailbox/set create accepts shareWith inline, which our client can use to propagate rights
to new folders.