5 Commits

Author SHA1 Message Date
rcourtman 78301b91ed Teach route checks and contracts about RequireOrgAdmin
The route inventory treated RequireOrgAdmin routes as unauthenticated
"bare" routes, and the agent diagnostics contract and the API
reference anchors still named RequireAdmin for routes that now opt
into organization authority. The security-privacy contract still said
org managers receive reportingRead through ensureAdminSession; it now
names the org-bound routes' check and records that instance
administration refuses organization owners. The agent-lifecycle
contract notes that agent routes declare that authority explicitly.
2026-10-17 10:24:15 +01:00
rcourtman 6f97d2a0bc docs: describe the token authority rules that now ship
Follows the token authority fixes. The API reference now says:
- agent uninstall is a collector's own-token removal, or an admin session;
- AI narration of reports needs ai:execute from API-token callers, for
  single and fleet reports, and otherwise falls back to the deterministic
  summary;
- API-token callers manage only the tokens in their own organizations,
  and only an instance-wide token can create, edit, rotate or delete
  another instance-wide token;
- quick setup that would change credentials needs an instance-wide
  token from API-token callers.

Adds the missing entry for POST /api/security/tokens/<id>/rotate, which
the regenerate entry already points scoped tokens to.

test_api_reference_routes.py pins each statement to the code that
enforces it, so the reference and the gates cannot drift apart. Each pin
fails when the code or the reference is reverted.

Contract-Neutral: Customer docs corrected to match shipped behaviour; no runtime, API or contract change.
2026-10-11 20:33:40 +01:00
rcourtman a65e18d9b3 docs: state the scopes for token regeneration and resource links
Follows the token scope fixes. POST /api/security/regenerate-token now
needs an instance-wide full-access token from API-token callers and
replaces every stored token; the reference says so and points scoped
tokens at the per-token rotate route. POST /api/resources/{id}/link,
/unlink and /report-merge need monitoring:write.

test_api_reference_routes.py pins each of these to the code that
enforces it, so the reference and the gates cannot drift apart again.
Each pin fails when the code or the reference is reverted.

Contract-Neutral: Customer docs corrected to match shipped behaviour; no runtime, API or contract change.
2026-10-11 16:34:02 +01:00
rcourtman 66d4239307 docs: stop labelling free Patrol routes as Pro
The API reference marked the Patrol stream, manual run, acknowledge,
snooze, suppress, suppressions and dismissed routes "(Pro)" and promised
a 402 when unlicensed. None of them is licence-gated: Patrol and
managing its findings are free (ai_patrol is a free feature, and the
frontend offers these controls on every plan). Only governed fixes need
Pro. The routes now show the scope they actually require and the
reference says what Community gets, including the one-full-run-per-hour
cap on manual runs.

Also corrects the findings routes: reinvestigate is Pro and needs the
ai_autofix entitlement and a Patrol mode above Watch only, and
reapprove is retired and always answers 410.

scripts/tests/test_api_reference_routes.py gains checks that a Patrol
route documented without a paid label has no licence wrapper in its
registration, and that reapprove is documented as retired. Each fails
when its claim is reverted.

Contract-Neutral: Customer docs corrected to match shipped behaviour; no runtime, API or contract change.
2026-10-11 16:02:29 +01:00
rcourtman 9031dd949c docs: correct API reference auth labels and add missing routes
Audited every HTTP route the server registers against docs/API.md.
Where a documented route and the code disagreed, or an integrator-facing
route was missing, the reference now matches the code.

- Auth and scope labels: notifications, SSO providers, license
  activate/clear, security reset-lockout, availability targets, agent
  profiles (every method needs settings:write for tokens), relay settings
  and the resource metadata routes (no admin requirement).
- Behaviour: POST /api/notifications/test targets one channel per request,
  the storage detail route is GET /api/storage/{storageId} (not a list at /api/storage/), token
  rename-only updates are accepted, validate-token moved out of the Audit
  Log (Pro) section because it has no licence gate, and the setup script
  is public.
- Retired routes: /api/ai/remediation/execute and /rollback always answer
  410 Gone, as approve already documented.
- Newly documented: GET /api/ai/patrol/runs/{id}, POST
  /api/availability-history, POST /api/agents/agent/{id}/allow-reenroll,
  PUT /api/truenas/connections/{id} and its /test route.

scripts/tests/test_api_reference_routes.py pins the corrections to the
router so later drift fails a test: every scope named on a route line must
exist in pkg/auth/scopes.go, the newly documented routes must exist in the
router, and the retired routes must say 410. It fails on the previous
reference and passes on this one.

Each doc is mirrored under frontend-modern/public/docs and updated in
both places. Labels where the docs and the code disagree about licence
gating are left alone; that needs a product decision, not a doc edit.

Contract-Neutral: Customer docs corrected to match shipped behaviour; no runtime, API or contract change.
2026-10-11 15:13:29 +01:00