raf: publish — relative links, auth audit section, component tables
This commit is contained in:
parent
a4d585c79c
commit
3a8ffe1643
4 changed files with 51 additions and 9 deletions
|
|
@ -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*
|
||||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
Loading…
Reference in a new issue