redirect to api key page when access gateway in browser

This commit is contained in:
miloschwartz
2026-08-12 11:15:50 -04:00
parent 833b27ab4a
commit 379b53bcca
4 changed files with 36 additions and 7 deletions
+9 -3
View File
@@ -337,10 +337,16 @@ export async function verifyResourceSession(
// Only offer a browser redirect to clients that can actually follow one and log in
// (an interactive browser). Non-browser clients (curl, scripts, bots, etc.) just get
// an unauthorized response from Badger instead of a login redirect URL.
// Inference browsers go to the dashboard keys page (not back to the inference host)
// so a valid session cannot create a redirect loop.
const redirectPath = clientIsBrowser
? `/auth/resource/${encodeURIComponent(
resource.resourceGuid
)}?redirect=${encodeURIComponent(originalRequestURL)}`
? mode === "inference"
? `/${resource.orgId}/resource/${encodeURIComponent(
resource.resourceGuid
)}/keys`
: `/auth/resource/${encodeURIComponent(
resource.resourceGuid
)}?redirect=${encodeURIComponent(originalRequestURL)}`
: undefined;
// Virtual API keys for public inference resources (provider-style auth headers).
@@ -42,6 +42,7 @@ export type GetResourceAuthInfoResponse = {
skipToIdpId: number | null;
orgId: string;
postAuthPath: string | null;
mode: string;
};
export async function getResourceAuthInfo(
@@ -227,7 +228,8 @@ export async function getResourceAuthInfo(
whitelist: effectivePolicy?.emailWhitelistEnabled ?? false,
skipToIdpId: effectivePolicy?.idpId ?? resource.skipToIdpId,
orgId: resource.orgId,
postAuthPath: resource.postAuthPath ?? null
postAuthPath: resource.postAuthPath ?? null,
mode: resource.mode
},
success: true,
error: false,
@@ -41,7 +41,9 @@ export default async function ResourceKeysPage(props: ResourceKeysPageProps) {
const user = await getUser();
if (!user) {
redirect("/");
redirect(
`/auth/login?redirect=/${orgId}/resource/${resourceGuid}/keys`
);
}
const cookieHeader = await authCookieHeader();
+21 -2
View File
@@ -71,6 +71,9 @@ export default async function ResourceAuthPage(props: {
);
}
const isInference = authInfo.mode === "inference";
const keysPath = `/${authInfo.orgId}/resource/${authInfo.resourceGuid}/keys`;
const hasLoginPageDomain = await isOrgSubscribed(
authInfo.orgId,
tierMatrix.loginPageDomain
@@ -159,10 +162,18 @@ export default async function ResourceAuthPage(props: {
if (user && !user.emailVerified && env.flags.emailVerificationRequired) {
redirect(
`/auth/verify-email?redirect=/auth/resource/${authInfo.resourceGuid}`
`/auth/verify-email?redirect=${encodeURIComponent(
isInference
? keysPath
: `/auth/resource/${authInfo.resourceGuid}`
)}`
);
}
if (isInference && !user) {
redirect(`/auth/login?redirect=${encodeURIComponent(keysPath)}`);
}
const cookie = await authCookieHeader();
// Check org policy compliance before proceeding
@@ -181,7 +192,9 @@ export default async function ResourceAuthPage(props: {
// If user is not compliant with org policies, show policy requirements
if (orgPolicyCheck && !orgPolicyCheck.allowed && orgPolicyCheck.policies) {
const resourceAuthPageUrl = `/auth/resource/${authInfo.resourceGuid}${redirectUrl !== authInfo.url ? `?redirect=${encodeURIComponent(redirectUrl)}` : ""}`;
const resourceAuthPageUrl = isInference
? keysPath
: `/auth/resource/${authInfo.resourceGuid}${redirectUrl !== authInfo.url ? `?redirect=${encodeURIComponent(redirectUrl)}` : ""}`;
return (
<div className="w-full max-w-md">
<OrgPolicyRequired
@@ -193,6 +206,12 @@ export default async function ResourceAuthPage(props: {
);
}
// Inference resources never establish a resource session on the inference
// host. Authenticated users retrieve their virtual API key on the dashboard.
if (isInference) {
redirect(keysPath);
}
if (!hasAuth) {
// no authentication so always go straight to the resource
redirect(redirectUrl);