Commit Graph
100 Commits
Author SHA1 Message Date
mrhid6 19383abaf8 fix(auth): final-review MFA fixes F1 F2 F3 F5 F7 and drop Ticket.Attempts
Chart Release / chart (push) Successful in 18s
Server Deploy / deploy (push) Successful in 5m51s
- OIDC sessions minted through saveSignIn with AMR oidc and StepUpAt
- passwordless passkey uses ValidateDiscoverableLogin with owner-handle check
- TOTP replay guard burns the matched step, not the current one
- enrol-only tickets refused once the user already has a factor
- bootstrap owner session minted through mintSession
2026-09-16 14:26:42 +00:00
mrhid6 dcdfd3ce52 test(mfa): fix step-up test to assert the fresh-session path 2026-09-16 14:20:42 +00:00
mrhid6 142b99e408 test(mfa): end-to-end coverage, OpenAPI and documentation 2026-09-16 14:18:39 +00:00
mrhid6 14e9db606a fix(mfa): wire up webauthn step-up routes
The missing /me/step-up/webauthn/begin and /finish were a plan defect,
not an acceptable gap: a user whose only factor is a passkey was
offered only recovery codes for step-up, burning one every ten
minutes. Adds the handlers in package auth (session-authenticated,
not themselves behind RequireStepUp, modeled on
HandleMFAWebAuthnBegin/finishAssertion) and registers both routes
behind the same RateLimitAuth() as /me/step-up. StepUpModal now offers
"Use passkey" when the server names webauthn and the browser supports
WebAuthn.
2026-09-16 09:44:41 +00:00
mrhid6 3e341b17ec feat(web): step-up modal and MFA settings controls
Adds the global re-authentication modal for guarded routes and the
owner/admin MFA controls on the settings page.

request() in lib/api.ts now intercepts a 403 step_up_required response,
awaits re-authentication through a callback registered by StepUpModal
(lib/stepup.ts), and retries the original request exactly once. The
modal offers TOTP, recovery code and password, since the webauthn
step-up routes (/me/step-up/webauthn/begin and /finish) are not
registered server-side yet; it omits the passkey option rather than
calling a route that does not exist.

me.stepUp posts one factor to /api/me/step-up. The settings page gains
an owner-only "Require MFA" toggle and the members table gains an MFA
column and a "Reset MFA" action, both routed through the existing
PUT /api/settings and DELETE /api/org/users/:id/mfa.
2026-09-16 09:33:50 +00:00
mrhid6 32fd11cde7 feat(web): account security page and MFA enrolment wizard 2026-09-16 09:26:54 +00:00
mrhid6 26825841fa feat(web): MFA and passkey sign-in on the login page 2026-09-16 09:22:18 +00:00
mrhid6 d8597ee3ae feat(mfa): require_mfa policy, sign-in rate limit and MFA column 2026-09-16 09:14:16 +00:00
mrhid6 f87626cf17 feat(mfa): account MFA management, passkey registration and step-up 2026-09-16 09:08:24 +00:00
mrhid6 bd0639acfa fix(mfa): refuse rather than panic when RequireStepUp sees no session 2026-09-16 09:03:22 +00:00
mrhid6 e2ff0dace9 feat(mfa): step-up re-authentication on sensitive actions 2026-09-16 09:01:19 +00:00
mrhid6 d54d8971b2 feat(mfa): passwordless passkey sign-in 2026-09-16 08:58:26 +00:00
mrhid6 14a1cdb2b0 feat(mfa): passkey verification as a second factor 2026-09-16 08:48:39 +00:00
mrhid6 1445af11ab fix(mfa): mint session before deleting ticket, collapse dead invalid_code branch 2026-09-16 08:43:53 +00:00
mrhid6 3fa469c303 feat(mfa): forced TOTP enrolment at sign-in 2026-09-16 08:41:56 +00:00
mrhid6 2d75832ceb feat(mfa): second-factor sign-in with TOTP and recovery codes 2026-09-16 08:39:48 +00:00
mrhid6 dfcfd1d3e2 fix(mfa): make ticket attempt count atomic via Redis INCR 2026-09-16 08:37:07 +00:00
mrhid6 9c60adc836 feat(mfa): pending-login ticket store 2026-09-16 08:34:57 +00:00
mrhid6 330c326fb5 fix(mfa): key TOTP replay guard on time step, not the code 2026-09-16 08:33:02 +00:00
mrhid6 25541345a8 feat(mfa): TOTP secrets, recovery codes and factor lookup 2026-09-16 08:30:55 +00:00
mrhid6 b78a9b3832 feat(mfa): user_mfa and webauthn_credentials collections 2026-09-16 08:27:54 +00:00
mrhid6 9aee0a61aa chore(server): bump vantage-shared to v0.7.0 for require_mfa 2026-09-16 08:22:08 +00:00
mrhid6 0aabb664e2 docs: implementation plan for MFA on local sign-in 2026-09-16 08:15:46 +00:00
mrhid6 e0468aa7b9 docs: design for MFA on local sign-in (TOTP, passkeys, step-up) 2026-09-15 15:48:59 +00:00
mrhid6 fbcf436ef6 feat: show Ubuntu phased updates apart and leave them out of pending counts
Chart Release / chart (push) Successful in 29s
Server Deploy / deploy (push) Successful in 5m9s
apt lists phased updates as upgradable while an upgrade defers them until
Ubuntu selects the host, so a freshly patched server kept reporting pending
updates. The agent now flags them; the server stores the flag and leaves them
out of patch run counts, and the server page shows them in their own section.
2026-09-15 14:55:30 +00:00
mrhid6 0e464c4bb8 fix(web): wrap long patch output lines instead of widening the run table
Chart Release / chart (push) Successful in 20s
Server Deploy / deploy (push) Successful in 1m14s
2026-09-15 14:27:42 +00:00
mrhid6 fc10575b08 fix: require a 2 minute boot time change before counting a patch reboot
Chart Release / chart (push) Successful in 36s
Server Deploy / deploy (push) Successful in 4m19s
Windows reports boot time as now minus uptime, which drifts by a second or so
between reports. A static report sent in the grace period before the reboot
could read as a changed boot and mark a server still owing a reboot as failed.
2026-09-15 14:09:34 +00:00
mrhid6 3f2d20868e fix(patching): final review fixes
Chart Release / chart (push) Successful in 19s
Server Deploy / deploy (push) Successful in 6m12s
- no dispatch in the last 15 minutes of a window; no-result timeout from dispatch time
- per-server output moves to patch_run_outputs (16MB document limit)
- reboot proven by a changed boot time; RebootTimeout 45m, ResultGrace 20m
- window update and delete are server-scoped against the policies using them
- scheduler puts the claim back on an error after it, so the next tick retries
- cancelled runs with failures alert; MCP apply_updates audits per server
- apply-updates 503 body documented; openapi regenerated
- web: cleared numeric fields no longer save as 0; Run now asks for confirmation
2026-09-15 13:49:28 +00:00
mrhid6 3ecea7c39f feat(web): show patch policy coverage on servers and open the run after Apply updates 2026-09-15 13:23:19 +00:00
mrhid6 68c613fd40 feat(web): patch run detail page with per-server output 2026-09-15 12:24:17 +00:00
mrhid6 70c239021d feat(web): patching page with policies, windows and runs 2026-09-15 11:19:01 +00:00
mrhid6 3a7618f82f feat(web): maintenance window and patch policy editors 2026-09-15 10:59:06 +00:00
mrhid6 7809419202 fix(web): anchor patch agent version regex to mirror server parseVersion 2026-09-15 09:43:56 +00:00
mrhid6 59e7ef63fe feat(web): patching API client, status vocabulary and navigation 2026-09-15 09:41:07 +00:00
mrhid6 b5bbf28c63 feat: patching REST API, patching scope, run IDs from apply-updates and MCP 2026-09-15 09:31:51 +00:00
mrhid6 17c9f813fc fix: patchsched hasActiveRun must not treat a real DB error as no active run 2026-09-15 09:19:51 +00:00
mrhid6 139658864b feat: patch scheduler loop; record patch results and verify reboots from the agent stream 2026-09-15 09:17:27 +00:00
mrhid6 1bb2ba7f2b fix: patch run dispatch - per-server contexts, cancel race, result command guard
Fix round 1 review findings on the patch run service:
- advanceRun no longer runs every server's dispatch claim and failed-send
  reset on the caller's shared short context; each gets its own fresh
  patchCtx(), and a failed reset write is logged instead of discarded.
- The dispatch claim (queued/waiting_offline -> patching) now also requires
  the run to still be status running with no cancelled_at, closing a race
  where a tick that loaded the run just before CancelPatchRun wrote
  cancelled_at could still dispatch.
- RecordPatchResult's write is now guarded on command_id too, so a late
  result for a superseded command cannot land on a re-dispatched attempt.
2026-09-15 09:09:12 +00:00
mrhid6 fef886c93b feat: patch run service - dispatch, results, reboot verification, cancel, alerts, retention 2026-09-15 09:04:23 +00:00
mrhid6 3a1614066e feat: maintenance window and patch policy services
Named patch_window.go (not patch_windows.go) since the _windows.go
suffix is Go's implicit GOOS build constraint and would silently
exclude the file on non-Windows builds.
2026-09-15 08:50:36 +00:00
mrhid6 c0e26d0493 feat: patchsched fire/skip decision and window arithmetic 2026-09-15 08:44:52 +00:00
mrhid6 b60daf0461 feat: patchrun - pure state machine for patch runs
Implements the patchrun package with a pure functional state machine for managing
patch runs. Contains no database dependencies - the services layer loads a run,
asks this package what should change, and writes changes guarded by expected status.

All 14 test cases pass, covering:
- Agent version parsing and support detection
- Concurrency limits and queueing
- Window deadlines and offline handling
- Result timeouts (ResultGrace, ManualTimeout, RebootTimeout)
- Reboot verification with boot time proof
- Run finalization logic
- Summary generation for alerts
2026-09-15 08:39:21 +00:00
mrhid6 8f1ea6d5a0 feat: patch models, scoped collections and indexes; pin vantage-shared v0.5.0 2026-09-15 08:27:04 +00:00
mrhid6 e63e773cda docs: implementation plan for scheduled patching; align spec audit names, alert payload and run source 2026-09-14 15:32:47 +00:00
mrhid6 48116bf737 docs: design for maintenance windows and scheduled patching 2026-09-14 14:41:24 +00:00
mrhid6 2b4b630ae0 chore: pin vantage-shared v0.3.3
Chart Release / chart (push) Successful in 22s
Server Deploy / deploy (push) Successful in 3m24s
2026-09-11 11:02:10 +00:00
mrhid6 ad0f583d41 chore: pin vantage-shared v0.3.2
Chart Release / chart (push) Successful in 21s
Server Deploy / deploy (push) Successful in 3m34s
2026-09-11 09:58:51 +00:00
mrhid6 5ca705c88c feat: login page says a locked instance is suspended instead of drawing the form
Chart Release / chart (push) Successful in 20s
Server Deploy / deploy (push) Successful in 4m4s
2026-09-11 09:05:44 +00:00
mrhid6 2d96cb4224 chore: pin vantage-shared v0.3.0
Chart Release / chart (push) Successful in 23s
Server Deploy / deploy (push) Successful in 3m31s
2026-09-11 08:36:27 +00:00
mrhid6 d2672fc022 docs: HQ dispute lock and purge contract 2026-09-10 13:25:47 +00:00
mrhid6 ec22696402 feat: purge instances whose HQ dispute failed; Free reaper skips locked instances 2026-09-10 13:25:33 +00:00
mrhid6 913d3da386 feat: refuse instances Vantage HQ has locked under a dispute 2026-09-10 13:24:47 +00:00
mrhid6 8bd0d790dd fix: Fixed modal overflow issue
Chart Release / chart (push) Successful in 11s
Server Deploy / deploy (push) Successful in 42s
2026-09-10 12:51:37 +00:00
mrhid6 3e4db573bc chore: Updated go deps
Chart Release / chart (push) Successful in 13s
Server Deploy / deploy (push) Successful in 2m37s
2026-09-10 12:08:53 +00:00
mrhid6 5925717ca8 fix: Fixed env variable
Chart Release / chart (push) Successful in 12s
Server Deploy / deploy (push) Failing after 1m6s
2026-09-10 11:19:53 +00:00
mrhid6 f3e7357735 fix: Fixed license page scrollbar overflow
Chart Release / chart (push) Successful in 14s
Server Deploy / deploy (push) Successful in 46s
2026-09-10 09:25:24 +00:00
mrhid6 6ee203f5e9 chore: replace em dashes with hyphens, add no-em-dash rule to CLAUDE.md
Chart Release / chart (push) Successful in 20s
Server Deploy / deploy (push) Failing after 1m52s
2026-09-10 09:18:55 +00:00
mrhid6 b36a696d0e feat: Added nginx container to docker compose file
Server Deploy / deploy (push) Successful in 9s
Chart Release / chart (push) Successful in 10s
2026-09-10 08:43:25 +00:00
mrhid6 1538ae9bd1 fix: Fixed docker compose images
Chart Release / chart (push) Successful in 11s
Server Deploy / deploy (push) Successful in 11s
2026-09-10 08:16:21 +00:00
mrhid6 5377a1e585 fix: bind scope tests to real code, close time-of-write gap, fail closed
Chart Release / chart (push) Successful in 15s
Server Deploy / deploy (push) Successful in 3m41s
The previous tests reimplemented the target-scope rule instead of calling
validateWorkflowTargetScope, so they proved nothing about CreateWorkflow
or UpdateWorkflow's actual enforcement. Split the check into a pure
decideWorkflowTargetScope (tested directly, no database) and a thin
wrapper behind an overridable listServersForScope seam, so tests can
invoke the real CreateWorkflow/UpdateWorkflow without a live database and
fail if the call sites are removed.

Close the time-of-write/time-of-fire gap: a restricted caller could
previously save target_tags matching no server today (a selector aimed
at hosts not yet provisioned or not yet tagged), pass validation on an
empty set, and have the scheduler fire on those hosts the moment they
appeared. Now a restricted caller specifying targets that resolve to
nothing is refused with the same message as an out-of-scope match; a
workflow with no targets at all, and an unrestricted caller, are
unaffected.

A database error while resolving the fleet now surfaces as an error
instead of folding into a pass.

Correct three comments that overstated what the code does: the
create/update route comment now mentions the tag-scope check, not only
validateTargetServers; the schedule route comment explains its safety
holds only for workflows written after this check existed, not for rows
already in the database under the old rule.
2026-09-09 11:56:15 +00:00
mrhid6 2e3d2a33f9 fix: close privilege escalation via workflow TargetTags on REST create/update
CreateWorkflow and UpdateWorkflow validated TargetServerIDs against the
caller's scope but never checked TargetTags, letting a restricted token
save a workflow with an empty ID list and an out-of-scope tag selector,
then reach those hosts once the scheduler fires it as the system with no
restriction of its own. Add validateWorkflowTargetScope, applying the
same all-or-nothing rule the MCP create_workflow tool already enforces:
resolve the full target set unscoped and scoped, refuse unless they
match. Update the PUT /api/workflows/:id/schedule fleetWide comment to
say why it is safe now (targets are constrained at write time) rather
than repeating the falsified claim that scheduling reaches nothing new.
2026-09-09 11:45:39 +00:00
mrhid6 52ac966cba fix(api): allow serverScopedRoutes entries for routes outside /api group
TestServerScopeMapCoversEveryScopedRoute wrongly required serverScopedRoutes
to be a subset of routeScopes, which only covers the authenticated /api
group. The ESO route is registered on the root router and is exempt from
routeScopes by design, so it failed the test despite being correctly
declared. Lift the hardcoded exception in AssertScopeMapComplete into a
named routesOutsideAPIGroup set that both scopes.go and the test read.
2026-09-09 11:32:52 +00:00
mrhid6 bfe58c4cd2 fix: Fixed serverscope for secret eso endpoint
Chart Release / chart (push) Successful in 23s
Server Deploy / deploy (push) Successful in 2m13s
2026-09-09 08:57:21 +00:00
mrhid6 9d7c4b72aa fix: Fixed openapi doc
Chart Release / chart (push) Successful in 14s
Server Deploy / deploy (push) Canceled after 2m8s
2026-09-09 08:46:25 +00:00
mrhid6 a2351c75dd feat:runscope test
Chart Release / chart (push) Successful in 23s
Server Deploy / deploy (push) Failing after 58s
2026-09-09 08:43:55 +00:00
mrhid6 3695bc9e1a feat(mcp): declare an input schema and a server-data flag for every tool 2026-09-09 08:41:16 +00:00
mrhid6 9bcec168b9 refactor(api): require every /api route to declare its server-scope status 2026-09-09 08:38:53 +00:00
mrhid6 d95f299562 feat(tokens): refuse minting mcp scopes without the MCP licence feature 2026-09-09 08:36:26 +00:00
mrhid6 ac8e957859 fix(security): scope package search, run documents, workloads and vulnerability reads to the token's tags 2026-09-09 08:36:04 +00:00
mrhid6 6a48dd5d73 fix(security): scope workflow target and monitor runner validation to the caller's tags 2026-09-09 08:33:38 +00:00
mrhid6 5fcfb40084 fix(security): scope workflow run dispatch and MCP run logs to the token's tags 2026-09-09 08:32:32 +00:00
mrhid6 705085d3c7 feat: Fixed spacing 2026-09-09 08:16:06 +00:00
mrhid6 67520c677b feat: show mcp feature row on the licence page 2026-09-09 08:09:46 +00:00
mrhid6 bb698eba8a feat: let an agent create steps, workflows and monitors, inert until a human arms them 2026-09-09 08:07:26 +00:00
mrhid6 3bdbf33f90 fix: scope monitor runner and workflow targets to the caller's fleet
GET /api/monitors and GET /api/monitors/:id returned Monitor.Runner
unfiltered; for an agent-pushed monitor that field is literally a server
ID, so a restricted token learned which out-of-scope server a monitor
runs on directly, not merely that one exists. services.RedactMonitorRunner
replaces Runner with models.RunnerRestricted when it names a server
outside the caller's scope, resolved once via the new
services.VisibleServerIDs rather than per monitor. The monitor itself is
still returned — a restricted operator may legitimately need to see that
it exists and is up or down — only the runner field goes neutral; omitting
the monitor entirely was considered and rejected as more surprising than
one field changing. Runner "server" (control-plane-run) is never
touched. The MCP list_monitors/get_monitor_status projections never had a
Runner field to begin with, so REST and the tool surface already agreed;
a comment now records why.

GET /api/workflows and GET /api/workflows/:id returned
Workflow.TargetServerIDs unfiltered — directly naming out-of-scope
servers, worse than a count. services.FilterVisibleServerIDs narrows the
list to what VisibleServerIDs admits and reports hidden (no count) when
at least one target was dropped; WorkflowResponse wraps *models.Workflow
with a scoped TargetServerIDs and a TargetsRestricted flag. TargetTags is
left untouched — the tag vocabulary is already ruled acceptable to
expose. The MCP list_workflows/get_workflow tools get the identical
treatment: list_workflows' target count is now based on the filtered ID
list, and get_workflow's workflowDetail carries the same
TargetsRestricted flag, so a model that sees a filtered target list and
then has run_workflow refuse the same workflow for out-of-scope targets
is not left concluding the refusal invented a problem the list never
mentioned.

All four routes recorded in serverScopedRoutes as true; none is
boot-enforced, for the same substring-filter reason as the key routes
added in the previous round.
2026-09-09 08:03:26 +00:00
mrhid6 e06f9d5670 fix: scope the assignment count leaked by the key list
GET /api/keys returned each key's AssignedCount as a raw
CountDocuments over every non-revoked assignment, with no scope filter —
a tag-restricted token reading the list saw a nonzero count for a key it
can see nothing assigned to in its own scope, which is enough to tell it
an assignment exists on a host it must not know about. Same class of leak
getKey's assignment-list filter closed on the detail route, surviving on
the list route through a count instead of a server object.

services.ListKeys now takes the caller's tokenScope. An unrestricted
caller (empty scope) takes the original unfiltered per-key
CountDocuments with no extra work, so the common case is not slower. A
restricted caller resolves the visible fleet once via ListServers before
the per-key loop, then counts each key's assignments with an added
server_id $in filter — one extra query total, not one per key.
ListKeys had exactly one caller (listKeys), so the parameter went there
rather than adding a second entry point.

Recorded GET /api/keys in serverScopedRoutes as true; its path, like GET
/api/keys/:id, matches none of serverTouchingRoutes' substrings, so the
entry is not boot-enforced. Deliberately did not widen the filter to
catch "keys" — that would sweep in create/delete/private-key routes with
no server data at all. The real fix for this shape of gap is the
declare-by-default inversion already recorded as a follow-up.
2026-09-09 07:54:42 +00:00
mrhid6 dc6e1b3c29 fix: widen server-scope boot check, filter out-of-scope key assignments
serverTouchingRoutes in cmd/main.go filtered on "server"/"console"/an exact
workflows-run match, which is how POST /api/keys/:id/assign reached
production with no scope check and no boot-time signal at all: its path
names neither. Widen the filter to also match ":serverId" and "assign",
and document at the filter why a substring match is the weak part of this
design — a route that acts on a server without saying so in its path stays
invisible to it — noting that inverting the model (every /api route
declares itself, with an exemption list) would be the stronger fix and is
left as a follow-up. Re-running the mechanical check against the widened
filter swept in no route beyond what serverScopedRoutes already declared.

GET /api/keys/:id also leaked out-of-scope hostnames: it returned every
assignment for a key, server attached, unfiltered by the caller's tag
restriction. getKey now drops any assignment whose server fails
services.ServerInTokenScope before returning the list — silently, so the
response carries no count of what was removed — while still returning the
key itself, since a restricted token may legitimately hold a key also
assigned outside its scope. GetAssignmentsWithServers has exactly one
caller (getKey), so the filtering is done in the handler rather than
threaded into the service. Recorded in serverScopedRoutes; its path
matches none of the filter's substrings either, so it is not boot-enforced
and is kept as a considered decision, same as the assign/revoke entries.
2026-09-09 07:51:04 +00:00
mrhid6 cbf929fe2d fix: audit refused and failed mcp write calls, scope key assignment to token
Every early return from a write-tool handler skipped both the tool's own
LogCall and transport.go's gated LogCall (which only fires for reads), so a
blocked mutation attempt left no audit trail. registerSDKTool now routes
every write-tool error through LogDenied (fan-out and tag-scope refusals,
by gate name) or LogFailure (everything else), keeping the successful-write
path logging its own resolved server count exactly as before.

Also close a live scope gap surfaced while reviewing this: POST
/api/keys/:id/assign called services.AssignKey with an unscoped GetServer
lookup, so a tag-restricted token could assign a key to a server outside
its restriction. The handler now resolves the target through
GetServerScoped first, matching its sibling revoke route, and the route is
recorded in serverScopedRoutes.
2026-09-09 07:46:45 +00:00
mrhid6 b3651ab58c feat: add mcp write tools with a fan-out guard 2026-09-09 07:28:48 +00:00
mrhid6 191a8e9074 fix(mcp): correct fleet online status, unsafe version filter, audit totals
summariseServer compared Status against "online", a value never assigned
anywhere (the real vocabulary is pending/active/offline), so every server
misreported as offline. search_fleet's version_below used a lexicographic
comparison across dpkg/rpm/apk version schemes with no common ordering, so
it refuses that filter now and returns all matches instead of a wrong
answer. listAuditResult's Total carried the "shown" JSON tag and the
capped count; it now reports the real total alongside shown.
2026-09-09 07:24:09 +00:00
mrhid6 ed79df4270 fix: restore the vantage-shared go.sum entries dropped by go mod tidy 2026-09-09 07:17:53 +00:00
mrhid6 7ec97ae8c2 feat: Removed go.mod replace
Chart Release / chart (push) Successful in 17s
Server Deploy / deploy (push) Successful in 3m9s
2026-09-08 15:10:05 +00:00
mrhid6 b96cd85e43 feat: go mod tidy
Chart Release / chart (push) Successful in 18s
Server Deploy / deploy (push) Failing after 1m16s
2026-09-08 15:00:54 +00:00
mrhid6 971bcece44 feat: Updated openapi doc 2026-09-08 14:51:43 +00:00
mrhid6 333d729026 feat: Updated go deps
Chart Release / chart (push) Successful in 19s
Server Deploy / deploy (push) Failing after 1m20s
2026-09-08 14:44:45 +00:00
mrhid6 8dd68e34c1 docs: mark the api keys redesign plan implemented
Chart Release / chart (push) Successful in 20s
Server Deploy / deploy (push) Failing after 1m11s
2026-09-08 14:14:57 +00:00
mrhid6 e5b9894384 feat: surface the mcp endpoint and its scopes on the api keys page 2026-09-08 14:14:44 +00:00
mrhid6 14b947f791 feat: add mcp read tools for fleet, health and workflow data 2026-09-08 14:12:44 +00:00
mrhid6 98233b620c docs: fold the mcp task 12 token-form steps into the api keys redesign 2026-09-08 14:12:26 +00:00
mrhid6 2d6b5bd8a3 feat: restrict an api key to tagged servers from the create dialog 2026-09-08 14:12:10 +00:00
mrhid6 ac9cc57e7e feat: rebuild the create key dialog around a scope matrix and a preview 2026-09-08 14:10:37 +00:00
mrhid6 a0641e8ecb feat: summarise key posture above the ledger 2026-09-08 14:09:00 +00:00
mrhid6 67ac029354 feat: redesign the api key list as a ledger with lifetime bars 2026-09-08 14:07:56 +00:00
mrhid6 a0b5565a63 docs: explain why GET /api/mcp deliberately answers 405 in stateless mode 2026-09-08 14:07:54 +00:00
mrhid6 aedc388535 refactor: split the api keys panel into ledger, chips, lifetime and dialog 2026-09-08 14:06:02 +00:00
mrhid6 5e4c8afdd1 feat: model an api key's remaining lifetime as a single value 2026-09-08 14:03:49 +00:00
mrhid6 0166b17299 feat: serve the mcp endpoint behind the licence feature 2026-09-08 13:57:21 +00:00
mrhid6 674236bb76 feat: audit mcp tool calls and guard against fleet-wide fan-out 2026-09-08 13:50:28 +00:00
mrhid6 5943d98681 feat: add the mcp tool registry and its scope gates 2026-09-08 13:50:01 +00:00
mrhid6 7ea8e2fff0 fix: close out-of-scope server access in vulns, packages, run logs, and key revoke 2026-09-08 13:48:11 +00:00