Three coupled fixes so non-admin agents (e.g. nav, role=mgr) can
actually create projects through hf-cli with their API key:
1. POST /projects no longer hardcodes is_admin. It checks the global
`project.create` perm via role_permissions (admin still wins via
is_admin short-circuit). Permission-denied 403 message names the
exact perm.
2. /auth/me/permissions now uses get_current_user_or_apikey (was
get_current_user JWT-only). This is what hf-cli hits to populate
its local permission cache that drives the "not permitted" gate;
previously every API-key-authed agent saw all commands as gated.
3. get_current_user_or_apikey now also accepts an API key delivered
via Authorization: Bearer (in addition to X-API-Key). hf-cli only
knows Bearer; trying to JWT-decode an API key string would fail —
so on decode failure, fall through to the API key lookup. Keeps
X-API-Key behavior unchanged.
4. init_bootstrap: add `project.create` to DEFAULT_PERMISSIONS and to
_MGR_PERMISSIONS so admin (auto-all) + mgr both get it on seed.
Bug came to light when manager-agent reported `hf project list`/`create`
returned `not permitted`. Root cause: hf-cli calls /auth/me/permissions
with the API key via Bearer header → 401 → state.Known=false → every
command in the surface is gated false locally. Even after the local
gate, POST /projects would still 403 due to the hardcoded admin check.
All four steps above are required end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Generic OIDC (Authlib discovery) Authorization Code flow; backend
issues the existing HS256 JWT on success. Unbound identities are
rejected (no auto-provisioning).
- User.oidc_issuer/oidc_subject (unique together) + startup migration.
- PUT/DELETE /users/{id}/oidc-binding (admin or account-manager;
JWT or API key; 409 on conflict). Self-link /auth/oidc/link
(non-OIDC_ONLY only). Public GET /auth/config.
- HARBORFORGE_OIDC_ONLY: /auth/token rejected, create/update ignore
password (passwordless users; API keys + OIDC still work).
- Dockerfile ARG/ENV HARBORFORGE_OIDC_ONLY; authlib+itsdangerous deps;
SessionMiddleware for OIDC state. Fixed _user_response to expose
the new binding fields.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Fix: /milestones?project_id= now accepts project_code (str) not just int
- Add: built-in acc-mgr user created on wizard init (account-manager role, no login, undeletable)
- Add: POST /users/{id}/reset-apikey with permission-based access control
- Add: GET /auth/me/apikey-permissions for frontend capability check
- Add: user.reset-self-apikey and user.reset-apikey permissions
- Protect admin and acc-mgr accounts from deletion
- Block acc-mgr from login (/auth/token returns 403)
- users router: accept username or id in get/update/delete/worklogs via _find_user_by_id_or_username()
- auth router: add GET /auth/me/permissions for CLI help introspection (token → user → role → permissions)