Skip to main content
CYPEX Documentation
Support
v2.0.0 Latest stable release View changelog ->
CYPEX — PostgreSQL Application Platform CYPEX Documentation Organizations & Row-Level Security

Organizations & Row-Level Security

5 min read

In CYPEX, an Organization is the unit of multi-tenancy. Isolation is enforced in PostgreSQL by Row-Level Security policies that read the request JWT, not by filters in application code. Application traffic — the generated UI, PostgREST API clients, and the backend’s end-user request path — is subject to the same policies, so reaching the database through a different client does not widen what a user can see.

Organizations are not an authorization system on their own. They add a per-request data scope on top of the PostgreSQL role grants that decide what a user may do.

This section is the conceptual reference. It complements, and does not replace, the post-upgrade procedure under Detailed organization setup. Read this section to understand the model; follow the linked procedure to set up additional organizations after the v2.0.0 upgrade.

Warning

Two boundaries of the enforcement claim. Both are worth knowing before a security review.

Your own tables are not covered. The policies installed by v2.0.0 protect CYPEX’s own catalog — the cypex, cypex_log, and sso_gateway schemas. They do not apply to the business schemas you model in. Isolating your own tables by organization is a policy you write; see Capabilities vs Data Scope for the template.

The control plane runs on a privileged connection. The backend serves platform-administrator requests over a separate administrative database login, which needs DDL rights to create schemas and run migrations. A PostgreSQL superuser is exempt from RLS by definition, and CYPEX does not set FORCE ROW LEVEL SECURITY on its tables. Treat the administrative connection string as a credential of the same weight as a database superuser password, and give the platform-administrator role type to as few people as the deployment allows.

Pages in this section

  1. What is an Organization? — the tenancy contract, the JWT claims, the four RLS helper functions, and the request flow.
  2. Setup guide — operational how-to: create, edit, and disable organizations, assign users, configure organization-scoped Schema Access, and troubleshoot common misconfigurations.
  3. Capabilities vs Data Scope — the model itself: capabilities say what a role may do; organizations say which rows it may act on.
  4. Organization hierarchy and assignment — how roles and schemas map onto an organization through t_role_organization and t_module_organization, and the order to wire them up in.
  5. Governance evidence — where evidence of an organization-related decision lives: the permission audit log and the backend write path.
  6. Building apps across organizations — application visibility per organization, export and import with organization context, and how to verify an app’s behaviour for users of two different organizations.

Module and Schema

Info
Module and Schema are the same concept. Both refer to a PostgreSQL schema — a namespace grouping tables, views, and functions. “Module” is the deprecated term; it survives in database identifiers such as cypex.t_module.schema_name and cypex.t_module_organization. Schema Access (new in v2.0.0) is the admin page that grants schemas to organizations. Where this section says “granting a module”, read “granting access to a schema”. See the Glossary.

The two dimensions at a glance

DimensionQuestion answeredWhere it lives
CapabilityWhat is this role allowed to do?PostgreSQL role grants
Data ScopeWhich rows may this user see or change?Organization mapping + RLS policies

A request must satisfy both. Broad capabilities with no organization mapping return nothing; an organization mapping with read-only capabilities returns everything in that organization and permits no changes.

Two pages cover this. The conceptual page has the model, the policy shapes, and worked examples. The admin-panel walkthrough covers the same ground through the GUI, with the Role Details screens and the combined-query flow.

Audit and verification

Permission changes are recorded in cypex_log.t_permission_audit_log — role and organization creation, grants and revocations, permission edits, connector executions, and explicitly logged access decisions. Administrators read it at:

GET /admin/audit/permissions
Info
RLS filtering itself is not logged. When a policy hides a row, nothing is written — the row simply does not appear. The audit log answers “who changed this permission, and when”. To answer “why can this role not see that object”, use Access Preview, which resolves capability and data scope together for a given role and organization.

The full evidence path, including the backend write path, is on the Governance evidence page.

Tip

After a v2.0.0 upgrade, confirm that RLS is enabled where it should be:

1
2
3
4
SELECT schemaname, tablename, rowsecurity
FROM pg_tables
WHERE schemaname IN ('cypex', 'cypex_log', 'sso_gateway')
ORDER BY schemaname, tablename;

The v2.0.0 migration set enables RLS on 37 tables in total — 28 in cypex, 5 in cypex_log, and 4 in sso_gateway. This query confirms that RLS is enabled; it does not confirm that a policy is correct. Read the policies in pg_policy, or use Access Preview. The full checklist is on the Upgrade to v2.0.0 page.

See also