mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-18 15:29:36 +00:00
Program F — Multi-Tenancy RLS (Row-Level Security):
alembic 20260417_0002_add_rls.py: Enables RLS on 23 tenant-scoped tables.
database_rls.py: set_tenant_context() helpers for SET LOCAL app.tenant_id.
middleware/tenant_rls.py: Extracts tenant_id from JWT on every request.
Default-deny when no context. PostgreSQL only (CI safe on SQLite).
Result: OWASP A01:2025 — access control enforced at DB layer.
Program G — Idempotency Standard:
models/idempotency_key.py: IdempotencyKey table with TTL + SHA256 hash.
services/idempotency_service.py: get_existing/store with request fingerprint.
middleware/idempotency.py: HTTP middleware on POST/PUT/PATCH.
Result: Duplicate side effects prevented on retry.
Program E — Persistent Durable Execution:
models/durable_checkpoint.py: DurableCheckpoint with sequence_num + status.
services/durable_runtime.py: start_run/checkpoint/complete/resume/list_incomplete.
Result: Workflows survive crashes — resume from last persisted checkpoint.
Program K — OpenTelemetry:
observability/otel.py: init/span/inject_correlation_id with graceful
degradation when OTel packages absent.
openclaw/gateway.py: Wraps execute() in span, binds correlation_id to
trace_id. Bridge between business correlation and production observability.
Program J — Release Gate Hardening:
docs/governance/release-gates.md: Documents 3 mandatory gates.
.github/workflows/dealix-ci.yml: Adds release_readiness_matrix as CI step.
release_readiness_matrix.py: Updated to check 41/41 components.
Verification:
architecture_brief.py: 40/40 PASS
release_readiness_matrix.py: 41/41 PASS
https://claude.ai/code/session_01W1rJthWDkasijTdXCfxVHs
50 lines
1.6 KiB
Python
50 lines
1.6 KiB
Python
"""Tenant context helpers for PostgreSQL Row-Level Security (RLS).
|
|
|
|
When RLS policies are enabled, each session must set:
|
|
SET LOCAL app.tenant_id = '<tenant-uuid>'
|
|
|
|
This must happen before any tenant-scoped query in the session.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
from uuid import UUID
|
|
|
|
from sqlalchemy import text
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
|
|
async def set_tenant_context(session: AsyncSession, tenant_id: str | UUID | None) -> None:
|
|
"""Set RLS tenant context for the current session.
|
|
|
|
Call at the start of every request handler that touches tenant-scoped data.
|
|
Uses SET LOCAL so it only affects the current transaction.
|
|
"""
|
|
if tenant_id is None:
|
|
# default-deny: no tenant context = no rows returned
|
|
await session.execute(text("SET LOCAL app.tenant_id = ''"))
|
|
return
|
|
|
|
tid = str(tenant_id)
|
|
# Sanitize: only valid UUID format allowed
|
|
try:
|
|
UUID(tid)
|
|
except (ValueError, TypeError):
|
|
await session.execute(text("SET LOCAL app.tenant_id = ''"))
|
|
return
|
|
|
|
await session.execute(text(f"SET LOCAL app.tenant_id = '{tid}'"))
|
|
|
|
|
|
async def clear_tenant_context(session: AsyncSession) -> None:
|
|
"""Clear tenant context (forces default-deny on subsequent queries)."""
|
|
await session.execute(text("SET LOCAL app.tenant_id = ''"))
|
|
|
|
|
|
async def get_current_tenant(session: AsyncSession) -> Optional[str]:
|
|
"""Get current tenant_id from session context."""
|
|
result = await session.execute(text("SELECT current_setting('app.tenant_id', true)"))
|
|
val = result.scalar()
|
|
return val if val else None
|