Calendar shared with "Read Free/Busy" permission is not visible to the grantee

Issue Description

When a calendar is shared with a user or group and the permission is restricted to “Read Free/Busy”, the shared calendar does not appear at all in the grantee’s calendar list. Other permission levels (e.g., “Read Items”) work as expected.

The same result is obtained when the share is created from within Bulwark instead of the Stalwart Web-UI.

Expected Behavior

The shared calendar should be discoverable and listed in the grantee’s calendar list. When opened, only free/busy time blocks should be visible to the grantee — event details (summary, location, description, attendees) should be hidden.

Actual Behavior

The shared calendar is not listed at all on the grantee side.

Reproduction Steps

  1. Log in to the Stalwart Web-UI as the owner of a calendar.
  2. Navigate to Calendars → <calendar> → Sharing.
  3. Add a user or group as a sharee.
  4. Set the permission for that sharee to “Read Free/Busy”.
  5. Save the share.
  6. Log in as the grantee in Bulwark, and/or connect via Thunderbird over CalDAV.
  7. Observe the grantee’s calendar list.

Stalwart Version

v0.16.x

Installation Method

Docker

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

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

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

This is actually working as specified.

The JMAP for Calendars draft (section 4.1) explicitly requires that a calendar shared with only mayReadFreeBusy must not be returned in Calendar/get or Calendar/query; the spec wording is “it must behave as though it did not exist”. The same model applies on the CalDAV side: free/busy-only calendars are not surfaced through PROPFIND. So none of the three clients you tried (web UI, Bulwark, Thunderbird) will ever see the shared calendar appear in the calendar list, and that’s by design.

The way the spec intends free/busy data to flow is through a separate availability query, not by mounting the calendar:

  • Over JMAP, the grantee calls Principal/getAvailability on the sharer’s principal id over a time window, and gets back a list of BusyPeriod objects covering only the busy ranges (no event details, no titles). Stalwart implements this and it does honor the Read Free/Busy grant.
  • Over CalDAV, the equivalent is the scheduling outbox flow from RFC 6638: the grantee POSTs an iTIP VFREEBUSY request to their own scheduling outbox URL with the sharer as the ATTENDEE, and the server returns the busy periods. This is what Thunderbird’s “Find a Free Time” / attendee availability dialog uses when scheduling a meeting.

So the practical answer is that “Read Free/Busy” is a scheduling primitive, not a calendar subscription. It lets the grantee see when the sharer is busy in availability dialogs, but it doesn’t add the calendar to their calendar list, and it never can (by spec) without leaking event existence beyond what was granted. If you want the grantee to actually see the calendar in their list with details hidden, you’d grant Read Items or higher and have the client render private events as opaque blocks. There’s no permission level that says “show the calendar in the list but only as busy blocks”, because the moment a calendar appears in the list, the client can enumerate its events.

If the availability lookup itself is not returning the right data in your setup, that would be a real bug and I’d want to dig in further; could you confirm whether Principal/getAvailability (or a VFREEBUSY POST from Thunderbird) returns the expected busy periods for the sharer’s principal? That would narrow down whether anything is actually broken versus just a UX expectation mismatch.

Thank you for the detailed explanation. You’re right, this is a UX expectation mismatch.

As for verifying the availability lookup itself: As far as I understand, Thunderbird only supports VFREEBUSY queries via an add-on that is no longer maintained. So I can’t reliably confirm or refute it from my side.

Thanks again for clarifying the intended behavior and the correct workflow.