Add self-service API tokens (PATs) — the UI had no way to create one

jump-host had zero API-token support: no model, no route, no UI, and
Auth.checkApiToken was explicitly absent from the createOidcClient() call
(per the comment it left behind). proxy and sso-manager-node both have
this; jump-host didn't.

Ports proxy's models/api_token.js + routes/api_token.js pattern (jmp_
prefix instead of prx_), wires checkApiToken into createOidcClient(), adds
Bearer-token support to middleware/auth.js, and adds a token management
card to dashboard.ejs (create/list/rotate/revoke) using app.modal/
app.messages.

Scope note: a jump-host token carries no group claims (unlike proxy's,
which snapshots the creator's groups), so it authenticates as its creator
for non-admin routes (e.g. GET /api/user/hosts) but can never pass
requireAdmin — a deliberate, conservative default rather than recomputing
live admin status per-request.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 19:44:04 -04:00
parent 4a70b5b27e
commit 4326d5588e
7 changed files with 348 additions and 5 deletions
+4
View File
@@ -9,6 +9,10 @@ router.use('/auth', require('../models').authRouter);
// Who am I — needs a valid session but no admin gate (drives the login state).
router.use('/user', middleware.auth, require('./user'));
// Self-service API token (PAT) management — any authenticated user, no
// admin gate (see routes/api_token.js for why a token can't reach admin routes).
router.use('/api-token', middleware.auth, require('./api_token'));
// Jump-host data — admin only (audit log, active sessions, metrics).
router.use('/', middleware.auth, middleware.requireAdmin, require('./jump'));