Skip to content

Commit e95c357

Browse files
committed
feat(sec): finalize rbac, nav, observability slices
1 parent 98b6377 commit e95c357

20 files changed

+1065
-201
lines changed

docs/05-ui-ux-delta.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,26 @@
2727
- **Elevation:** Create shadow tokens for interactive surfaces (cards, modals) aligned with neo-brutalism outlines.
2828
- **Radius:** Maintain bold outlines but add `radius-sm` (4px) for chip components and `radius-lg` (16px) for cards.
2929

30+
### 3.1 Token Snapshot — 2025-10-31
31+
| Token | Value | Notes |
32+
| --- | --- | --- |
33+
| `brand.ink` | `#1F1F1F` | Primary copy color for Role Manager, nav links, and badges. |
34+
| `brand.panel` | `#FFF8F1` | Background for RBAC Role Manager container; meets 7:1 contrast against ink text. |
35+
| `brand.surface.info` | `#F2F4FF` | Applied to informational badges within nav IA flyouts. |
36+
| `brand.border.muted` | `#D9D3F4` | Outline for neutral stats in Role Manager roster. |
37+
| `brand.border.warning` | `#FFB020` | Moderator badge border; accessible against ink text. |
38+
| `brand.focus` | `#6C63FF` | Used for ring styles on search, skip-link, and nav buttons. |
39+
| `shadow-brand-sm` | `4px 4px 0px rgba(34, 34, 34, 0.12)` | Applied to summary cards and nav chips. |
40+
| `shadow-brand-lg` | `8px 8px 0px rgba(34, 34, 34, 0.18)` | Elevated Role Manager forms. |
41+
42+
Tokens are declared in `tailwind.config.js` and consumed within `src/components/admin/RoleManager.tsx` and `src/components/ui/NewNavbar.tsx` to ensure a single source of truth.
43+
3044
## 4. Accessibility Notes
3145
- All new interactive components must support keyboard navigation, focus-visible styles, and ARIA attributes.
3246
- Provide descriptive labels for toggles (e.g., fee coverage slider) and ensure error messages include guidance.
3347
- For events, include accessibility notes (wheelchair access, ASL availability) and ensure color-coded statuses have text equivalents.
3448
- Implement reduced motion mode for animations in reputation celebrations and feed transitions.
49+
- RBAC Role Manager exposes live search and roster list with `aria-live="polite"` status updates and keyboard-visible focus rings tied to `brand.focus`.
3550

3651
## 5. Responsive Behavior
3752
- **Mobile:** Sticky quick actions (Join Space, New Post) at bottom; collapsible filters for search and moderation queues.
@@ -42,3 +57,4 @@
4257
- Maintain component specs in Storybook (to be configured) with accessibility checklists.
4358
- Update `neobrutalismthemecomp.MD` with new tokens and examples.
4459
- Capture screenshots/GIFs for each new flow when feature flags progress to pilot.
60+
- Telemetry: `recordNavInteraction` logs `nav_interaction_total{target,from,variant,role}` from `NewNavbar`, enabling engagement panels on `dash_ops_rbac_v1`.

docs/06-data-model-delta.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
### Index & Policy Update — 2025-10-31
2828

2929
- Indexes: `space_members(role_id, status)`, `space_members(space_id, role_id)`, `spaces(visibility)`, `posts(space_id, status)`, `posts(space_id, published_at DESC)`, `comments(thread_root_id, created_at DESC)`, `reports(space_id, status)`, `reports(subject_type, subject_id)`.
30+
- 2025-10-31 Follow-up (`0021_sec_001_constraints_indexes.sql`): Added unique index `profile_roles_profile_role_idx`, composite moderation index `space_members_role_status_v2_idx`, refined post timeline index `posts_space_status_published_idx`, and `comments_thread_status_created_idx` to stabilize queue queries. Enforced canonical slug constraint `roles_slug_canonical_ck` to guarantee `normalize_role_slug` invariants.
3031
- Constraints: canonical slug check on `roles.slug`; composite PK enforced on `space_members`.
3132
- RLS: deny-by-default policies now depend on helper functions to gate CRUD by canonical role ladder across `spaces`, `space_members`, `space_rules`, `posts`, `post_versions`, `comments`, `reports`, `feature_flags`, `audit_logs`, `profile_roles`.
3233
| `donations` | Monetary contributions | `id`, `profile_id`, `target_type`, `target_id`, `amount`, `currency`, `fee_amount`, `donor_covers_fees`, `is_recurring`, `status`, `receipt_url`, `created_at` | Index on (`target_type`, `target_id`) |

docs/07-security-privacy.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727

2828
Full matrix with endpoint mapping maintained alongside Supabase policy definitions. Automated tests validate allow/deny paths per `/tests/security`.
2929

30-
**Admin Guard Hardening:** Unified admin API routes now delegate to `requireAdmin` in `src/lib/auth/require-admin.ts`, which resolves canonical roles, audits denials via `audit_logs`, and emits `authz_denied_count{resource,role,space,reason}`. Guard usage now extends to user management and gamification APIs, ensuring telemetry tags include `resource`, `role`, `space`, `reason` for Operations dashboards. RLS helper functions (`normalize_role_slug`, `user_space_role_at_least`, `highest_role_slug`) back deny-by-default policies across `spaces`, `space_members`, `space_rules`, `posts`, `post_versions`, `comments`, `reports`, `feature_flags`, and `audit_logs`.
30+
- Integration coverage refreshed on 2025-10-31: `tests/security/rbac-policies.test.ts` exercises the role/action/table matrix using Supabase service credentials. Route-level guards for admin user management are unit tested (`tests/unit/require-admin.test.ts`, `tests/unit/feature-flags-admin-route.test.ts`) and new permissions helpers are validated via `tests/unit/rbac-permissions.test.ts`.
3131

32-
**Runbook – RLS Denial Spike (2025-10-31):** If `authz_denied_count` surges, check Operations dashboard panel `op_rbac_denials` for `resource` + `space` tags. Use `/admin/audit` to confirm actor role assignments and `feature_flag_audit` for recent flag toggles. Validate helper functions are returning canonical slugs via Supabase SQL (`select public.highest_role_slug('<profile-id>'::uuid)`). Rollback: toggle `rbac_hardening_v1` off, apply migration `0020_sec_001_rls_policies.down.sql`, restore from PITR if required. Document incident in `/docs/operations/runbooks/rls-denial-spike.md` (to be created).
32+
**Admin Guard Hardening:** Unified admin API routes now delegate to `requireAdmin` in `src/lib/auth/require-admin.ts`, which resolves canonical roles, audits denials via `audit_logs`, and emits `authz_denied_count{resource,role,space,reason}`. Guard usage now extends to user management and gamification APIs, ensuring telemetry tags include `resource`, `role`, `space`, `reason` for Operations dashboards. RLS helper functions (`normalize_role_slug`, `user_space_role_at_least`, `highest_role_slug`) back deny-by-default policies across `spaces`, `space_members`, `space_rules`, `posts`, `post_versions`, `comments`, `reports`, `feature_flags`, and `audit_logs`. The role manager UI behind `rbac_hardening_v1` surfaces canonical badges, enforces audit logging on each mutation, and is covered by synthetic navigation tests plus axe scans.
33+
34+
**Runbook – RLS Denial Spike (2025-10-31):** If `authz_denied_count` surges, check Operations dashboard panel `op_rbac_denials` for `resource` + `space` tags. Use `/admin/audit` to confirm actor role assignments and `feature_flag_audit` for recent flag toggles. Validate helper functions are returning canonical slugs via Supabase SQL (`select public.highest_role_slug('<profile-id>'::uuid)`). Rollback: toggle `rbac_hardening_v1` off, apply migration `0020_sec_001_rls_policies.down.sql`, restore from PITR if required. Document investigation outcomes in `/docs/operations/runbooks/rls-denial-spike.md`.
3335

3436
## 3. Input Validation & Sanitization
3537
- Use Zod schemas for all API inputs, with centralized validation utilities.

docs/08-observability.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
| `crash_free_sessions` | % of sessions without fatal error | Gauge | `platform` |
2020
| `authz_denied_count` | Authorization failures | Counter | `resource`, `role`, `space` |
2121
| `flag_evaluation_latency_ms` | Feature flag evaluation | Histogram | `flag_key` |
22+
| `nav_interaction_total` | Nav hub clicks (flag cohorts) | Counter | `target`, `from`, `variant`, `role` |
2223
| `webhook_delivery_success_rate` | Webhook successes vs. attempts | Gauge | `event_type` |
2324
| `automod_trigger_count` | Automod actions per rule | Counter | `rule_type`, `space` |
2425

25-
> 2025-10-31: Added `admin_publish_duration_ms` internal histogram for staff tooling responsiveness and began emitting `content_publish_latency_ms` from `/api/admin/posts`. Structured logs now include `user_id_hash`, `space_id`, and feature flag context for audit correlation.
26+
> 2025-10-31: Added `admin_publish_duration_ms` internal histogram for staff tooling responsiveness and began emitting `content_publish_latency_ms` from `/api/admin/posts`. Structured logs now include `user_id_hash`, `space_id`, and feature flag context for audit correlation. `nav_interaction_total` now captures navigation hub engagement per flag cohort.
2627
2728
## 3. Tracing Strategy
2829
- Instrument Next.js route handlers and server components with OpenTelemetry.
@@ -38,6 +39,7 @@
3839
## 5. Dashboards
3940
- **Executive KPI Dashboard (`dash_exec_kpi_v1`):** Aggregates content latency (panels for `content_publish_latency_ms`, `admin_publish_duration_ms`), crash-free sessions, and donation funnel placeholders.
4041
- **Operations Dashboard (`dash_ops_rbac_v1`):** Displays `authz_denied_count` (tagged by `resource`, `role`, `space`), moderation backlog, feature flag toggles (joining `feature_flag_audit`), and Playwright synthetic status.
42+
- **Navigation Engagement Panel (`dash_ops_nav_v1`):** Breaks down `nav_interaction_total` by target hub, role, and variant (legacy vs `nav_ia_v1`).
4143
- **Commerce Dashboard:** Shows donation funnel, payout queue status, dispute rate.
4244
- **Events Dashboard:** Tracks registrations, attendance, revenue, NPS survey results.
4345
- **Reliability Dashboard:** SLO status, error budgets, incident history.
@@ -68,7 +70,7 @@
6870
- Adopt OpenTelemetry SDK for Next.js + Node workers; export to vendor (e.g., Grafana Cloud, Honeycomb).
6971
- Use Supabase Logflare integration for SQL audit, complement with custom metrics via functions.
7072
- Configure synthetic monitoring (Pingdom/Lighthouse CI) for home feed, space page, checkout flow.
71-
- Add Playwright synthetic tests for core user journeys with metrics logging.
73+
- Add Playwright synthetic tests for core user journeys with metrics logging. `tests/synthetic/observability.spec.ts` covers nav IA, admin flag guard, and publish route smoke flows (skipped when `PLAYWRIGHT_TEST_BASE_URL` undefined).
7274

7375
## 9. Runbooks
7476
- Create `/docs/operations/runbooks/` with scenario-specific guides (publish latency, payment failures, search outage).

docs/10-release-plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
| Flag Key | Purpose | Default | Owner | Notes |
55
| --- | --- | --- | --- | --- |
66
| `rbac_hardening_v1` | Locks down canonical role ladder, admin tooling | OFF | Security Lead | Staff-only until Phase-1 gate |
7-
| `nav_ia_v1` | Enables refreshed navigation IA + tokens | OFF | Design Lead | Staged rollout via staff cohort |
7+
| `nav_ia_v1` | Enables refreshed navigation IA + tokens | OFF | Design Lead | Staged rollout via staff cohort; nav telemetry recorded via `nav_interaction_total` |
88
| `observability_v1` | Surfaces observability UI surfaces | OFF | SRE Lead | Infra toggle, dashboards verified first |
99
| `spaces_v1` | Enables space creation, rules, membership | OFF | Product Lead | Phase 2 pilot with selected communities |
1010
| `content_templates_v1` | Activates new editors/templates | OFF | Content PM | Depends on `spaces_v1` |
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Runbook: RLS Denial Spike
2+
3+
**Last updated:** 2025-10-31
4+
5+
## 1. Detection
6+
- Alert `pd-sec-ops::rbac_denials_spike` triggers when `authz_denied_count` > 25/min tagged `resource=admin_users` or `resource=spaces`.
7+
- Operations dashboard panel `dash_ops_rbac_v1 :: RBAC Denials` shows trend by `resource`, `role`, `space` tags.
8+
- Synthetic check `observability synthetic journeys › admin flag console guard surfaces login` failing may indicate lockout.
9+
10+
## 2. Immediate Actions
11+
1. Confirm the spike in Grafana panel and correlate to recent deployments/flag toggles.
12+
2. Query Supabase audit logs:
13+
```sql
14+
select created_at, actor_role, action, reason, metadata
15+
from audit_logs
16+
where resource = 'admin_users'
17+
and created_at > now() - interval '1 hour'
18+
order by created_at desc;
19+
```
20+
3. Validate helper function output for affected profiles:
21+
```sql
22+
select highest_role_slug('<profile-id>'::uuid);
23+
```
24+
4. Check feature flag history for `rbac_hardening_v1` and related nav flags in `/admin/feature-flags` (audit entries are stored in `feature_flag_audit`).
25+
26+
## 3. Mitigation
27+
- If regression tied to new policies, toggle `rbac_hardening_v1` OFF for all but security staff.
28+
- Re-run policy tests via `npm run test -- tests/security/rbac-policies.test.ts` in staging.
29+
- If helper function bug, apply hotfix migration or revert via `supabase/migrations/0020_sec_001_rls_policies.down.sql` followed by redeploy.
30+
- For false positives (expected denials), adjust alert threshold temporarily via Grafana annotations and document rationale.
31+
32+
## 4. Communication
33+
- Update #ops-telemetry Slack channel with incident timeline and current mitigation steps.
34+
- If admin access degraded for staff, notify affected cohorts and provide estimated resolution time.
35+
- Log incident in `/docs/operations/incidents/YYYY-MM-DD-<summary>.md` once stabilized.
36+
37+
## 5. Recovery & Verification
38+
- After mitigation, re-enable `rbac_hardening_v1` for staff cohort and monitor `authz_denied_count` for 30 minutes.
39+
- Ensure Playwright synthetic journeys pass in CI (`tests/synthetic/observability.spec.ts`).
40+
- Capture metrics snapshot and attach to incident record.
41+
42+
## 6. Postmortem Checklist
43+
- Identify root cause (policy regression, role sync failure, guard bug).
44+
- Add automated test coverage if gap discovered.
45+
- Update documentation and backlog items if new work required.
46+
- Close incident with summary and action items in weekly progress log.

docs/progress/weekly-2025-10-24.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Weekly Progress — 2025-10-24
2+
3+
## Shipped Tickets
4+
- SEC-001: RBAC/RLS hardening (Role Manager UI, policy migrations, guard telemetry) behind `rbac_hardening_v1`.
5+
- UX-010: Navigation IA & design tokens applied to top nav and admin role tooling behind `nav_ia_v1`.
6+
- OBS-100: Observability baseline instrumentation (nav interaction metrics, synthetic journeys, structured logging enrichments) behind `observability_v1` UI surfaces.
7+
8+
## Flags Enabled
9+
- `rbac_hardening_v1`: Staff-only in staging for Role Manager validation.
10+
- `nav_ia_v1`: Staff-only cohort to evaluate hub engagement.
11+
- `observability_v1`: SRE sandbox only; dashboards linked but UI gates remain off for general users.
12+
13+
## KPI Deltas
14+
- `authz_denied_count` trending flat (≤2/min) after Role Manager smoke tests.
15+
- `nav_interaction_total` baseline captured for staff navigation (~35 clicks/hour) to tune IA.
16+
- `content_publish_latency_ms` P95 steady at 4.2s post-instrumentation.
17+
18+
## New Risks / Assumptions
19+
- A-009: Flag ownership clarified (Design Lead for nav IA, SRE Lead for observability); update kept open for Phase-1 tracking.
20+
- Monitoring gap: Playwright synthetic suite depends on `PLAYWRIGHT_TEST_BASE_URL`; missing env will skip checks—documented for CI configuration.
21+
22+
## Next Targets
23+
- Harden Storybook coverage for tokenized components (SpaceHeader, TemplatePickerModal, DonationWidget, EventCard).
24+
- Expand RLS integration tests to cover reports/audit log mutations with moderator/admin roles.
25+
- Connect dashboards to production Grafana workspace and validate alert routing (`pd-sec-ops`, `ops-telemetry`).

0 commit comments

Comments
 (0)