From 09e4e591921ab36e2ffc262180aa2f63587c5d06 Mon Sep 17 00:00:00 2001 From: Michael Dieringer <65093775+MichaelDieringer@users.noreply.github.com> Date: Sat, 20 Jun 2026 11:35:01 +0200 Subject: [PATCH] exposed --- ...sed-objects-must-be-in-a-permission-set.md | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 custom/knowledge/architecture/exposed-objects-must-be-in-a-permission-set.md diff --git a/custom/knowledge/architecture/exposed-objects-must-be-in-a-permission-set.md b/custom/knowledge/architecture/exposed-objects-must-be-in-a-permission-set.md new file mode 100644 index 0000000..6012ca5 --- /dev/null +++ b/custom/knowledge/architecture/exposed-objects-must-be-in-a-permission-set.md @@ -0,0 +1,41 @@ +# Exposed objects must be in at least one permission set + +**Rule (CURABIS-ARCH-011):** Every *exposed* object in a CURABIS app must be a member of +at least one permission set shipped by that app. "Exposed" means any object reachable from +outside the app's own UI: + +- API pages (`PageType = API`) +- Web-service-enabled pages and queries (`ServiceEnabled = true`, published web services) +- API queries + +## Why + +An exposed object that is in no permission set is **unusable and invisible** to the users +and service identities that are supposed to call it. This is exactly how the MCP API pages +(`CUR MCP Projects`, `CUR MCP Active Tasks`, `CUR MCP Task Comments`) failed: the tables +behind them were granted, but the pages themselves had no `= X` execute permission, so the +MCP server could not see or call them. + +It is also a **governance gap**: an endpoint that nobody deliberately put in a permission +set is an endpoint nobody is deciding who may reach. Exposure must be an explicit choice. + +## How to apply + +1. For every exposed object, add an execute entry (`page "..." = X`, `query "..." = X`) to + a permission set in the app. +2. **Sensitive endpoints go in a dedicated admin permission set** (e.g. `CUR ... Admin`) + that is *not* part of the default assignable set — so reaching them is a deliberate grant, + not the default. +3. If an object should not be reachable from outside at all, **remove the exposure** instead + (drop `PageType = API` / `ServiceEnabled`) rather than leaving an orphaned endpoint. + +## How to check + +Scan the app for exposed objects and verify each is referenced in a permission set: + +- find every `PageType = API`, `ServiceEnabled = true`, and API query +- confirm each appears as a `page`/`query` `= X` entry in at least one `permissionset` +- flag any exposed object with no permission-set membership + +A reviewer (or an automated check) should fail the change if an exposed object is missing +from every permission set.