Files
mattermost/server
Nick MisasiandCursor Agent c7eff70026 ABAC: plugin-keyed resource types, trusted plugin PAP/CEL APIs, and AuthZEN-style decision API (#37509)
* MM: add v0.5 plugin access control policy model, registry, and decision outcomes

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: add plugin access control PDP/PAP app-layer methods with fail-closed semantics

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: expose plugin access control API surface (EvaluateAccessControl + PAP/CEL methods)

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: add store-layer round-trip tests for v0.5 plugin access control policies

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: extract plugin access control app code into plugin_access_control.go

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: add atomic type-guarded AccessControlPolicyStore.DeleteIfType

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: plugin PAP hardening — atomic typed delete, indistinguishable 404s, audit every attempt

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: close plugin Get-by-ID TOCTOU via GetPolicyOfType; stamp save audit operation at entry

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Fix gob RPC poisoning from native attribute select options

NativeUserAttributeFields stored bool-select options as
[]map[string]string inside PropertyField.Attrs (map[string]any). gob
requires concrete types inside interface values to be registered, and
[]map[string]string is not registered in client_rpc.go, so encoding the
GetAccessControlFieldsAutocomplete reply failed and net/rpc shut down
the shared plugin API connection, breaking every subsequent plugin API
call.

Build the options from gob-registered containers ([]any/map[string]any)
instead; JSON output is byte-identical. Add gob round-trip regression
tests covering every plugin access control API reply payload: the
autocomplete response including native attribute fields (fails against
the old code), policies with JSON-decoded Props, visual AST condition
values of every runtime shape, expression check errors, query users
responses, and evaluation decisions.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Move plugin access control gob-safety tests into their own file

Pure move: plugin_access_control_test.go crossed 1000 lines; the gob-safety
helper and TestPluginAccessControlGobSafety now live in
plugin_access_control_gob_test.go, unchanged.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM: resolve plugin policy existence when ABAC is unavailable (Option B)

Every evaluation-impossible branch of EvaluatePluginAccessRequest
(service nil / unlicensed / flag off / user load or subject build
failure / evaluator infra error / unknown outcome) now performs a raw
open-core store read on the already-validated resource ID: no stored
row returns no_policy so the caller can safely apply legacy behavior;
any stored row (with a Warn on a foreign-type anomaly) or a failed
read returns unavailable so the caller must fail closed. This lets the
plugin drop its local policy index entirely.

Strengthens the EvaluateAccessControl doc contract accordingly and
reworks the fail-closed test matrix with with/without-row splits per
branch, a foreign-type-row case, a store-read-error case on the store
mock, and passthrough rows pinning that the fallback read never runs
when the evaluator answers.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Clarify EvaluateAccessControl failure-mapping doc

A failure with a definitive store miss maps to no_policy under the
Option B semantics, so 'failures never map to allow or no_policy' was
inaccurate. State precisely: never allow; no_policy only on positively
determined non-existence; deny for defensive failures on a resolved
policy; unavailable otherwise.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Tighten ABAC comments

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Document AccessDecision.Outcome as plugin-API-only

The evaluator populates Outcome on every lane, but the only production
reader is the app layer's EvaluatePluginAccessRequest, which maps it
into PluginAccessControlDecision; core channel/team enforcement reads
the collapsed Decision bool alone. State that on the field.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Retrigger CI to rebuild enterprise image with updated enterprise branch

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Document that only the evaluator's plugin lane sets AccessDecision.Outcome

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: key plugin resource types as plugin_id:type and drop the static registry

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: replace AccessDecision.Outcome with the AuthZEN decision context reason

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: drop type-scoped policy get/delete and check the type in the app layer

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: compare plugin policy type ownership exactly instead of case-insensitively

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: bound the whole policy type to the Type column width

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: require an allow before treating a decision as the no-policy fallback

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: treat a colliding foreign-type policy row as no_policy, not a deny

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: gate plugin policy reads on a raw store read before normalization

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: pin policy type immutability on save in the store tests

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: reuse a single unavailable-error constructor in the existence fallback

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: re-check plugin policy ownership on the normalized get read

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ABAC: confirm plugin policy ownership before surfacing a normalization error

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-04 09:59:48 -04:00
..
2023-03-22 17:22:27 -04:00
2026-06-29 20:33:46 +02:00
2023-03-22 17:22:27 -04:00
2023-03-22 17:22:27 -04:00
2026-04-21 02:33:20 -07:00
2023-03-22 17:22:27 -04:00
2024-05-15 12:05:13 -03:00