# AwoooP RLS Access Path Audit

> Purpose: verify API runtime DB access paths are ready for fail-closed RLS.

Before enabling RLS policies, runtime database access must set
`app.project_id`. The approved paths are:

- FastAPI dependency `get_db()`.
- Background/service context `get_db_context()`.
- `UnitOfWork`, which now sets `app.project_id` on entry.

Both `get_db()` and `get_db_context()` derive `app.project_id` from
`src.core.context.get_current_project_id()` unless the caller passes an explicit
project id to `get_db_context()`.

Run:

```bash
python3 scripts/ops/awooop-rls-access-audit.py
```

To include accepted exceptions:

```bash
python3 scripts/ops/awooop-rls-access-audit.py --show-allowed
```

## 2026-05-12 Result

After fixing direct `get_session_factory()` runtime call sites:

```text
AwoooP RLS access audit: BLOCKED=0 ALLOW=10
```

Accepted exceptions:

- `apps/api/src/db/base.py`: owns the shared engine/session factory and sets
  `app.project_id` in `get_db()` / `get_db_context()`.
- `apps/api/src/routes/health.py`: raw `asyncpg` health check only runs
  `SELECT 1`, not tenant table queries.
- `apps/api/src/main.py` and `apps/api/src/workers/signal_worker.py`: only log a
  sanitized DB host suffix.
- `apps/api/src/services/incident_approval_service.py`: injects
  `UnitOfWork`; `UnitOfWork` now sets `app.project_id`.

Manual scripts under `apps/api/scripts/` and top-level `scripts/` are not API
runtime. They still need operator review before being used against production
after RLS policy enablement.
