Some services issue keys in pairs. Stripe gives you a publishable key beginning pk_ for Stripe.js and mobile SDKs, and a secret key beginning sk_ for your server. Stripe's documentation says the publishable key can identify your account and create tokens from payment details but cannot perform sensitive operations. Supabase follows the same model with keys beginning sb_publishable_ and sb_secret_, replacing the older anon and service role keys.
Finding a publishable key in your page source is normal and is not a leak. The two real mistakes go the other way. The first is putting the secret key where the publishable one belongs, which AI tools do when a call fails with a permissions error and the quickest fix is the more powerful key. The second is assuming that the publishable key protects your data. It does not. With Supabase, anyone holding it can query your database directly, and only your row level security policies decide what comes back.
Check the prefix of every key in your frontend code and environment files. Anything that starts with sk_, sb_secret_ or is labelled service role belongs only on the server. Then make sure the data reachable with the publishable key is locked down by policies, because that key is public by design.
pk_live_... browser or mobile app
sb_publishable_... browser or mobile app
sk_live_... server only
sb_secret_... server only