You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a Station platform engineer, I need a dedicated authentication model for Station-Bot administration so that only signed-in Station users can reach the admin surface, Station can call Station-Bot over a secure machine-to-machine identity boundary, and the Station super admin retains a break-glass login path if Discord authentication is unavailable.
Definition of Done
Station-Bot administration requests from the browser require an authenticated Station user session; anonymous users cannot bootstrap or mutate any Station-Bot admin route
Discord OAuth2 is the primary interactive login path for all normal Station users, including guild owners and guild admins
Local username/password login is restricted to the station_super_admin break-glass account and is intended only for cases where Discord is down or the Discord login flow is broken
Station-to-Station-Bot calls use a dedicated OAuth 2.0 Client Credentials identity rather than forwarding the end-user browser token downstream
A minimum downstream scope model is defined and enforced for the Station admin client, with separate scopes for read, write, and privileged action paths
Station stores any Station-Bot admin client credentials securely, never returns them to the frontend, and masks/reveals/rotates them using the same write-only secret discipline already expected for operator config
The frontend has clear auth-state handling for this area: no anonymous access, predictable 401/403 behavior, session-expiry handling, and degraded-state rendering when downstream client auth fails
Tests cover unauthenticated browser requests, Discord-authenticated access, blocked local login for non-super-admin users, allowed break-glass local login for the super admin, expired/revoked Station sessions, missing/invalid downstream client credentials, and downstream scope mismatch failures
pnpm typecheck passes
Acceptance Criteria
A user who is not logged in to Station cannot access /admin/station-bot, cannot call Station-Bot admin API routes, and does not receive any Station-Bot bootstrap payload
Guild owners and guild admins authenticate through Discord OAuth2 rather than local username/password login
Local login is unavailable to normal customer users and is only supported for the station_super_admin break-glass account
A signed-in Station user never sends Station-Bot client credentials to the browser; the browser only talks to Station, and Station talks to Station-Bot using the dedicated client identity
If the Station-Bot admin client is missing, revoked, or has insufficient scopes, the Station UI shows a degraded integration/authentication state instead of exposing a generic 500 or blank screen
Session expiry during Station-Bot admin use results in the same re-authentication behavior as the rest of Station, without leaving the admin area in a misleading partially-authenticated state
The downstream client scope contract is explicit and versioned. Minimum expected scopes should be:
station-bot:admin:read
station-bot:admin:write
station-bot:admin:action
Technical Elaboration
Station already has two relevant authentication primitives in code today:
End-user authentication via JWT-backed Station sessions, refresh rotation, session IDs, blacklist support, and both local and Discord auth support in backend/src/modules/auth
Machine-to-machine authentication via OAuth client credentials, ClientAuthGuard, and ScopesGuard
This story should formalize how those pieces are used for Station-Bot administration:
Browser → Station: authenticated Station user session only
Station interactive login policy:
station_super_admin may use local login as a break-glass path
all other customer-facing/admin users should authenticate with Discord OAuth2
Station → Station-Bot: dedicated OAuth client credentials token issued for the Station admin integration
Never: browser directly calling Station-Bot admin APIs with bot credentials or with a forwarded end-user JWT
Recommended implementation shape:
Station frontend admin route still relies on the existing Station user auth flow
Station backend explicitly distinguishes break-glass local login policy for the super admin from normal Discord-based auth for customer accounts
Station backend station-bot-admin module acquires and caches a downstream client token for the configured Station-Bot admin client
Downstream Station-Bot admin endpoints enforce scopes such as:
station-bot:admin:read for config/bootstrap/status fetches
station-bot:admin:write for standard config mutation
station-bot:admin:action for resync/manual action operations such as exec-hangar controls
Station stores the client ID and secret in secure operator config, with masked-read behavior after save
Station surfaces distinct integration-auth states:
user not signed in
user signed in but Station lacks downstream client config
downstream client configured but token request failed
downstream token valid but missing scopes
downstream auth healthy
This ticket is intentionally about authentication and service identity, not end-user permissions. Whether a signed-in user is allowed to see or mutate a specific bot domain is handled by the authorization story.
Design Elaboration
From the user’s perspective, Station-Bot administration should feel like a normal authenticated Station area, not a second login wall. Guild owners and guild admins sign in through Discord; the Station super admin retains a clearly designated break-glass local login only for platform support continuity.
The important UX requirement is clarity when auth breaks. If the user session expired, say so. If Discord auth is degraded, the super admin still has a recovery path. If the downstream bot client is misconfigured, say so. If Station can render the shell but cannot authenticate to Station-Bot, that degraded state should be obvious before the user edits anything.
Parent Epic:#231 Depends on: None. This is an authentication foundation story for the Station Bot Administration epic. Blocks:#232, #233, #243, #244
User Story
As a Station platform engineer, I need a dedicated authentication model for Station-Bot administration so that only signed-in Station users can reach the admin surface, Station can call Station-Bot over a secure machine-to-machine identity boundary, and the Station super admin retains a break-glass login path if Discord authentication is unavailable.
Definition of Done
station_super_adminbreak-glass account and is intended only for cases where Discord is down or the Discord login flow is brokenpnpm typecheckpassesAcceptance Criteria
/admin/station-bot, cannot call Station-Bot admin API routes, and does not receive any Station-Bot bootstrap payloadstation_super_adminbreak-glass accountstation-bot:admin:readstation-bot:admin:writestation-bot:admin:actionTechnical Elaboration
Station already has two relevant authentication primitives in code today:
backend/src/modules/authClientAuthGuard, andScopesGuardThis story should formalize how those pieces are used for Station-Bot administration:
station_super_adminmay use local login as a break-glass pathRecommended implementation shape:
station-bot-adminmodule acquires and caches a downstream client token for the configured Station-Bot admin clientstation-bot:admin:readfor config/bootstrap/status fetchesstation-bot:admin:writefor standard config mutationstation-bot:admin:actionfor resync/manual action operations such as exec-hangar controlsThis ticket is intentionally about authentication and service identity, not end-user permissions. Whether a signed-in user is allowed to see or mutate a specific bot domain is handled by the authorization story.
Design Elaboration
From the user’s perspective, Station-Bot administration should feel like a normal authenticated Station area, not a second login wall. Guild owners and guild admins sign in through Discord; the Station super admin retains a clearly designated break-glass local login only for platform support continuity.
The important UX requirement is clarity when auth breaks. If the user session expired, say so. If Discord auth is degraded, the super admin still has a recovery path. If the downstream bot client is misconfigured, say so. If Station can render the shell but cannot authenticate to Station-Bot, that degraded state should be obvious before the user edits anything.
Parent Epic: #231
Depends on: None. This is an authentication foundation story for the Station Bot Administration epic.
Blocks: #232, #233, #243, #244