Skip to content
Ketryon
Blog

9 min read

Has your Lovable or Supabase key ended up on GitHub?

GitHub now finds more leaked Lovable and Supabase keys, but a warning is only the start of the work.

By Written with AI assistance from the source

Mist-covered cliffs along a calm coast
Photo: Fabio Montello on Unsplash

What GitHub has actually changed

In October 2026, GitHub expanded its secret scanning to support more types of secrets from Lovable and Supabase. Secret scanning looks for known formats of API keys, access tokens and other credentials that have ended up in a repository.

According to GitHub's changelog, GitHub now recognises Lovable API keys, as well as Supabase OAuth tokens and scoped personal access tokens. This does not only apply to files in the latest version of the project. GitHub also searches Git history, branches and content around pull requests and issues. When support for a new type of secret is added, older code may therefore trigger an alert.

The detectors do not work in the same way for every provider. Lovable participates in GitHub's partner programme. When a supported Lovable key is found in a public repository, GitHub can report it directly to Lovable. Lovable states that exposed API keys beginning with lov_ are then revoked automatically and the workspace owner is notified.

This means you may not necessarily receive a standard warning in GitHub first. An integration job may instead stop working because the key has already been revoked.

For the new Supabase formats, GitHub creates a secret scanning alert when the repository settings and GitHub plan support it. GitHub's basic scanning runs automatically in public repositories. For private repositories, you need to check which security features are enabled in the organisation.

The important thing is to treat detection as a safety net, not as a security model. An attacker or automated search service may find the key before GitHub, the provider or you have time to respond.

Not all Supabase keys are secret

The word key can easily lead to the wrong conclusion. Some keys are intended to be used in client-side code, while others provide privileged access and must never reach the browser.

Supabase distinguishes between publishable keys and secret keys. The publishable key identifies your app but only provides the access allowed by the database permissions and Row Level Security. It can therefore be used in a browser. The older anon key has an equivalent client role.

A Supabase secret key or older service_role key is something entirely different. It is used in trusted backend code and can bypass Row Level Security. If it ends up in client-side code or Git history, it should be treated as compromised.

The Supabase tokens added in GitHub's update are mainly intended for the Supabase Management API:

  • Scoped personal access token is used by tools such as the CLI, CI workflows, MCP servers and automation. The token can be limited to selected projects and permissions.
  • OAuth access token is used when an integration acts on behalf of a Supabase user after approval.

These are not the same as the publishable key your frontend uses to read data through the Supabase client. The update does not mean that every visible Supabase key is an incident.

What matters is what the credential can do:

Type of credentialWhere it may be usedWhat you should check
Supabase publishable or older anonClient-side codeThat RLS and database permissions are configured correctly
Supabase secret or older service_roleBackendThat it is never built into the client or committed
Supabase personal access tokenCLI, CI or server automationThat the token has the minimum necessary permissions
Lovable API keyTrusted server or automationThat it is stored as a secret and has restricted access
Stripe secret keyBackendThat payment requests are made on the server side

A publishable key does not make the database secure by itself. Security depends on table permissions, RLS policies and checks on the signed-in user. If an anonymous user can read or change everything, the problem is the database configuration, not the fact that the publishable key is visible.

Why client-side code and environment files become traps

Code that runs in the browser is effectively public. A visitor can inspect JavaScript files, network requests and values built into the application. This also applies when the repository is private.

Variable names with prefixes such as VITE_ or NEXT_PUBLIC_ normally indicate that the value should be sent to the client. The prefix does not protect anything. It does the opposite: the build tool makes the value available in the browser.

This is reasonable for a Supabase URL and a publishable Supabase key. It is wrong for a Lovable API key, Supabase secret key, service_role, Stripe secret key or personal access token.

A .env file is not automatically a secure vault either. It is only a file format for configuration. Its security depends on whether the file is committed, which variables are built into the client and where the app runs.

Lovable also has a workflow that differs from many traditional projects. Lovable's documentation states that the project's .env file should be included in the repository because VITE_ values are needed for previews and published builds. The file must therefore contain only values that can safely be made public.

Private values in Lovable should instead be stored in Secrets and used by Edge Functions or other server functions. They are injected at runtime and are not sent to the browser. On Vercel, the corresponding values should be added to the project's environment variables without a public prefix and only read by server-side code.

Common leaks happen when you:

  • paste a real key into code to test an integration quickly
  • give a secret variable a public client prefix
  • commit a local environment file before .gitignore is configured correctly
  • put the key in an example, log or error message
  • send a key in a prompt, comment or pull request
  • reuse the same privileged key across several services
  • move a server request to the frontend to solve a CORS or authentication problem

A good rule of thumb is that the browser should only call your own backend when an external service requires a secret key. The backend function reads the secret from the platform's secret manager, checks the user and then makes the onward request.

What to do if a key has leaked

Deleting the line and making a new commit is not enough. The key may remain in Git history, old builds, caches, logs and local copies. Assume that a committed secret has already been copied.

Follow this order:

  • Identify exactly what type of key it is. Check the provider, permissions, environment and which systems use it.
  • Disable or revoke the old key. Do not wait for the code to be cleaned up. If Lovable has already revoked the key, verify its status in the workspace settings.
  • Create a replacement with fewer permissions. Use separate keys for different integrations and restrict projects, scopes, validity periods and permitted IP addresses where the service supports it.
  • Update all dependencies. Replace the value in Lovable Secrets, Supabase, Vercel, GitHub Actions and other environments that use the key.
  • Redeploy the affected services. An updated environment variable does not always help an already built client or running process.
  • Check that the old key no longer works. Test without reactivating it or adding it back to the code.
  • Review logs and activity. Look for unexpected API requests, changed project settings, new users, database queries or deployments from the period after the exposure.
  • Remove the secret from the code. Move the request to server-side code and use the platform's secret manager.
  • Assess whether the Git history needs to be rewritten. This may be justified if the value still appears in searches or if the repository will be shared further, but rewriting never replaces revocation.

For a leaked Supabase personal access token, delete the token and create a new one with scoped permissions. If a Supabase secret key or service_role has leaked, you need to rotate the project's server key and check data access. If an OAuth authorisation has been compromised, the connection needs to be revoked so that the associated token cannot be renewed.

Do not close the GitHub alert as a false positive simply because the file has been deleted. Document which key was revoked, where the replacement is stored and which checks you carried out.

Build a routine that catches the next mistake

Secret scanning is most useful when it forms part of a simple process. Check GitHub's Security view, enable available protection against pushing secrets and run Lovable's security scanning after changes to integrations or backend code.

Also review the variables in the project manually:

  • Which values are intended to be public?
  • Which variables have VITE_ or NEXT_PUBLIC_?
  • Is there a server key in the frontend code?
  • Do Supabase tables with client access have working RLS policies?
  • Do CI workflows use scoped tokens instead of account-wide access?
  • Does each integration have its own key that can be revoked without stopping the rest of the system?
  • Do old keys remain in Git history, examples or documentation?
  • Do you know who is responsible for responding to security alerts?

The important shift is to stop thinking of environment variables as automatically private. Instead, ask where the value is used, where the code runs and what permissions the credential provides. This makes it clearer what can be kept in the client and what must remain on the server side.

When a quick Lovable prototype starts handling real users, data and integrations, key management also needs to be part of the work from prototype to product.


Source: GitHub changelog

Want to know what your build would take?

Three questions, then you get a clickable sketch for free.

Tell me where you are
← All articles

More from Ketryon

Just need a page or a video?

Two standalone services for when a whole subscription is more than you need — a landing page or a launch video, made by the same person.