docs(ops): 記錄 RLS role bootstrap 套用
This commit is contained in:
@@ -1,3 +1,40 @@
|
||||
## 2026-05-12 | RLS Role Bootstrap 已套用
|
||||
|
||||
**背景**:上一輪已新增 `scripts/ops/awooop-rls-role-bootstrap.sql`,但尚未執行;使用者批准後,本輪只執行 role bootstrap,不啟用 RLS policy。
|
||||
|
||||
**執行方式**:
|
||||
- 沒有使用 `sudo`,也沒有走 K8s app `DATABASE_URL`。
|
||||
- 188 `ollama` 使用者可用 Docker;使用 host PostgreSQL socket 與 host `postgres` UID `115:121` 連線。
|
||||
- 驗證連線為 `current_user=postgres`、`rolsuper=true` 後,透過 stdin 執行 `scripts/ops/awooop-rls-role-bootstrap.sql`。
|
||||
- SQL 成功 `COMMIT`,未建立任何密碼、未修改 K8s Secret、未啟用任何 RLS policy。
|
||||
|
||||
**role 結果**:
|
||||
- `awooop_app`:`NOLOGIN`,非 superuser,非 `BYPASSRLS`。
|
||||
- `awooop_platform_admin`:`NOLOGIN`,`BYPASSRLS=true`。
|
||||
- `awooop_migration`:`NOLOGIN`,`BYPASSRLS=true`。
|
||||
- `awoooi` 仍是 production API DB user,並已成為 `awooop_app` member。
|
||||
- `awoooi_migrator` 存在,並已授權 `awooop_migration` group;未變更其 password / login secret。
|
||||
|
||||
**post-bootstrap RLS preflight**:
|
||||
- `bash scripts/ops/awooop-rls-preflight.sh --exact-counts` → exit `2`,符合預期,因 policy 尚未啟用。
|
||||
- `PASS=7 WARN=0 BLOCKED=1`。
|
||||
- 新增轉綠:
|
||||
- `required_roles` → PASS。
|
||||
- `app_role_membership` → PASS。
|
||||
- 唯一 BLOCKED:
|
||||
- `rls_enabled_forced_policy`:target tables 尚未 RLS enabled / forced / policied。
|
||||
- exact counts 仍顯示 target tables `NULL project_id = 0`。
|
||||
|
||||
**production smoke**:
|
||||
- `https://awoooi.wooo.work/api/v1/health` → 200,PostgreSQL / Redis / Ollama / OpenClaw / SignOz 均 up。
|
||||
- `/api/v1/platform/runs/list?per_page=1` → 200,`total=126`。
|
||||
- `awoooi-api` pods 2/2 running;近 10 分鐘 log 未見 DB permission / RLS / SQLAlchemy / asyncpg error。
|
||||
|
||||
**下一步**:
|
||||
- 不要直接全表熱開 RLS。
|
||||
- 先做 DB access path audit,確認所有 production read/write 入口皆會設定 `app.project_id`。
|
||||
- 再產出 staged policy enablement:先 staging / canary,再 production batch。
|
||||
|
||||
## 2026-05-12 | 188 Ollama Gate 綠燈與 RLS Role Bootstrap 設計
|
||||
|
||||
**背景**:Wave 1 尚有兩個可收斂點:188 local Ollama 是否仍有 direct caller,以及 RLS roles 缺失如何安全補上。原則維持:只驗證與準備,不直接 uninstall 188 Ollama,不直接 production 熱開 RLS。
|
||||
|
||||
@@ -28,7 +28,7 @@ AWOOOP_RLS_SSH_TARGET=wooo@192.168.0.120 bash scripts/ops/awooop-rls-preflight.s
|
||||
|
||||
Exit code `2` means the gate is blocked and RLS must not be enabled yet.
|
||||
|
||||
## 2026-05-12 Production Result
|
||||
## 2026-05-12 Initial Production Result
|
||||
|
||||
`--exact-counts` returned:
|
||||
|
||||
@@ -61,28 +61,58 @@ Important exact counts from the same run:
|
||||
| `knowledge_entries` | 2102 | 0 |
|
||||
| `playbooks` | 220 | 0 |
|
||||
|
||||
## 2026-05-12 Role Bootstrap Applied
|
||||
|
||||
At `19:33 CST`, the manual role bootstrap was applied through the host
|
||||
PostgreSQL socket as `postgres`. It did not enable RLS policies.
|
||||
|
||||
Post-bootstrap `--exact-counts` returned:
|
||||
|
||||
- `PASS current_role_rls_enforced`: current DB user is still `awoooi`, not
|
||||
superuser and not `BYPASSRLS`.
|
||||
- `PASS project_context_set_config`: `set_config('app.project_id', 'awoooi', TRUE)` works.
|
||||
- `PASS required_roles`: `awooop_app`, `awooop_platform_admin`, and
|
||||
`awooop_migration` now exist.
|
||||
- `PASS app_role_membership`: current API DB user is a member of `awooop_app`.
|
||||
- `PASS project_id_columns`: every existing target table has `project_id`.
|
||||
- `BLOCKED rls_enabled_forced_policy`: target tables are still not RLS enabled,
|
||||
forced, or policied.
|
||||
- `PASS fail_open_policies`: no fail-open policy expressions detected.
|
||||
- `PASS project_id_backfill`: exact counts found zero `NULL project_id` rows in
|
||||
counted target tables.
|
||||
|
||||
Current blocker summary:
|
||||
|
||||
```text
|
||||
PASS=7 WARN=0 BLOCKED=1
|
||||
```
|
||||
|
||||
Updated exact counts:
|
||||
|
||||
| Table | Rows | NULL project_id |
|
||||
| --- | ---: | ---: |
|
||||
| `audit_logs` | 686 | 0 |
|
||||
| `awooop_mcp_tool_registry` | 4 | 0 |
|
||||
| `awooop_outbound_message` | 248 | 0 |
|
||||
| `awooop_projects` | 2 | 0 |
|
||||
| `awooop_run_state` | 126 | 0 |
|
||||
| `incidents` | 1524 | 0 |
|
||||
| `knowledge_entries` | 2103 | 0 |
|
||||
| `playbooks` | 220 | 0 |
|
||||
|
||||
## Remediation Order
|
||||
|
||||
1. Create or reconcile RLS roles.
|
||||
- Current production app user is `awoooi`; policy design must either grant it
|
||||
membership in `awooop_app` or update the application connection role before
|
||||
policies are enforced.
|
||||
- Do not create passworded LOGIN roles in a migration unless the K8s Secret
|
||||
rotation path is ready.
|
||||
- Use `scripts/ops/awooop-rls-role-bootstrap.sql` only after review, and run
|
||||
it manually as `postgres` or a `CREATEROLE` operator. It is intentionally
|
||||
outside `apps/api/migrations/` so Gitea auto-migration will not run it.
|
||||
2. Verify all DB access paths use `get_db()` / `get_db_context()` or otherwise set
|
||||
1. Verify all DB access paths use `get_db()` / `get_db_context()` or otherwise set
|
||||
`app.project_id` before queries.
|
||||
3. Apply policies first in staging or a canary DB.
|
||||
4. In production, enable one batch at a time.
|
||||
5. After each batch, run:
|
||||
2. Apply policies first in staging or a canary DB.
|
||||
3. In production, enable one batch at a time.
|
||||
4. After each batch, run:
|
||||
|
||||
```bash
|
||||
bash scripts/ops/awooop-rls-preflight.sh --exact-counts
|
||||
```
|
||||
|
||||
6. Validate AwoooP Runs, Approvals, Monitoring, Tickets, Cost, alert ingestion,
|
||||
5. Validate AwoooP Runs, Approvals, Monitoring, Tickets, Cost, alert ingestion,
|
||||
background workers, and TelegramGateway mirror paths.
|
||||
|
||||
## Do Not
|
||||
|
||||
Reference in New Issue
Block a user