Cross-Context Collaboration deprecated
Introduction
In a multi-tenant deployment, users are partitioned into contexts. Historically a permission could only ever refer to an entity (user or group) of the same context, so collaboration stopped at the context boundary. Cross-context collaboration lifts that restriction in a controlled way: a user in one context can be granted a native permission on a resource owned by a user in another context of the same deployment, and works with it as a first-class internal entity rather than as a guest.
This is what distinguishes cross-context collaboration from Federated Sharing. Federated Sharing builds on the guest-mode share link: the recipient subscribes to a remote share, and the data is accessed live through a proxy or a remote-account integration - there is still a (guest) account standing in for the foreign user. Cross-context collaboration creates no shadow or guest account: the foreign user appears directly in the resource's permission list as a context-qualified entity, and the grant is enforced natively by the owning context. The two features can coexist, but they solve different problems and are configured independently.
Because a grant now reaches across a trust boundary, the feature is disabled by default and gated by an explicit, deny-by-default deployment policy (trust zones, see below). An operator must deliberately opt the relevant users and contexts in before any cross-context grant can be created.
Supported scope
Cross-context collaboration is available for a defined set of surfaces (a whitelist - everything else continues to be context-local):
| Surface | What can be shared cross-context |
|---|---|
| Calendar | Calendar folders shared to a user in another context are surfaced as foreign calendar accounts. Private/personal folders can be shared read-write; public folders are read-only for the foreign user (an appointment in a public folder requires an organizer internal to the owning context). See com.openexchange.calendar.crosscontext.enabled. |
| Mail folders shared via IMAP ACLs to a user whose mailbox lives on the same mail server but in another context. See Cross-Context Permissions. | |
| Deputy | A deputy (representative) can be appointed across context boundaries, subject to the same trust-zone policy — including through the SOAP provisioning API (example). See Deputy permissions. |
Contacts/address-book folders and Drive/Infostore folders are not cross-context share targets and are not on the roadmap. (Foreign users may still surface in the address book - e.g. through an LDAP-backed contacts provider - so they can be picked as a sharee. Their own contact/file folders, however, are not surfaced to a foreign grantee as cross-context share targets - no provider brings a cross-context contact or Drive/Infostore folder to the grantee, even though the generic folder-permission layer does not specifically reject such a grant.)
Preconditions
Cross-context collaboration operates within a single deployment. Contexts may be distributed across different database schemas/shards, but there is one installation. In addition:
- Identifier resolution. To turn an email address (entered by a client) into a context-qualified internal entity, the deployment needs an installation-wide resolver - typically the LDAP-backed Mail Resolver. Without it, a client can only address a foreign user by a fully-qualified identifier, not by a plain email address.
- For mail folders specifically (in addition to the above):
- the IMAP server must support the IMAP4 ACL Extension (RFC 4314);
- all users of the deployment must share the same mail server;
- a Mail Login Resolver must be configured to map between IMAP ACL identities and OX user/context identifiers;
- doveadm must be reachable for managing (and retracting) mailbox ACLs - see Operations below.
Enabling and configuration
Two things must be true for a cross-context grant to be created: the relevant surface must be enabled, and the trust-zone policy must admit the liaison. All properties are config-cascade aware and reloadable.
Trust zones - the deployment policy gate
The central gate is com.openexchange.crosscontext.trustZones: a comma-separated list of trust-zone tags.
- A cross-context grant is admitted only if the sharing user's zone set and the target context's zone set share at least one tag (set intersection).
- The default is empty, which denies all cross-context sharing. A deployment must first opt the relevant users and/or contexts into one or more zones.
- Resolution is via the config-cascade, with the source side queried per user and the target side queried per context. Set the value to
globalat server level to allow anyone to share with anyone, or scope it per reseller / per context to carve out brand and organization boundaries.
Example: tag all contexts of one customer with a shared zone (com.openexchange.crosscontext.trustZones = acme) to allow collaboration inside that customer while keeping every other context isolated.
Assigning a zone to a context via provisioning
Because the value is config-cascade aware, a context's zones (the target side of the policy) are assigned through provisioning rather than via .properties files. The property is a comma-separated list, so a context can be placed in several zones at once. With the command-line tools:
$ changecontext -A oxadminmaster -P secret -c 12 --config/com.openexchange.crosscontext.trustZones=acme,eu-corp
The same context-level assignment over the SOAP provisioning API is an OXContextService.change request that carries the value in the config namespace of the context's user attributes:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://soap.admin.openexchange.com" xmlns:xsd="http://dataobjects.soap.admin.openexchange.com/xsd" xmlns:xsd1="http://dataobjects.rmi.admin.openexchange.com/xsd">
<soapenv:Header/>
<soapenv:Body>
<soap:change>
<soap:ctx>
<xsd:id>12</xsd:id>
<xsd:userAttributes>
<xsd:entries>
<xsd:key>config</xsd:key>
<xsd:value>
<xsd:entries>
<xsd:key>com.openexchange.crosscontext.trustZones</xsd:key>
<xsd:value>acme,eu-corp</xsd:value>
</xsd:entries>
</xsd:value>
</xsd:entries>
</xsd:userAttributes>
</soap:ctx>
<soap:auth>
<xsd1:login>oxadminmaster</xsd1:login>
<xsd1:password>secret</xsd1:password>
</soap:auth>
</soap:change>
</soapenv:Body>
</soapenv:Envelope>
The policy's source side is resolved per user, but that lookup falls back through the config-cascade to the context value - so assigning the zone at context level (as above) on both the sharing context and the target context covers both ends of the policy, and a separate per-user assignment is normally not needed. A context's assignment is cleared again with changecontext ... --remove-config/com.openexchange.crosscontext.trustZones.
Per-surface enablement
| Property | Default | Effect |
|---|---|---|
com.openexchange.calendar.crosscontext.enabled | true | Whether foreign shared calendar folders are surfaced to the user (private/personal read-write, public read-only). |
com.openexchange.mail.crossContextPermissions | false | Master switch for sharing mail folders to foreign users. |
com.openexchange.mail.crossContextRequireSameServer | true | Reject a mail grant up front if the foreign grantee's primary mailbox is on a different mail server. Leave on unless the effective mail server cannot be reliably determined. |
(Deputy uses its own feature enablement via the open-xchange-deputy package; see the deputy article.)
Guest promotion
com.openexchange.crosscontext.tryPromoteGuests (default true) controls what happens when a client adds a permission for a recipient identified only by an email address. When the address resolves to a provisioned internal user in another context and the trust-zone policy admits the liaison, the permission is transparently promoted to a regular cross-context permission - no guest user is materialized. With false, such a recipient stays on the ordinary guest-share path. Resolved per sharing user.
Enforcement and revocation
Trust zones are an admission gate: the policy is enforced when a cross-context grant is created. Once admitted, a grant is not re-checked on the read path - it behaves like an ordinary internal share and survives a later trust-zone change until it is explicitly revoked. To withdraw an existing grant, remove the share (or deputy) directly, or use the administrative cross-context purge tool (see Operations).
Mail revocation is the doveadm dimension. When a mail-folder grant is explicitly revoked, App Suite removes its tracking and the underlying IMAP ACL is retracted via best-effort doveadm; without doveadm the raw-IMAP ACL persists until doveadm becomes reachable (the periodic reconciler retries). A short-lived, per-user, in-memory message cache may serve already-fetched messages for up to its (small) TTL after a revocation.
Operations
- Liaison registry. Every cross-context grant is tracked in a per-user-schema
xctx_liaisonstable - a bridge index that lets the deployment find, retract, and clean up cross-context grants without scanning every context. - Audit & on-demand retraction (admin REST). A basic-auth administrative tool under
…/preliminary/crosscontext/v1lets operators review and manually revoke cross-context grants:- Inbound - what a principal has received:
GET /inbound/{context}(all liaison-holding entities in a context) andGET /inbound/{context}/{user}(one principal), broken down per module;DELETE /inbound/{context}/{user}retracts it (off-boarding a grantee), optionally scoped byfrom(a sharing context),owner, ormodule. - Outbound - what a user has shared out from its own resources (the folders it owns, its mailbox, and the deputies it appointed - i.e. "who can access this user's resources"):
GET /outbound/{context}/{user}lists it andDELETE /outbound/{context}/{user}retracts it, optionally scoped byto(a grantee context) ormodule.
- Inbound - what a principal has received:
The DELETE operations are an unconditional operator override - they do not consult the trust-zone policy - and are the primary way to retract an existing cross-context grant, since trust zones gate only at admission time (see Enforcement and revocation). Retracting a mail share requires doveadm; the grantee-side registry rows are cleaned up best-effort, with the periodic reconciler as the backstop. - Reconcilers / cleanup jobs. The registry is kept consistent by source- and target-side reconciler clean-up jobs that catch the cases where the real-time after-commit hook could not run (storage briefly unreachable, schema restored from backup, direct SQL that bypasses the folder service). These are documented under Database Cleanup Jobs. The bulk operations are idempotent, so re-runs against an already-consistent schema are cheap. - doveadm for mail. Retracting a mail-folder ACL (e.g. when a cross-context grant is explicitly revoked) requires doveadm. If doveadm is not reachable, mail ACL retraction cannot complete; the server logs a warning (rate-limited to once per day to avoid log flooding) so the condition is visible without being noisy. Ensure doveadm connectivity in any deployment that enables com.openexchange.mail.crossContextPermissions. - Pre-existing / raw ACLs. ACLs created directly on the IMAP server (outside App Suite) are not tracked in the liaison registry, so the audit and purge tooling does not see them; a one-time sweep is needed if such grants already exist (see Limitations).
Rendering foreign entities in clients
A client rendering a cross-context relationship cannot resolve the counterpart on its own: the entity lives in a different context, so its bare numeric id is meaningless locally and there is no directory to look up a display name or e-mail. Responses that surface a (possibly foreign) entity therefore carry a pre-resolved entityInfo block — resolved server-side from the entity's own context, mirroring the Shared Accounts API. It reuses the shared-account shape (identifier, type, display_name, contact.email1, …); for a foreign entity the qualified identifier (<id>@<contextId>) is the stable key, while the bare numeric entity is omitted because it does not resolve in the requesting user's context.
For the deputy API this means GET /deputy?action=all describes each deputy via entityInfo, and GET /deputy?action=reverse additionally describes each (possibly foreign) grantor via grantorEntityInfo. See Entity information in deputy listings.
Limitations
- Mail requires the same mail server. Cross-context IMAP/ACL sharing only works within a single mail backend; a grant to a foreign user on a different mail server is rejected (unless
crossContextRequireSameServeris disabled). - Mail revocation needs doveadm; residual raw-IMAP ACLs need a sweep. Withdrawing a cross-context mail grant is explicit (a per-share revoke or the purge tool); App Suite then retracts the underlying IMAP ACL via best-effort doveadm. Without doveadm the IMAP ACL persists until doveadm becomes reachable. A client talking raw IMAP directly relies on that ACL, so residual or pre-existing raw-IMAP ACLs are removed only by the doveadm retraction or a one-time sweep.
- Public calendar folders are read-only across contexts. A private/personal calendar folder can be shared read-write to a foreign user; a public folder is read-only for the foreign grantee, because creating or changing an appointment in a public folder requires an organizer internal to the folder's owning context, which a foreign user cannot be. Cross-context free/busy and conflict-checking are out of scope for this feature.
- No contacts/Drive targets. As noted under Supported scope.
Error reference
When a cross-context grant is attempted but cannot be honored, clients receive a dedicated, translatable error rather than a generic failure:
| Code | Meaning |
|---|---|
FLD-1053 | The liaison is denied by the deployment policy - the trust zones of the sharing user and the target context do not intersect. |
FLD-1052 | The grantee's permission is not applicable for this resource - e.g. a mail grant where the foreign mailbox is not on the same mail server. |
XCTX-* | Cross-context infrastructure errors: identifier could not be resolved to a valid principal, a database error in the liaison registry, or a mail-ACL retraction failure. |
The FLD-1053 / FLD-1052 deny paths are deterministic and surface up front, so a client need not wait for a downstream failure to learn that a grant is not permitted.