Contract-freeze · UX approval

Service tokens · Approval Frames

The consumer surface for machine-to-machine credentials: create a scoped service token, copy its secret the one time it's shown, list active tokens by prefix, and revoke. Backed by FuzeFront's own Security API — no identity or authorization vendor is named anywhere. Reached from the account-security area, alongside access administration. Walk each frame below; the reveal-once screen (c) is the one that matters most.

Frame (a) · /settings/tokens

Service tokens

The list: name, prefix, scope chips, created, last-used, revoke.

Frame (b) · /settings/tokens

Create token

Name + scope checkboxes + optional expiry. At least one scope required.

Frame (c) · /settings/tokens · MOST IMPORTANT

Secret shown once

Copy affordance, explicit "I've saved it" ack, honest unrecoverable warning.

Frame (d) · /settings/tokens

Revoke token

Ordinary confirm, plus type-to-confirm when the token is in active use.

Frame (e) · /settings/tokens

States

Loading, no-tokens invitation, load error+retry, and 403 (never a sign-in redirect).

Build inventory

Approving these frames approves this component/package plan. Implementation cannot quietly invent a different architecture. Mirrored in manifest.jsonbuild.

Flows

  • ServiceTokensFlow
    route /settings/tokens · approved: false

Components

  • TokenList
  • TokenRow
  • ScopeChips
  • CreateTokenDialog
  • ScopePicker
  • RevealOncePanel
  • CopySecretButton
  • RevokeTokenDialog
  • AccessDeniedNotice

Packages

  • @fuzefront/service-tokens-ui
● Awaiting approval — per flow

Design system: @fuzefront/design-system (fuse-seam, tokens only) · Contract: backend/security/src/routes/api-tokens.ts@fuzefront/security-client · Component: @fuzefront/service-tokens-ui → ServiceTokensFlow.
Commissioned by approval: (1) a last_used_at field on the token record (frames a, d) — not backed today; (2) bringing the token CRUD endpoints into the frozen packages/security/openapi.yaml (only issue + introspect live there now). The raw secret shown is a deliberately-fake placeholder. Approve per-flow by setting approved: true in manifest.json, or reply @claude approve / @claude reject: <reason>.

Review · api-tokens approve or reject each flow ↓
service-tokenspendingApproveReject