GitHub
10/31/2026, 10:40 AMbase: './', with <base href="/"> in index.html and relative asset URLs. The web server rewrites the href to the prefix.
• New src/lib/base-path.ts reads the prefix from document.baseURI and exposes appPath().
• appPath() is used for the TanStack Router basepath, every fetch to /api/..., the 36 hard window.location.href = '/login' redirects, the logout return URL, the Monaco loader path and the /img/* URLs.
API
• New --base-path flag, env SERVICE_BASE_PATH, basePath in api.yml.
• The value is validated by config.NormalizeBasePath, which accepts plain path segments only. This matters because the value goes into cookie Path attributes and Location headers. Startup fails on an invalid value.
• The prefix is added to:
• the session, CSRF and ID-token cookie paths, and their clears on logout;
• the auth-state cookie path (IssueStateCookie and ClearStateCookie now take basePath);
• the OIDC and SAML callback redirects and the unauthorised redirect;
• the `loginUrl`s in /api/v1/auth/methods.
Deploy and docs
• `deploy/nginx/frontend.conf`: a commented prefix block (rewrite plus sub_filter).
• deploy/config/api.yml and `docs/auth-providers.md`: the new setting, and a note that the OIDC redirect URL, SAML ACS URL and IdP callback URLs must include the prefix.
Security and operational impact
• With no prefix set, behaviour is unchanged.
• The prefix must be set in both places, nginx and SERVICE_BASE_PATH. Otherwise cookies are set for / and redirects go to the host root.
• With a prefix set, cookies are scoped to it, so browsers must use the prefixed URL. Bearer-token clients are unaffected.
• This touches cookies, redirects and auth flows, so it should get a security review.
Validation
• go vet ./... and go test ./... pass.
• Frontend: 674 Vitest tests pass and npm run check is clean. The production build emits relative asset and font URLs.
• New tests:
• NormalizeBasePath, including cookie and header injection attempts;
• state-cookie issue and clear paths under a prefix;
• logout cookie clears under a prefix;
• prefixed `loginUrl`s;
• the OIDC callback redirect under a prefix;
• the frontend basePath following <base href>.
• Manual: the built SPA loaded under /osctrl/ through a mock server that copies the nginx rewrite. /osctrl/ redirected to /osctrl/login, the logos and fonts loaded, and the console showed no errors.
• Not validated: the nginx config itself (nginx isn't installed locally), a real OIDC or SAML login under a prefix, an editor page under a prefix, and Playwright.
jmpsec/osctrlGitHub
10/31/2026, 10:47 AM