import { PermissionAction } from '@supabase/shared-types/out/constants' import { JwtSecretUpdateStatus } from '@supabase/shared-types/out/events' import { useParams } from 'common' import { Loader } from 'lucide-react' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' import { Admonition, GenericSkeletonLoader } from 'ui-patterns' import { Input } from 'ui-patterns/DataInputs/Input' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { ConnectionIcon } from '@/components/interfaces/Connect/ConnectionIcon' import { ConnectButton } from '@/components/interfaces/ConnectButton/ConnectButton' import { AlertError } from '@/components/ui/AlertError' import { InlineLink } from '@/components/ui/InlineLink' import { getKeys, useAPIKeysQuery } from '@/data/api-keys/api-keys-query' import { useLegacyAPIKeysStatusQuery } from '@/data/api-keys/legacy-api-keys-status-query' import { useJwtSecretUpdatingStatusQuery } from '@/data/config/jwt-secret-updating-status-query' import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' export const APIKeys = () => { const { ref: projectRef } = useParams() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') const { data: settings, error: projectSettingsError, isError: isProjectSettingsError, isPending: isProjectSettingsLoading, } = useProjectSettingsV2Query({ projectRef }) const { data: legacyAPIKeysStatusData, isPending: isLoadingAPIKeysStatus } = useLegacyAPIKeysStatusQuery({ projectRef }, { enabled: canReadAPIKeys }) const { data: apiKeys, error: errorAPIKeys, isError: isErrorAPIKeys, isPending: isLoadingAPIKeys, } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) const { anonKey, serviceKey, publishableKey, secretKey } = getKeys(apiKeys) const hasNewAPIKeys = !!publishableKey && !!secretKey const isLegacyKeysEnabled = legacyAPIKeysStatusData?.enabled ?? false const isApiKeysEmpty = !hasNewAPIKeys && !anonKey && !serviceKey const { data, error: jwtSecretUpdateError, isError: isJwtSecretUpdateStatusError, isPending: isJwtSecretUpdateStatusLoading, } = useJwtSecretUpdatingStatusQuery( { projectRef }, { enabled: !isProjectSettingsLoading && isApiKeysEmpty } ) const isLoading = isLoadingAPIKeys || isLoadingAPIKeysStatus || isProjectSettingsLoading const isError = isErrorAPIKeys || isProjectSettingsError || isJwtSecretUpdateStatusError // Only show JWT loading state if the query is actually enabled const showJwtLoading = isJwtSecretUpdateStatusLoading && !isProjectSettingsLoading && isApiKeysEmpty const jwtSecretUpdateStatus = data?.jwtSecretUpdateStatus const isNotUpdatingJwtSecret = jwtSecretUpdateStatus === undefined || jwtSecretUpdateStatus === JwtSecretUpdateStatus.Updated const protocol = settings?.app_config?.protocol ?? 'https' const endpoint = settings?.app_config?.endpoint const apiUrl = `${protocol}://${endpoint ?? '-'}` return ( Project API Your API is secured behind an API gateway which requires an API Key for every request.
You can use the parameters below to use Supabase client libraries.
{isLoading ? ( ) : isError ? ( ) : showJwtLoading ? (

JWT secret is being updated

) : !isLegacyKeysEnabled && !hasNewAPIKeys ? ( Create a set of API keys from your{' '} project settings {' '} to connect to your project } /> ) : ( <>

API Key

{anonKey?.name} public
) } description={

This key is safe to use in a browser if you have enabled Row Level Security (RLS) for your tables and configured policies. You may also use the{' '} {hasNewAPIKeys ? 'secret' : 'service'} key which can be found{' '} here {' '} to bypass RLS.

} >

Choose your preferred framework

Connect to your project from a variety of frameworks, ORMs, an MCP server, or even directly via connection string.

)} ) }