- Implemented BunPackageNormalizer to deduplicate packages by name and version. - Created BunProjectDiscoverer to identify Bun project roots in the filesystem. - Added project files for the Bun analyzer including manifest and project configuration. - Developed comprehensive tests for Bun language analyzer covering various scenarios. - Included fixture files for testing standard installs, isolated linker installs, lockfile-only scenarios, and workspaces. - Established stubs for authentication sessions to facilitate testing in the web application.
173 lines
4.7 KiB
Markdown
173 lines
4.7 KiB
Markdown
# Findings Ledger RLS Migration Guide
|
||
|
||
> **Task:** DEVOPS-LEDGER-TEN-48-001-REL
|
||
> **Contract:** [CONTRACT-FINDINGS-LEDGER-RLS-011](../../contracts/findings-ledger-rls.md)
|
||
> **Applies to:** PostgreSQL 16+ with Findings Ledger schema
|
||
|
||
## Overview
|
||
|
||
Migration `007_enable_rls.sql` enables Row-Level Security (RLS) on all Findings Ledger tables, implementing tenant isolation at the database level. This document covers deployment procedures for release pipelines and air-gapped environments.
|
||
|
||
## Prerequisites
|
||
|
||
- PostgreSQL 16 or later
|
||
- All prior migrations applied (001–006)
|
||
- Service accounts configured with appropriate roles
|
||
|
||
## Migration Files
|
||
|
||
| File | Purpose | SHA256 |
|
||
|------|---------|--------|
|
||
| `007_enable_rls.sql` | Apply RLS policies | (generated at build time) |
|
||
| `007_enable_rls_rollback.sql` | Revert RLS policies | (generated at build time) |
|
||
| `007_enable_rls.manifest.json` | Metadata for offline-kit | (generated at build time) |
|
||
|
||
## Protected Tables
|
||
|
||
The migration enables RLS and creates tenant isolation policies on:
|
||
|
||
1. `ledger_events`
|
||
2. `ledger_merkle_roots`
|
||
3. `findings_projection`
|
||
4. `finding_history`
|
||
5. `triage_actions`
|
||
6. `ledger_attestations`
|
||
7. `orchestrator_exports`
|
||
8. `airgap_imports`
|
||
|
||
## Deployment Procedures
|
||
|
||
### Standard Pipeline Deployment
|
||
|
||
The CI workflow at `.gitea/workflows/findings-ledger-ci.yml` handles migration validation automatically:
|
||
|
||
1. Applies prerequisites (001–006)
|
||
2. Applies RLS migration (007)
|
||
3. Validates RLS configuration
|
||
4. Tests rollback capability
|
||
5. Verifies idempotency
|
||
|
||
### Manual Deployment
|
||
|
||
```bash
|
||
# 1. Connect to database
|
||
psql -h $PGHOST -p $PGPORT -U $PGUSER -d $PGDATABASE
|
||
|
||
# 2. Apply migration
|
||
\i migrations/007_enable_rls.sql
|
||
|
||
# 3. Validate
|
||
SELECT tablename, rowsecurity
|
||
FROM pg_tables
|
||
WHERE schemaname = 'public'
|
||
AND tablename IN (
|
||
'ledger_events', 'ledger_merkle_roots', 'findings_projection',
|
||
'finding_history', 'triage_actions', 'ledger_attestations',
|
||
'orchestrator_exports', 'airgap_imports'
|
||
);
|
||
-- All should show rowsecurity = true
|
||
```
|
||
|
||
### Air-Gapped Deployment
|
||
|
||
1. **Export migration bundle**
|
||
```bash
|
||
# After CI passes, download the migration artifact
|
||
gh run download -n findings-ledger-migrations
|
||
```
|
||
|
||
2. **Transfer to air-gapped environment**
|
||
- Copy `out/findings-ledger/offline-kit/` to target host
|
||
- Verify SHA256 checksums match manifest
|
||
|
||
3. **Apply migration**
|
||
```bash
|
||
cd /path/to/offline-kit/migrations
|
||
# Verify checksums
|
||
sha256sum -c 007_enable_rls.manifest.json
|
||
|
||
# Apply
|
||
psql -f 007_enable_rls.sql
|
||
```
|
||
|
||
4. **Validate using RlsValidationService**
|
||
```bash
|
||
dotnet run --project tools/LedgerReplayHarness \
|
||
-- --connection "$LEDGER_DB" --validate-rls-only
|
||
```
|
||
|
||
## Rollback Procedure
|
||
|
||
If issues are encountered, rollback is safe and non-destructive:
|
||
|
||
```bash
|
||
psql -f migrations/007_enable_rls_rollback.sql
|
||
```
|
||
|
||
The rollback:
|
||
- Disables RLS on all 8 tables
|
||
- Drops tenant isolation policies
|
||
- Removes the `findings_ledger_app` schema and tenant function
|
||
- Does NOT drop the `findings_ledger_admin` role (preserves other grants)
|
||
|
||
## Validation Checklist
|
||
|
||
After applying the migration, verify:
|
||
|
||
- [ ] All 8 tables have `relrowsecurity = true` in `pg_class`
|
||
- [ ] All 8 tenant isolation policies exist in `pg_policies`
|
||
- [ ] Function `findings_ledger_app.require_current_tenant()` exists
|
||
- [ ] Application can connect and query with tenant context
|
||
- [ ] `RlsValidationService.ValidateAsync()` returns `IsCompliant = true`
|
||
|
||
## Tenant Context Requirements
|
||
|
||
After RLS is enabled, all queries must set tenant context:
|
||
|
||
```sql
|
||
-- Set tenant before querying
|
||
SELECT set_config('app.current_tenant', 'tenant-123', false);
|
||
|
||
-- Now queries are tenant-scoped
|
||
SELECT * FROM ledger_events; -- Only returns tenant-123 data
|
||
```
|
||
|
||
The `LedgerDataSource.OpenConnectionAsync(tenantId, ...)` handles this automatically for application code.
|
||
|
||
## Admin Bypass
|
||
|
||
For migrations and cross-tenant admin operations, use the `findings_ledger_admin` role:
|
||
|
||
```sql
|
||
SET ROLE findings_ledger_admin;
|
||
-- Queries now bypass RLS
|
||
```
|
||
|
||
## Metrics & Observability
|
||
|
||
After migration, monitor:
|
||
- `ledger_connection_opened_total{role="tenant"}` - Connection count with tenant context
|
||
- `ledger_connection_opened_total{role="system"}` - Admin/migration connections
|
||
- RLS violation errors in application logs
|
||
|
||
## CI Workflow Integration
|
||
|
||
The migration is validated in every CI run via:
|
||
|
||
```yaml
|
||
# .gitea/workflows/findings-ledger-ci.yml
|
||
jobs:
|
||
migration-validation:
|
||
# Tests apply → validate → rollback → re-apply cycle
|
||
```
|
||
|
||
## Related Documents
|
||
|
||
- [Tenant Isolation & Redaction](../tenant-isolation-redaction.md)
|
||
- [Findings Ledger Deployment](../deployment.md)
|
||
- [Offline Kit Operations](../../../24_OFFLINE_KIT.md)
|
||
|
||
---
|
||
|
||
*Created 2025-12-06 for DEVOPS-LEDGER-TEN-48-001-REL*
|