Skip to main content

Module visibility

Module visibility 

Source
Expand description

Drive move visibility-diff algorithm — the security-critical core of drive move’s safety gate (ADR-0070).

Deliberately pure: zero DriveClient/network dependency, and zero dependency on crate::drive::file_move (or any other engine module) — this module classifies an already-fetched set of permission snapshots, so the whole file is unit-testable with no wiremock at all. DrivePermission fetching lives in crate::drive::permissions_api; orchestration (which files to fetch, calling classify, gating the move) lives in crate::drive::file_move.

§The algorithm

Drive’s permissions.list(fileId) returns a file’s full effective permission set (direct + inherited, merged) — but the permissionDetails[].inherited flag that would let us split “direct” from “inherited” is only populated for Shared Drive items, not My Drive files. So instead of reading that split off the file directly, it’s derived by subtraction, from three snapshots the caller fetches:

before          = principal_set(permissions.list(file_id))
current_parent  = principal_set(permissions.list(union of file's current parent(s)))  // ∅ if none
dest            = principal_set(permissions.list(dest_folder_id))

direct_on_file  = before − current_parent      // what's granted on the file, not inherited
after           = direct_on_file ∪ dest

added   = after − before     // visibility increase: new principals gain access
removed = before − after     // visibility decrease: principals lose access

Multi-parent legacy files: the caller unions permissions across every current parent, not just the first, before calling diff_visibility. An orphan/root file with no current parent passes an empty current_parent_perms slice, which degenerates correctly to “everything on the file counts as direct.”

§Known limitation: shadowed grants

If a principal has both a direct grant on the file and inherited access via the current parent (a “shadowed” grant), the subtraction can’t distinguish them: direct_on_file won’t include that principal (it’s in current_parent too), so if dest also doesn’t grant it, after won’t include it either — diff_visibility reports it as losing access even though it actually keeps it via the shadowed direct grant, invisible to this subtraction.

This is the safe failure direction: it can only produce a false positive on removed (an unnecessary --allow-visibility-decrease requirement), never a false negative on addeddirect_on_file ⊆ before always holds, and dest enters after unfiltered, so a real visibility increase is always caught. Accepted, not a bug to fix later.

Structs§

BlockReasons
Which safety gate(s) block a move.
MoveGateFlags
The three independent, per-move opt-ins classify gates on.
VisibilityDiff
The result of diffing a file’s visibility before/after a hypothetical move — see the module doc for the algorithm and its known limitation.

Enums§

Principal
A Drive permission’s identity, independent of role.

Functions§

classify
Classifies whether a move is clear to proceed.
diff_visibility
Computes the visibility diff a move from the file’s current parent(s) to a destination folder would produce, given three already-fetched permission snapshots (see the module doc’s algorithm).
principal_set
Builds the set of principals a permission list grants access to.