Skip to content

0012. Require one fully accessible side to manage a sync rule

Date: 2026-07-31 Status: Accepted

Context

ADR-0007 split a PlatformSupport user's reach in two: connections to a system they operate are fully accessible, every other connection of the same tenant is status-only. A SyncRule joins two connections (ADR-0010 guarantees both belong to the same tenant), so that split does not decide the question by itself — a rule can have one fully accessible side, two, or none, and ADR-0007 says nothing about which of those permits a change.

Requiring both sides looks like the safer reading. It is not a workable one. SystemConnection::fullyAccessibleBy() matches only systems whose driver returns true from SystemDriver::canHaveSupportUsers(), i.e. internal consuming platforms (ADR-0008). Every rule the platform derives on activation spans shop ↔ internal product, and a shop adapter can never have support members. A support user therefore never holds full access to both sides of a real rule.

Decision

A sync rule is visible when its tenant is reachable, and changeable — created, activated, deactivated, deleted — when at least one of its two connections is fully accessible.

Two scopes on SyncRule state this once: accessibleBy(User) for visibility (checking the source connection alone, since ADR-0010 guarantees a shared tenant) and manageableBy(User) for changes. SyncRulePolicy reads view from the first and update/delete from the second, and the admin panel's query and row actions read from the same two scopes rather than restating the rule.

create is the exception: it receives no rule to inspect, so there the bar is only "holds sync_rules.create and has at least one fully accessible connection". Whether a specific pair is allowed is decided when the rule is saved, by the form's validation and by SyncRule::booted().

Consequences

A support user of one internal platform can change a rule that also touches a second internal platform they have no relationship with — for example a User Platform → WooCommerce rule, when they operate rapidmail and reach the tenant through it. That is the accepted cost: the alternative reduces rule management to SuperAdmin in practice while presenting itself as a graded permission, which is worse than a boundary that is honest about where it sits.

Rule content is still constrained independently of who is editing: the direction matrix (ADR-0005) and tenant isolation (ADR-0010) are enforced on save regardless of the actor.