InfoThis page is the admin-panel walkthrough: where each dimension lives in the GUI, and how they combine at query time. For the full conceptual write-up (JWT claims, RLS SQL, theroleTypeAPI contract), see Capabilities vs Data Scope under Organizations.
The v2.0.0 access model has two independent dimensions. A request only returns rows when both agree:
| Dimension | Question answered | Where it’s configured |
|---|---|---|
| Capabilities | What is this user allowed to do? | PostgreSQL role grants (SELECT/INSERT/UPDATE/DELETE, EXECUTE) |
| Data Scope | Which rows is this user allowed to act on? | Organization assignment + Row-Level Security |
A role with broad capabilities but no organization mapped sees no tenant rows. A role mapped to an organization but with read-only capabilities sees all of that organization’s rows but can’t change them. Neither dimension substitutes for the other.
Capabilities are configured on Roles & Capabilities, under Role Details:
Role Details — Role Attributes
PostgreSQL role attributes (Superuser, Can Login, Create Roles, Create Databases, …) define what this role can do at the database level.

Role Details — Capabilities
Schema-level permissions (e.g. eshop: USAGE). Object-level permissions on views, functions, and state transitions are assigned separately; review the resolved outcome on the Access Preview page.

Data Scope is configured on the same Role Details panel, under the Organizations tab, and at role-creation time:
Role Details — Organizations
Organization Boundaries: users holding this role can only access data within the organizations assigned here.

Create Role — Organization Assignments
For Organization Administrator and Organization Member role types, at least one organization must be assigned here before the role can be saved.

A role with capabilities but zero organizations assigned is flagged No Scope in the role list — see Roles & Capabilities — User-Defined Roles.
flowchart LR
req["Incoming request<br/>role + org_id claim"]
cap{"Capability check<br/>PostgreSQL role grant"}
scope{"Data Scope check<br/>RLS policy on org_id"}
deny["No rows / operation denied"]
allow["Rows returned"]
req --> cap
cap -->|"denied"| deny
cap -->|"allowed"| scope
scope -->|"no match"| deny
scope -->|"match"| allowBoth checks run on every request. Capabilities are enforced by the PostgreSQL role the session runs as; Data Scope is enforced by RLS policies keyed on the org_id JWT claim (wired by the v2.0.0 upgrade’s Organizations migrations). Neither layer knows about the other — that separation is intentional, so granting a capability and assigning an organization remain independent operations.
| No organization assigned | Assigned to Org A only | Assigned to Org A + Org B | |
|---|---|---|---|
Organization Member (cypex_user) | No rows visible (No Scope) | SELECT-only, Org A rows | SELECT-only, Org A + Org B rows |
| Organization Administrator | No rows visible (No Scope) | Full CRUD, Org A rows | Full CRUD, Org A + Org B rows |
System Administrator (cypex_admin) | Full CRUD, all organizations — every policy admits the role via cypex.is_admin(); organization assignment doesn’t apply | same | same |
Every capability or data-scope change — role create/update, capability grant, organization assignment — is written to cypex_log.t_permission_audit_log (action, entity_type — role / organization / view / function / state_transition —, before_state, after_state). It’s queryable via:
GET /admin/audit/permissions
InfoThere is no dedicated admin-panel page for this log yet — it’s API-only, filterable byuserId,action,entityType,entityId, and date range. See Governance evidence for the full evidence trail (write-path service calls and doc-side approvals).
Before Organizations, app rendering in CYPEX was single-dimension: Applications predicts an application for a chosen owner user, and CYPEX renders only the tables, forms, and buttons that user’s role permits — capabilities alone decided the outcome, because there was no separate data-scope concept to layer on top.
v2.0.0 keeps that capability-driven prediction unchanged, but adds Data Scope as a second, independent axis: the same predicted app now also filters rows by the viewing user’s organization membership at query time via RLS. Two users with the identical role see the identical app shape (same capabilities), but different data (different data scope) if they belong to different organizations.
InfoComing from Oracle APEX? The two security concepts on this page have direct APEX equivalents — useful shorthand if you’re mapping a migrated application’s access model.
| Oracle APEX concept | CYPEX equivalent |
|---|---|
| Authorization Scheme | PostgreSQL role grant (Capabilities, this page’s first dimension) |
| Workspace / App Group | Organization (Data Scope, this page’s second dimension), enforced via RLS instead of an application-level check |
APEX evaluates both as PL/SQL conditions inside the application; CYPEX evaluates the same two questions as PostgreSQL role grants and RLS policies at the database layer, so the access rules hold regardless of which client queries the data.
- Glossary — the one-line Capability and Data Scope definitions.
- Capabilities vs Data Scope (full docs) — the conceptual mental model, RLS SQL, and the
roleTypeAPI contract. - Roles & Capabilities — create and edit roles.
- Organizations — the admin-panel entry point for multi-tenancy.
- Governance evidence — the permission audit log and approvals trail.
- Applications — the legacy capability-only app prediction this model now layers on top of.
- User management — how the CYPEX user concept maps to roles.
- Connectors — how the same Capabilities/Data Scope model governs the external API connector platform.