Summary
POST /api/auth/generatetoken cannot mint a scope-restricted token, even though the token layer supports it. AuthToken.generate accepts an options.scopes (validated by resolveTokenScopes), but the endpoint neither accepts nor forwards it:
generateTokenHandler passes only { lifespan: req.body.lifespan } — req.body.scopes is dropped.
- The route's request-body schema in
routes.json declares only lifespan.
So every manual token created through the API inherits the user's full scopes; there's no way to request a narrower one via the endpoint.
Fix
- Forward
req.body.scopes in generateTokenHandler.
- Add
scopes (array of strings) to the request-body schema.
Backwards-compatible: omitting scopes behaves exactly as today (full scopes). No new authorisation surface — resolveTokenScopes already enforces the rules (rejects *:*, forbids a super user minting a manual token, and rejects scopes exceeding a non-super user's own via TOKEN_SCOPE_INVALID).
Summary
POST /api/auth/generatetokencannot mint a scope-restricted token, even though the token layer supports it.AuthToken.generateaccepts anoptions.scopes(validated byresolveTokenScopes), but the endpoint neither accepts nor forwards it:generateTokenHandlerpasses only{ lifespan: req.body.lifespan }—req.body.scopesis dropped.routes.jsondeclares onlylifespan.So every manual token created through the API inherits the user's full scopes; there's no way to request a narrower one via the endpoint.
Fix
req.body.scopesingenerateTokenHandler.scopes(array of strings) to the request-body schema.Backwards-compatible: omitting
scopesbehaves exactly as today (full scopes). No new authorisation surface —resolveTokenScopesalready enforces the rules (rejects*:*, forbids a super user minting a manual token, and rejects scopes exceeding a non-super user's own viaTOKEN_SCOPE_INVALID).