Watch
1
0
Fork
You've already forked RedFlag
0

raf: publish — relative links, auth audit section, component tables

This commit is contained in:
Fimeg 2026-06-11 17:47:21 -04:00
commit 3a8ffe1643
4 changed files with 51 additions and 9 deletions

View file

@ -53,8 +53,8 @@ server/
| Admin | `admin-only` | `WebAuthMiddleware + AdminRoleMiddleware` | `/api/v1/admin/*` |
**Cross-references:**
- [security/01-trust-boundaries](security/01-trust-boundaries.md) (full trust boundary matrix)
- [security/02-authentication-stack](security/02-authentication-stack.md) (auth layers)
- [security/01-trust-boundaries](../security/01-trust-boundaries.md) (full trust boundary matrix)
- [security/02-authentication-stack](../security/02-authentication-stack.md) (auth layers)
---
@ -71,7 +71,7 @@ server/
- 055: process explorer tables (`agent_process_snapshots`, `agent_processes`, `agent_process_related`)
**Cross-references:**
- [deployment/01-docker-stack](deployment/01-docker-stack.md) (database configuration)
- [deployment/01-docker-stack](../deployment/01-docker-stack.md) (database configuration)
- [testing/01-test-pyramid](testing/01-test-pyramid.md) (migration test coverage)
---
@ -131,7 +131,7 @@ func DownloadAgent(w http.ResponseWriter, r *http.Request) {
**Cross-references:**
- [flows/03-agent-upgrade](flows/03-agent-upgrade.md) (agent download flow)
- [security/04-machine-binding](security/04-machine-binding.md) (download authentication)
- [security/04-machine-binding](../security/04-machine-binding.md) (download authentication)
**Known issues:**
- BUG-003: `version="latest"` doesn't match any signed package → signature header not set
@ -170,17 +170,19 @@ func DownloadAgent(w http.ResponseWriter, r *http.Request) {
| NonceService | `services/update_nonce.go` | Replay attack prevention (update nonces) |
| TimezoneService | `services/timezone.go` | Time handling for distributed agents |
| ProcessHandler | `api/handlers/processes.go` | On-demand process scan endpoints (trigger, report, list, detail) |
| RouteAuditor | `routeaudit/auditor.go` | Boot-time audit: every route carries its boundary's auth or the server refuses to start |
| RetentionService | `services/retention.go` | Scheduled pruning of append-only history tables (metrics/events/audit horizons, operator-tunable, 0 = keep forever) |
---
## Cross-References
- **HTTP API** → [security/01-trust-boundaries](security/01-trust-boundaries.md)
- **Database** → [deployment/01-docker-stack](deployment/01-docker-stack.md)
- **HTTP API** → [security/01-trust-boundaries](../security/01-trust-boundaries.md)
- **Database** → [deployment/01-docker-stack](../deployment/01-docker-stack.md)
- **Command signing** → [verification/01-signing-pipeline](verification/01-signing-pipeline.md)
- **Binary distribution** → [flows/03-agent-upgrade](flows/03-agent-upgrade.md)
- **Scheduler** → [flows/05-capability-advertisement](flows/05-capability-advertisement.md)
---
*Last reviewed: 2026-06-10*
*Last reviewed: 2026-06-11*

View file

@ -24,11 +24,20 @@ web/src/
│ ├── SecuritySettings, Settings, settings/, RateLimiting
│ └── Setup, Login, TokenManagement
├── components/
│ ├── primitives/ # SortableTable, StatusBadge, SeverityBadge, command primitives
│ ├── primitives/ # FilterBar, SearchInput, FilterDropdown, FilterPill, FilterCountButton,
│ │ # SortableTable, StateBadge (StatusBadge/SeverityBadge), CommandCard,
│ │ # CommandStatusBadge, Modal, PageState, Pagination, StatCard,
│ │ # ScreenshotCard, MetricItem, ProcessTable
│ ├── security/ # Security health panels
│ ├── DependencyClosureTree, VulnerabilityList
│ ├── ProcessesTab, ProcessDetailModal
│ └── AgentHealth, HistoryTimeline, AttentionPanel, ...
├── hooks/ # Stateful composition over primitives
│ ├── useFilterUrl # URL-synced filter state (useFilterUrl.ts)
│ ├── useQueryParser # key:value query string parsing (useQueryParser.ts)
│ ├── useMultimodalFilter # Composed filter: search box + filter pills + URL (useMultimodalFilter.ts)
│ ├── useDebounce # Generic debounce (useDebounce.ts)
│ └── useColumnSort # Reusable column sort state (useColumnSort.tsx)
├── lib/
│ ├── api.ts # API client (web-auth boundary)
│ ├── polling.ts # POLL.* constants — all intervals centralized
@ -43,6 +52,7 @@ web/src/
## Conventions
- **One way to render state.** Status and severity render through `StatusBadge` / `SeverityBadge` — never ad-hoc colored spans. Tables that sort use `SortableTable`.
- **One way to filter.** Filter state syncs to URL via `useFilterUrl`; free-text search uses a local `useState` + `useDebounce` pair (instant feedback in the input, debounced value for API calls). Compose both into a `FilterBar`. No ad-hoc `useState` chains for filter state.
- **Polling intervals** come from `POLL.*` in `lib/polling.ts` — no hardcoded milliseconds in components.
- **Render the divergence, not the union** (framework §11.8): when agent-reported and server-expected state differ, the UI shows the difference, it does not paper over it.
- All routes sit behind `WebAuthMiddleware` (admin routes additionally behind `AdminRoleMiddleware`) — see [security/01-trust-boundaries](security/01-trust-boundaries.md).

View file

@ -94,6 +94,12 @@
| `web/src/pages/Settings.tsx` | Settings pages |
| `web/src/pages/Dashboard.tsx` | Dashboard |
| `web/src/components/AgentHealth.tsx` | Health monitoring |
| `web/src/components/primitives/` | UI primitive library — FilterBar, SearchInput, FilterDropdown, FilterPill, FilterCountButton, SortableTable, StateBadge, CommandCard, CommandStatusBadge, Modal, PageState, Pagination, StatCard, ScreenshotCard, MetricItem, ProcessTable |
| `web/src/hooks/useFilterUrl.ts` | URL-synced filter state |
| `web/src/hooks/useQueryParser.ts` | key:value query string parser |
| `web/src/hooks/useMultimodalFilter.ts` | Composed multimodal filter |
| `web/src/hooks/useDebounce.ts` | Generic debounce |
| `web/src/hooks/useColumnSort.tsx` | Reusable column sort |
| `web/src/hooks/useCommands.ts` | TanStack Query hook |
| `web/src/hooks/useAgents.ts` | Agent data hook |

View file

@ -143,6 +143,30 @@ Ties to SEC-012 (renewal atomicity): the server side is now fully transactional;
---
## Structural Enforcement: Boot-Time Route Audit
BUG-013 was a one-off fix; the route audit (`server/internal/routeaudit/`) is the
structural answer to that class. At startup the server walks every registered route
in the Gin engine and verifies each handler chain carries the auth middleware its
trust boundary requires. Any route that lacks auth and is not on the explicit public
allowlist refuses boot: `[CRITICAL] route_missing_auth`, exit 1. An unauthenticated
endpoint cannot ship by omission — it can only exist as a reviewed line in
`PublicPathSet`.
**Classification is by code-pointer identity, not symbol name.** Each trust boundary
has exactly one middleware instance, created once in `main`, used at every route, and
registered with the auditor (`RegisterAuth`). Name-based matching was tried and
retired: compiler inlining renames closure symbols (missing real middleware), and
substring matching can silently accept a colliding name as an auth boundary. Pointer
identity over shared instances fails loudly in the safe direction — a stray fresh
constructor call or unregistered wrapper flags its routes at boot instead of passing
them silently.
**Cross-references:**
- [core/01-ethos](core/01-ethos.md) (principle #2: no unauthenticated endpoints)
---
## Doctrine: Pull-Only Agent Channel
The agent↔server control channel is **pull-only**. The agent polls; the server never
@ -175,4 +199,4 @@ bounded by what agents choose to fetch and verify.
---
*Last reviewed: 2026-05-26*
*Last reviewed: 2026-06-11*