5.1 KiB
Administrative authentication foundation
Integrated administrative sign-in
Administrators sign in at /admin/login using the shared credential configured
as ADMIN_AUTH_SECRET. The page submits the credential directly to
POST /api/admin/auth/login; it does not place the credential in a URL or store
it in browser storage.
Successful authentication creates the administrative session cookie and sends
the browser to /admin. The /admin server-side loader validates that cookie
before loading administrative data. A valid session is not sufficient by
itself: the existing /admin IP allowlist remains an additional restriction,
and a valid administrator outside the allowed network is sent to /403.
The administrative interface provides a Sign out control which calls
POST /api/admin/auth/logout, clears the cookie, and returns the browser to
/admin/login. Sessions expire after 20 minutes and expired, invalid, or
missing sessions are redirected to the login page.
Required server-side configuration
The deployment must provide all of the following server-side values:
ADMIN_AUTH_SECRET: a unique high-entropy administrative passphrase of at least 32 characters.ADMIN_SESSION_SECRET: a different unique high-entropy signing key of at least 32 characters.NEXTAUTH_URL: the existing canonical application URL. Administrative login and logout compare the requestOriginwith this server-configured origin.
The administrative values must never use a NEXT_PUBLIC_ prefix or be exposed
to browser JavaScript. Do not commit real values. Missing, short, or identical
administrative secrets fail closed.
Security properties and limitations
- Credentials are derived with Node
scryptand compared withtimingSafeEqual. - Sessions are stateless, versioned HMAC-SHA256 tokens with a 20-minute fixed lifetime and a random nonce.
- The cookie is
HttpOnly,SameSite=Strict, scoped to/, explicitly expires, and isSecurein production. - Login and logout require an exact same-origin
Originmatch againstNEXTAUTH_URL; missing or malformed origins fail closed. - Authentication responses use
Cache-Control: no-store. - Logout clears the browser cookie. Because sessions are stateless, a stolen token can remain valid until its short expiry; later protected routes must continue verifying signature and expiry on every request.
- This is shared-credential authentication. A valid token proves knowledge of the shared credential, not the identity of a named administrator.
- Protecting
/adminprevents its server-side Prisma, storage, and CRM data loading from running without a valid administrative session. It does not by itself protect browser-addressable API routes.
Administrative API protection limitations
The current administrative UI directly uses API routes that do not yet enforce the administrative session, including:
/api/admin/getnewappeals_api/api/admin/getlatestdocuments_api/api/admin/getStatusCountsByAppeal_api/api/admin/getStatusCountsByAppealAndLPA_api
The appeals and documents routes expose paging operations used after the page has loaded. The status routes expose administrative dashboard reads. These routes retain their existing relay token and HMAC behaviour but have no independent administrative-session authorization. A later authorised stage must enforce the administrative session on privileged API routes and account for both browser calls and the existing server-side bootstrap callers.
Storage download, representation editing, queue actions, and draft deletion also retain their existing authorization behaviour in this stage. In particular, the original cross-container deletion risk is not remediated by the administrative page login and remains a separate mitigation boundary.
Directly observed storage routes include:
/api/file/getrepsblobproxy, which forwards a caller-supplied container using server relay credentials and path signing./api/file/editRepJson, which performs a direct blob mutation and has no visible administrative-session or HMAC check./api/file/downloadbloband/api/file/createrepcompletemessage_api, which enforce existing path-HMAC checks but not administrative authorization./api/file/deleteblobcaseand/api/file/deleteblobrep, whose existing cross-container deletion behaviour is intentionally unchanged in this stage.
Deployment requirements before production use
The repository does not provide a demonstrated distributed rate-limit service. Administrative login must therefore be protected by an ingress, gateway, WAF, or shared backing service that enforces rate limits consistently across all deployed instances. A process-local limiter is intentionally not used because it would reset on restart and could be bypassed across instances.
The deployment must also ensure NEXTAUTH_URL is the correct canonical HTTPS
origin. Login and logout intentionally do not derive trust from Host or
forwarding headers.
Any future administrative state-changing API must require more than possession of the cookie: it must independently validate the administrative session and enforce same-origin/CSRF protection before performing side effects.