Admin (site-admin only)
Planned. The admin API is not exposed yet. Site-admin actions today are reachable through the
/admin/web UI and theshithubd adminCLI subcommands.
The site-admin surface is intentionally narrow: most operator
actions go through the CLI (shithubd admin …) where they're
auditable from journal logs. The planned API here exists for
automation that's already authenticated as a site admin (e.g.,
an SSO/SCIM bridge).
Planned routes
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /api/v1/admin/users |
site-admin | List users (paginated). |
| GET | /api/v1/admin/users/{id} |
site-admin | One user, with admin-only fields. |
| POST | /api/v1/admin/users/{id}/suspend |
site-admin | Freeze the account. |
| POST | /api/v1/admin/users/{id}/reinstate |
site-admin | Un-freeze. |
| POST | /api/v1/admin/users/{id}/reset-password |
site-admin | Force a password reset email. |
| POST | /api/v1/admin/users/{id}/site-admin |
site-admin | Grant or revoke site-admin bit. |
Authorization
A regular PAT — even one held by a user who is a site admin — is not enough by itself; the admin endpoints require both:
- The token's owner has the
is_site_adminflag set. - The token has the
admin:sitescope (separate fromadmin:org).
Both checks must pass; either alone returns 403.
Audit
Every admin API call writes to the same admin_audit_log the
web admin UI uses. Each row carries the calling site admin's id,
the target id, the action, and the request IP.
View source
| 1 | # Admin (site-admin only) |
| 2 | |
| 3 | > **Planned.** The admin API is not exposed yet. Site-admin |
| 4 | > actions today are reachable through the `/admin/` web UI and |
| 5 | > the `shithubd admin` CLI subcommands. |
| 6 | |
| 7 | The site-admin surface is intentionally narrow: most operator |
| 8 | actions go through the CLI (`shithubd admin …`) where they're |
| 9 | auditable from journal logs. The planned API here exists for |
| 10 | automation that's already authenticated as a site admin (e.g., |
| 11 | an SSO/SCIM bridge). |
| 12 | |
| 13 | ## Planned routes |
| 14 | |
| 15 | | Method | Path | Scope | Purpose | |
| 16 | |--------|------------------------------------------|----------------|----------------------------------| |
| 17 | | GET | `/api/v1/admin/users` | site-admin | List users (paginated). | |
| 18 | | GET | `/api/v1/admin/users/{id}` | site-admin | One user, with admin-only fields.| |
| 19 | | POST | `/api/v1/admin/users/{id}/suspend` | site-admin | Freeze the account. | |
| 20 | | POST | `/api/v1/admin/users/{id}/reinstate` | site-admin | Un-freeze. | |
| 21 | | POST | `/api/v1/admin/users/{id}/reset-password`| site-admin | Force a password reset email. | |
| 22 | | POST | `/api/v1/admin/users/{id}/site-admin` | site-admin | Grant or revoke site-admin bit. | |
| 23 | |
| 24 | ## Authorization |
| 25 | |
| 26 | A regular PAT — even one held by a user who is a site admin — is |
| 27 | **not enough** by itself; the admin endpoints require both: |
| 28 | |
| 29 | - The token's owner has the `is_site_admin` flag set. |
| 30 | - The token has the `admin:site` scope (separate from `admin:org`). |
| 31 | |
| 32 | Both checks must pass; either alone returns 403. |
| 33 | |
| 34 | ## Audit |
| 35 | |
| 36 | Every admin API call writes to the same `admin_audit_log` the |
| 37 | web admin UI uses. Each row carries the calling site admin's id, |
| 38 | the target id, the action, and the request IP. |