Skip to content

feat: runtime allowed-agent registration via admin API - #17

Merged
zippy merged 6 commits into
mainfrom
feat/dynamic-progenitor-registration
Aug 21, 2026
Merged

zippy merged 6 commits into
mainfrom
feat/dynamic-progenitor-registration

Conversation

@zippy

@zippy zippy commented Aug 14, 2026

Copy link
Copy Markdown
Member

First half of #13: a progenitor (or any allowed agent) can now be registered at runtime instead of editing allowed_agents in the config and redeploying — no more dependency loop between the progenitor node and the joining service.

curl -X POST https://join.example.com/v1/admin/allowed-agents \
  -H "Authorization: Bearer $JOINING_ADMIN_SECRET" \
  -d '{"agent_key": "uhCAk...", "label": "acme-net progenitor"}'
  • New AllowedAgentStore (memory / sqlite / Cloudflare KV; backend follows session.store). agent_allow_list accepts agents from the static config list OR the store — existing deployments are unaffected.
  • Admin routes POST/GET/DELETE /v1/admin/allowed-agents, bearer-authenticated by the new agent_registration.admin_secret config; mounted only when configured. Mirrors the dynamic linker registration pattern.
  • The admin bearer middlewares (this one and the existing linker one) are now scoped to their own path families — the previous /v1/admin/* wildcard on the linker middleware would have 403'd the new routes whenever both admin secrets were configured. src/routes/admin-linkers.ts is touched for exactly this reason, with a combined-admin regression test.

Operational notes:

  • Node-only out of the box: the bundled Cloudflare worker entry does not wire a KvAllowedAgentStore yet; Workers deployments must construct one in their worker entry (same pre-existing gap as the linker admin routes).
  • Unregistering prevents future joins only — it does not end in-flight sessions or revoke already-joined agents (reconnect does not consult the allow list; revocation remains hc_auth_approval's job).
  • sqlite deployments using agent_allow_list will create allowed-agents.db next to the sessions db on upgrade.
  • Registration only affects joins when agent_allow_list is in auth_methods; the server warns at startup otherwise.

@zippy
zippy requested a review from ThetaSinner August 14, 2026 12:48
Comment thread src/agent-registration/sqlite-store.ts
`registered_at` records when an agent was first allowed, so re-POSTing a
key to correct its label no longer resets the clock. The admin route
carries the existing timestamp forward and returns 200 instead of 201;
the stores stay last-write-wins so all three backends behave alike.
DELETE followed by POST remains the way to get a fresh timestamp.
@zippy
zippy merged commit 380cccf into main Aug 21, 2026
1 check passed
@zippy
zippy deleted the feat/dynamic-progenitor-registration branch August 21, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants