diff --git a/canvas/src/components/settings/TokensTab.tsx b/canvas/src/components/settings/TokensTab.tsx index 092e4df56..5210b8a17 100644 --- a/canvas/src/components/settings/TokensTab.tsx +++ b/canvas/src/components/settings/TokensTab.tsx @@ -16,7 +16,40 @@ interface TokensTabProps { workspaceId: string; } +// The settings panel passes the literal sentinel "global" when no canvas +// node is selected. Workspace tokens are inherently per-workspace — there +// is no /workspaces/global/tokens endpoint (querying the uuid column with +// "global" 500s on Postgres). The org-wide equivalent lives in the +// separate "Org API Keys" tab. Mirrors the sentinel-awareness that +// api/secrets.ts already has (workspaceId === 'global' → /settings/secrets). +const GLOBAL_WORKSPACE_ID = 'global'; + export function TokensTab({ workspaceId }: TokensTabProps) { + if (workspaceId === GLOBAL_WORKSPACE_ID) { + return ( +
+ Bearer tokens for authenticating API calls to this workspace. +
+Select a workspace node first
++ Workspace tokens are scoped to a single workspace. Select a node + on the canvas to manage its tokens, or use the{' '} + Org API Keys tab + for org-wide API keys. +
++ {SECRET_SHAPE_DENIED_MARKER} +
++ The platform refused to surface this file because its + path or content matched a credential-shape pattern. + The bytes never left the workspace container. +
++ If this is a false positive (test fixture, docs example, + or content that happens to share a credential's shape), + rename the file or adjust the content via the workspace + terminal so the regex no longer matches, then refresh. +
+