How it works
Most services hand out two kinds of key. Publishable keys (Stripe's pk_ keys, Razorpay's key id, a Supabase publishable or anon key, a Firebase web config) are meant to sit in a website or app and only identify the account. Secret keys (Stripe's sk_ keys, Razorpay's key secret, Supabase's service role key, an OpenAI key) can move money, read every record or run up a bill, so they are only ever used from a server.
On a server, secrets live in environment variables: in development they come from a .env file listed in .gitignore, and in production from the host's settings or a secrets manager such as AWS Secrets Manager, Google Secret Manager, Doppler or Infisical. CI systems such as GitHub Actions keep their own encrypted secrets. Anything shipped to a browser or phone can be read by its user, and any variable prefixed NEXT_PUBLIC_ (Next.js) or VITE_ (Vite) is built into the code sent to browsers, so those prefixes are only for values that may be public.
Leaked keys are found fast, because bots scan public repositories for them; GitHub secret scanning and tools such as gitleaks can catch many before or just after they are pushed. Deleting a leaked key from the code is not enough, because it survives in Git history and in copies; revoke it and issue a new one. Keys scoped to only the permissions they need, rotated regularly, limit the damage when one escapes.
Related terms
More in Security
Secrets