2.3 KiB
2.3 KiB
Scripting Hammerhead: API audit
Everything the dashboard does goes through the JSON API (server.go lists the routes). Callers
authenticate with the hh_session cookie or Authorization: Bearer hhk_<id>_<secret>.
Credentials
| Credential | Reaches | Made at |
|---|---|---|
| Organization key | that organization's /api/orgs/{org}/... routes (admin rights), GET /api/orgs, GET /api/edges (edges the org may use) |
POST /api/orgs/{org}/apikeys |
| Server key | every organization, plus the server-admin routes: edges, /api/admin/alerts, users, settings, POST /api/orgs |
POST /api/admin/apikeys (signed-in server admin only) |
The secret is shown once, in the key field of the create response. A key cannot mint keys at server
level, and a server key has no user, so /api/me and other per-user routes refuse it.
Gaps found, and what was done
| Gap | Resolution |
|---|---|
Edges, server alerts, POST /api/orgs required a browser session (withServerAdmin refused keys) |
server keys, accepted by withServerAdmin |
| No way to mint an unattended server credential | GET/POST/DELETE /api/admin/apikeys |
GET /api/edges was session-only |
accepts keys; an org key sees the edges its org may use |
| No way to list orgs with a key | GET /api/orgs |
| Key creation did not return the key's ID | create response now has id as well as key |
Creating an alert channel returned only {ok:true} |
response now includes the channel id |
createOrg added the caller as a member |
skipped for server keys (they have no user) |
Known remaining gaps (not blocking scripting)
- No per-resource
GET: sites, domains, ports and alert channels are read fromGET /api/orgs/{org}/stateandGET /api/orgs/{org}/alerts. Clients filter by ID. - Alert channel secrets (webhook URL, Sandbar key) are never returned, so a client can't detect drift in them; a
blank value on
PUTkeeps the stored one. - Keys are all-powerful within their scope (no read-only or per-resource scopes), and have no expiry.
PUTon ports replaces the whole object; omitted fields reset.- Site tokens are returned on create and, for admins, in
state. - Deleting an edge or site cascades silently (its ports and domains go with it, as do ports left with no target), so Terraform plans should not rely on dependent resources surviving.