37 lines
2.2 KiB
Markdown
37 lines
2.2 KiB
Markdown
# 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` |
|
|
| `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 from `GET /api/orgs/{org}/state` and
|
|
`GET /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 `PUT` keeps the stored one.
|
|
- Keys are all-powerful within their scope (no read-only or per-resource scopes), and have no expiry.
|
|
- `PUT` on ports replaces the whole object; omitted fields reset.
|
|
- Site tokens are returned on create and, for admins, in `state`.
|
|
- Deleting an edge/site does not check for ports that use it (the server cleans up or refuses; clients should order deletes).
|