diff --git a/messages/en-US.json b/messages/en-US.json
index 52458fcbe..b58ebfd0c 100644
--- a/messages/en-US.json
+++ b/messages/en-US.json
@@ -1678,6 +1678,9 @@
"commandVirtualApiKeys": "Virtual API Keys",
"virtualApiKeysTitle": "Manage Virtual API Keys",
"virtualApiKeysDescription": "Create and manage manual API keys for AI Gateway access to public AI gateways",
+ "virtualApiKeysBannerTitle": "Identity Keys for Every User",
+ "virtualApiKeysBannerDescription": "Every user already has an identity key available at {keysUrl}. You can also manually generate keys here that grant direct access to public AI gateways.",
+ "virtualApiKeysBannerButtonText": "View Identity Keys",
"virtualApiKeys": "Virtual API Keys",
"virtualApiKeysSearch": "Search keys...",
"virtualApiKeysCreate": "Create Virtual API Key",
@@ -1742,6 +1745,8 @@
"myVirtualApiKeysViewSecretDescription": "This secret authenticates you to AI Gateway resources",
"aiProvidersTitle": "AI Providers",
"aiProvidersDescription": "Connect model providers for AI workloads in this organization",
+ "aiProvidersBannerTitle": "Connect Model Providers",
+ "aiProvidersBannerDescription": "Providers are the model backends Pangolin uses for AI workloads. Connect OpenAI, Anthropic, and other providers here, then attach them to public AI gateways so users can call models with identity-aware access, budgets, and logging.",
"aiProvidersAdd": "Add Provider",
"aiProvidersSearch": "Search providers...",
"aiProvidersEmpty": "No AI providers yet",
diff --git a/src/app/[orgId]/settings/ai-providers/page.tsx b/src/app/[orgId]/settings/ai-providers/page.tsx
index 024170590..572ce90d4 100644
--- a/src/app/[orgId]/settings/ai-providers/page.tsx
+++ b/src/app/[orgId]/settings/ai-providers/page.tsx
@@ -1,3 +1,4 @@
+import AiProvidersBanner from "@app/components/AiProvidersBanner";
import AiProvidersTable from "@app/components/AiProvidersTable";
import SettingsSectionTitle from "@app/components/SettingsSectionTitle";
import { internal } from "@app/lib/api";
@@ -49,6 +50,8 @@ export default async function AiProvidersPage({ params, searchParams }: Props) {
description={t("aiProvidersDescription")}
/>
+
+
({
diff --git a/src/app/[orgId]/settings/virtual-api-keys/page.tsx b/src/app/[orgId]/settings/virtual-api-keys/page.tsx
index ba8f4ea01..28a73253e 100644
--- a/src/app/[orgId]/settings/virtual-api-keys/page.tsx
+++ b/src/app/[orgId]/settings/virtual-api-keys/page.tsx
@@ -6,6 +6,7 @@ import { redirect } from "next/navigation";
import { cache } from "react";
import { GetOrgResponse } from "@server/routers/org";
import OrgProvider from "@app/providers/OrgProvider";
+import VirtualApiKeysBanner from "@app/components/VirtualApiKeysBanner";
import VirtualApiKeysTable, {
type VirtualApiKeyRow
} from "@app/components/VirtualApiKeysTable";
@@ -142,6 +143,8 @@ export default async function VirtualApiKeysPage(
description={t("virtualApiKeysDescription")}
/>
+
+
{
+ const t = useTranslations();
+
+ return (
+ }
+ description={t("aiProvidersBannerDescription")}
+ />
+ );
+};
+
+export default AiProvidersBanner;
diff --git a/src/components/VirtualApiKeysBanner.tsx b/src/components/VirtualApiKeysBanner.tsx
new file mode 100644
index 000000000..dd2aa1186
--- /dev/null
+++ b/src/components/VirtualApiKeysBanner.tsx
@@ -0,0 +1,45 @@
+"use client";
+
+import { Button } from "@app/components/ui/button";
+import { useEnvContext } from "@app/hooks/useEnvContext";
+import { ArrowRight, KeyRound } from "lucide-react";
+import { useTranslations } from "next-intl";
+import Link from "next/link";
+import DismissableBanner from "./DismissableBanner";
+
+type VirtualApiKeysBannerProps = {
+ orgId: string;
+};
+
+export const VirtualApiKeysBanner = ({ orgId }: VirtualApiKeysBannerProps) => {
+ const t = useTranslations();
+ const { env } = useEnvContext();
+
+ const dashboardUrl = env.app.dashboardUrl?.replace(/\/$/, "") ?? "";
+ const keysUrl = dashboardUrl
+ ? `${dashboardUrl}/${orgId}/keys`
+ : `/${orgId}/keys`;
+
+ return (
+ }
+ description={t("virtualApiKeysBannerDescription", { keysUrl })}
+ >
+
+
+
+
+ );
+};
+
+export default VirtualApiKeysBanner;