RLS and permission exceptions register
Table of Contents
- 1. Summary
- 2. Detail
- 2.1. How to read an entry
- 2.2. E1. The system party reads every party's compute work
- 2.3. E2. Rows with no party are visible to every party session
- 2.4. E3. Every session reads the system tenant's grid sample rows
- 2.5. E4. Tables that the installation owns
- 2.6. E5. The service enters a tenant to read or write
- 2.7. E6. The permissions and the route that open the grid to tenants and parties
- 2.8. E7. An operator enters each tenant to read its work
- 2.9. E8. The installation's work totals
- 3. See also
1. Summary
This page lists, in one place, every exception to the tenant and party row-level security rules, and every table that the installation owns, that the compute grid work added. Each entry gives what changed, why, what it exposes, what limits it, how it was checked, and where its security review and sign-off stand. The rule that governs entries is in Data read across tenants: an exception needs a stated reason, a review and a sign-off before it is accepted. No entry here has completed a security review yet. The state of each is stated, so a later review can start from this list.
The guard check_rls_system_tenant_widenings.py still reports 11 system-tenant widenings, all listed, and none of the entries below adds one. None gives a system-tenant session a read of another tenant's rows.
2. Detail
2.1. How to read an entry
| Field | Meaning |
|---|---|
| What | The policy, table, permission or route that changed, and the file |
| Why | The reason, and who asked for it |
| Exposes | What a session can now read that it could not before |
| Limits | What still holds it back |
| Evidence | How it was checked, with the PR |
| Review | The state of the security review |
| Sign-off | The state of the owner's approval |
States: Pending means not done. A state is changed only when the review or the approval has happened, and the date and the person are written beside it.
2.2. E1. The system party reads every party's compute work
| What | The four party policies of the compute tables (batches_party_isolation_policy, workunits_party_isolation_policy, results_party_isolation_policy, grid_samples_party_isolation_policy) gain or (select ores_compute_session_is_system_party_fn()). The function is true when the session's party is the tenant's system party. File: projects/ores.sql/create/compute/compute_rls_policies_create.sql. |
| Why | A tenant administrator who signs in as the system party saw the fleet and no jobs, because the party rule hid every other party's rows from a session in a party with no children. The owner's rule, stated on 2026-10-13: the system party sees every party of the tenant, and each other party sees only its own. |
| Exposes | To a session in the tenant's system party: the batches, workunits, results and grid sample rows of every party of its own tenant. |
| Limits | The policies are restrictive, so the tenant isolation policy still applies and no other tenant's row is reachable. Only the four compute tables change. No other table's party rule changes. A session in any other party reads the same rows as before. |
| Evidence | PR #3217. A transaction with the session settings of the Acme system party read 285 batches, 18034 workunits, 18034 results and 57 party sample rows. The same with a child party (ACCOUK) read 0 of each. A repository test checks that the system party sums every party and a party sums its own. |
| Review | Pending |
| Sign-off | The owner asked for the rule on 2026-10-13 and instructed the merge of PR #3217 on 2026-10-13, which accepts it for the merge. A separate sign-off after the security review is still pending. |
Open points for the review:
- The function compares the session's party with the system party by id. It does not look at the session's mode or permissions, so any account that can act in the system party gets the rule. The accounts that can do so are those linked to that party.
- The same rule exists for the accounts table in another form (the system party's people are visible to everyone). The two rules are not the same rule, and the review should say whether they should be.
2.3. E2. Rows with no party are visible to every party session
| What | The party policies pass a row whose party_id is NULL. This is the rule that batches, workunits and results already had. The grid samples now follow it. |
| Why | Work from before the party scope has no party, and so has work that a service submits. Both must stay visible inside the tenant. |
| Exposes | A session in a party reads the counters of the tenant's no-party work, summed with its own party's counters in the grid series. |
| Limits | Only inside the tenant. The rows hold counts and no business data. |
| Evidence | PR #3214. A repository test counts the no-party row in a party session on purpose. |
| Review | Pending |
| Sign-off | Pending |
2.4. E3. Every session reads the system tenant's grid sample rows
| What | The grid samples table policy is tenant_id = current or tenant_id = system. It is the shared-reference shape and is older than this work. The tenant series read now uses it: the host counts come from the system tenant's rows. |
| Why | A tenant needs the installation's capacity (hosts, online, idle) to read its own queue. The owner decided on 2026-10-13 that a summary of capacity is fine for a tenant. |
| Exposes | The installation's host, online and idle counts to every tenant's session. |
| Limits | The series read takes only the three host columns of the system rows. No machine, host name or hardware is read for a tenant, and the BFF reads no node series and no host list for a tenant. |
| Evidence | PR #3214. A repository test reads the fleet through a tenant session. A BFF test checks that no node or host read happens for a tenant. |
| Review | Pending |
| Sign-off | Pending |
Open point for the review: the policy admits the whole system-tenant row, and the fleet row also holds the system tenant's own job counters for its work with no party. The series read does not use them, but a direct read of the table by a tenant session would see them. The review should say whether the fleet should move to a row or table of its own.
2.5. E4. Tables that the installation owns
| What | ores_compute_work_ledger_tbl (PR #3198) and ores_compute_work_tenants_tbl (PR #3214). The policy of each is tenant_id = current and tenant_id = system, which admits only a session of the system tenant. |
| Why | The queue of the grid serves every tenant, and the system tenant cannot read a tenant's own rows, so the queue cannot be a query over the tenants' results. The tenant list exists because the poller of the samples must know which tenants to count, and the compute service has no read of the tenant roster. |
| Exposes | Nothing to a tenant. The ledger holds result ids, tenant ids, platforms, priority, host, lease and attempts. The tenant list holds tenant ids and a time. Neither holds business data. |
| Limits | A tenant session and an operator who has entered a tenant read none of either table. Both are written only by the compute service as the system tenant. |
| Evidence | PRs #3198 and #3214. Repository tests read each table. A test checks that a tenant session reads none of the tenant list. The validation ignore list names both tables for the tenant column rule. |
| Review | Pending |
| Sign-off | Pending |
2.6. E5. The service enters a tenant to read or write
| What | The compute service uses tenant_context::with_tenant to enter a tenant. The claim handler marks a result in progress, the lease reaper ends a result, the dispatcher saves results, and the poller reads each tenant's work and writes its sample rows. |
| Why | The work belongs to the tenant, and the queue and the samples belong to the installation. Entering the tenant is the documented way for a service to touch a tenant's own rows. |
| Exposes | The service reads and writes the work of every tenant that it serves, as the tenant. |
| Limits | Each entry is of one tenant at a time and writes only that tenant's own rows. The reads count rows and the writes are the ones the operation needs. |
| Evidence | PRs #3198, #3201 and #3214. |
| Review | Pending. The review should check whether a service's entry needs an audit record, as an operator's entry has. |
| Sign-off | Pending |
2.7. E6. The permissions and the route that open the grid to tenants and parties
| What | The Member role holds compute::grid_samples:read, compute::batches:read, compute::workunits:read and compute::results:read in the populate script. The grid screen card needs compute::grid_samples:read and no longer the read of the deployment. The BFF route /api/operations/grid/series serves a tenant or party session its own series without the deployment read. File: projects/ores.sql/populate/iam/iam_roles_populate.sql, projects/ores.web/packages/bff/src/operations.ts. |
| Why | A tenant administrator and a party member must see the grid's load, throughput and outcomes for their own work. The owner decided on 2026-10-13 that a party user sees all the statistics of the party. |
| Exposes | Every person of a tenant gains the read of the grid series and usage for the work their party scope allows. The workunit and result reads add the jobs of the person's own parties. The BFF hides the host of a result from a session that is not an operator. |
| Limits | The rows are cut by the policies above. The machines, nodes and heatmap routes still need the read of the deployment. The route reads no node and no host for a non-operator. |
| Evidence | PR #3214. BFF and web tests check the tenant series route and that a tenant is not offered the machines, nodes or heatmap. |
| Review | Pending. The live Member roles of Acme and Barclays were not changed. The populate script is the only change, so a database that is not rebuilt does not have the permissions, and that includes the workunit and result reads added by PR #3647. A live check after a recreate showed a member of the batches' own party reading the tree and a member of another party reading none. |
| Sign-off | Pending |
2.8. E7. An operator enters each tenant to read its work
| What | The BFF enters each tenant with readInsideTenant, reads the usage there, and leaves. The server records each entry and exit. |
| Why | A system administrator needs the grid's use by tenant, and no policy lets the system tenant read another tenant's work. |
| Exposes | The operator reads each tenant's usage counts, as that tenant. |
| Limits | The entries are recorded. A tenant that cannot be entered is listed as unavailable and never as empty. |
| Evidence | PR #3197. |
| Review | Pending |
| Sign-off | Pending |
2.9. E8. The installation's work totals
| What | The table ores_compute_work_totals_tbl, one row for each grid sample, with the counters of every tenant's work summed. Its policy is tenant_id = current and tenant_id = system, as the work ledger's is. Files: projects/ores.sql/create/compute/compute_work_totals_create.sql, projects/ores.compute/core/src/repository/work_total_repository.cpp. |
| Why | A session of the system tenant saw 22 hosts and no jobs, because the work counts are each tenant's and the system tenant reads none of them. The owner chose on 2026-10-21 a table of the installation that only the system tenant reads. A first change made the fleet row count every tenant's work through a function with its owner's rights. A review found that a database role could read any tenant's counts through it, and every tenant session reads the fleet row, so it was withdrawn. |
| Exposes | To a session of the system tenant: the sum of the job counters of all tenants. |
| Limits | The table holds counts and names no tenant, party, batch or result. A tenant session reads none of it, and the grid reads take it only for a session of the system tenant. The compute service writes it as the system tenant. The poller sums the counters it reads inside each tenant (entry E5), so no read crosses a tenant and no function runs with its owner's rights. A poll that could not read a tenant writes no row, so the totals never show a tenant's work as empty. |
| Evidence | PR #3607. Repository tests check that the totals add up, that the system tenant reads what it wrote, and that a tenant session reads none. A read-only database role reads 0 job counts of the ACME tenant through the stats function. |
| Review | Pending |
| Sign-off | The owner chose the table on 2026-10-21. A separate sign-off after the security review is pending. |
Open points for the review:
- The totals are a cross-tenant aggregate, which the ownership page calls a fact of several tenants. The table keeps it where only the system tenant reads it. The review should say whether the audit task needs to confirm the rule.
- The outcome counters cover the last day, as the rows they sum do.
3. See also
- Data read across tenants: the rule that an exception needs a reason, a review and a sign-off.
- How the compute grid queues and claims work: the work ledger and the claim.