100 lines
2.5 KiB
Markdown
100 lines
2.5 KiB
Markdown
# AwoooP RLS Canary Wave 1.1
|
|
|
|
This wave targets one low-row non-empty table:
|
|
|
|
- `awooop_mcp_tool_registry`
|
|
|
|
It does not include `awooop_projects`.
|
|
|
|
Status: applied to production on 2026-05-12.
|
|
|
|
## Why Not `awooop_projects`
|
|
|
|
`awooop_projects` has only two rows, but it is not safe to enable with a normal
|
|
tenant-only policy yet. `platform_operator_service.list_tenants()` currently
|
|
uses `get_db_context("awoooi")` while the API contract says Operator Console
|
|
returns all projects. A tenant policy on `awooop_projects` would hide the
|
|
`ewoooc` row from that endpoint.
|
|
|
|
Blocker before enabling `awooop_projects`:
|
|
|
|
- introduce an explicit platform-admin/bypass role path for Operator Console
|
|
cross-tenant reads, or
|
|
- redesign list-tenants semantics so it is intentionally tenant-scoped.
|
|
|
|
## Scope
|
|
|
|
Latest live evidence before apply:
|
|
|
|
```text
|
|
awooop_mcp_tool_registry: ewoooc=4
|
|
```
|
|
|
|
Runtime read path:
|
|
|
|
- `McpGateway._gate3_tool()` filters by `ctx.project_id`, `tool_name`, and
|
|
`is_active`.
|
|
|
|
## Apply
|
|
|
|
```bash
|
|
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 \
|
|
-f scripts/ops/awooop-rls-canary-wave1-1-tool-registry.sql
|
|
```
|
|
|
|
The SQL aborts if:
|
|
|
|
- table is missing,
|
|
- `project_id` is missing,
|
|
- any `project_id` is NULL,
|
|
- row count exceeds the reviewed canary cap of 20 rows.
|
|
|
|
## Verification
|
|
|
|
Expected after apply:
|
|
|
|
- no context: `awooop_mcp_tool_registry` reads/writes are denied or return no
|
|
rows, depending on query shape and privilege path.
|
|
- `app.project_id='ewoooc'`: the four active ewoooc tools are visible.
|
|
- `app.project_id='awoooi'`: no ewoooc tools are visible.
|
|
- global RLS preflight remains blocked only by later-wave tables.
|
|
|
|
## 2026-05-12 Production Evidence
|
|
|
|
Apply completed with `COMMIT` through the 188 postgres/operator socket path.
|
|
|
|
Post-apply relation state:
|
|
|
|
```text
|
|
awooop_mcp_tool_registry|rls=true|force=true|policies=1|fail_open=false
|
|
```
|
|
|
|
API pod behavior test:
|
|
|
|
```text
|
|
tool_registry_no_context=0
|
|
tool_registry_ewoooc_context=4
|
|
tool_registry_awoooi_context=0
|
|
tool_registry_insert_with_context=allowed_and_rolled_back
|
|
tool_registry_probe_rows_after=0
|
|
```
|
|
|
|
Operator/global count:
|
|
|
|
```text
|
|
ewoooc|4
|
|
```
|
|
|
|
Note: after RLS is enabled, API-pod `--exact-counts` are tenant-visible counts,
|
|
not global counts. Use postgres/operator evidence for global row-count checks.
|
|
|
|
## Rollback
|
|
|
|
```bash
|
|
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 \
|
|
-f scripts/ops/awooop-rls-canary-wave1-1-tool-registry-rollback.sql
|
|
```
|
|
|
|
Rollback removes the Wave1.1 policy and disables RLS on
|
|
`awooop_mcp_tool_registry`. It does not modify data.
|