API-key gelekt of onverwacht hoge rekening: dit doe je nu
Trek de key vandaag nog in en maak een nieuwe, ook als je niet zeker weet of hij misbruikt is. Zet daarna een uitgavenlimiet, haal de key uit je code en je git-geschiedenis, en vraag de provider om naar de rekening te kijken. Een gelekte key blijft geldig tot jij hem intrekt, dus de volgorde doet ertoe.
Een gelekte API-key is geen ramp als je snel bent. Het geld dat al weg is, krijg je misschien niet terug. Het geld dat er morgen bij komt wel: dat houd je tegen door de key in te trekken. Hieronder eerst hoe je het merkt, dan waarom het gebeurt, dan de stappen.
Herken je dit?
- Een rekening van OpenAI of Anthropic die tien keer hoger is dan normaal, terwijl je app niet drukker werd.
- Een mail van GitHub dat er een secret in je repository staat, of een mail van de provider dat je key is uitgeschakeld.
- In het verbruiksoverzicht staan aanroepen naar modellen die jouw app niet gebruikt, of verkeer midden in de nacht.
- In Stripe staan klanten, refunds of betalingen die niemand van jullie heeft gemaakt.
- Je opent de broncode van je eigen site in de browser en ziet daar een regel die begint met
sk-.
Eén van die vijf is genoeg om de stappen hieronder te doorlopen.
Hoe een key uitlekt
Bijna altijd op een van drie manieren. De eerste: de key staat in de frontend. Een AI-builder die een chatfunctie of betaling inbouwt, zet de aanroep naar OpenAI of Stripe vaak rechtstreeks in de browsercode, omdat dat in de preview meteen werkt. Alles wat de browser krijgt, kan iedere bezoeker lezen.
De tweede: de key staat in een omgevingsvariabele die naar de browser gaat. In Vite gaat alles met VITE_ ervoor mee in de build, in Next.js alles met NEXT_PUBLIC_. Een key in VITE_OPENAI_API_KEY is dus geen geheim, ook al staat hij in een .env-bestand.
De derde: de key staat in de git-geschiedenis. Iemand zette hem ooit in een bestand, haalde hem er later weer uit, en pushte naar een openbare repository. De laatste versie is schoon, de commit van drie weken geleden niet. Bots scannen openbare repositories continu op die patronen, en een key is soms binnen minuten na de push in gebruik.
Zo los je het op, in vijf stappen
1. Trek de key in en maak een nieuwe
Dit eerst, vóór je gaat zoeken hoe het kwam. Elke provider heeft er een pagina voor:
- OpenAI: in het dashboard onder API keys de key verwijderen en een nieuwe maken, bij voorkeur per project.
- Anthropic: in de Console onder API keys de key uitschakelen en een nieuwe maken.
- Stripe: in het Dashboard onder Developers › API keys de secret key laten roteren. Stripe kan de oude een tijdje laten doorwerken; kies hier voor direct.
- Supabase: een uitgelekte service_role-key of secret key vervangen in de API-instellingen van je project. Gebruik je nog de oude JWT-keys, dan betekent vervangen dat je het JWT-secret vernieuwt, en dan worden ook alle ingelogde gebruikers uitgelogd. Doe het toch.
Zet de nieuwe key alleen op de server: in de omgevingsvariabelen van je hosting, zonder VITE_- of NEXT_PUBLIC_-voorvoegsel.
2. Zet een limiet op wat de key kan kosten
Bij OpenAI en Anthropic stel je per project of werkruimte een budget en een melding in. Zet dat budget op wat je app in een normale maand verbruikt, met wat ruimte. Een limiet voorkomt niet dat een key uitlekt, wel dat een uitgelekte key je een maand huur kost.
Bij Stripe werkt het anders: daar beperk je wat een key mag. Een restricted key die alleen betalingen mag aanmaken, kan geen klanten opvragen en geen refunds doen.
3. Zoek waar de key nog meer staat
Zoek in je eigen code en in de build die online staat. Een key van OpenAI begint met sk-, van Anthropic met sk-ant-, een live secret key van Stripe met sk_live_.
grep -rn "sk-\|sk_live_\|service_role" src/ dist/Zoek daarna in de hele geschiedenis van je repository, niet alleen in de laatste versie. Gitleaks is een gratis scanner die precies dat doet.
gitleaks git --verbose .4. Haal de key uit de git-geschiedenis
Met git filter-repo vervang je de key in elke commit door een vaste tekst. Daarna moet je force-pushen, en moet iedereen die de repository heeft opnieuw clonen.
# vervangen.txt
sk-proj-oude-key-hier==>VERWIJDERD
git filter-repo --replace-text vervangen.txt
git push --force --allWeet wat dit wel en niet doet. Het haalt de key uit je repository, maar niet uit de forks en clones die al bestaan. Daarom is stap 1 de echte oplossing en is deze stap opruimen.
5. Vraag de provider om naar de rekening te kijken
Schrijf de support van OpenAI, Anthropic of Stripe aan met wat je weet: sinds wanneer de key openstond, wanneer je hem introk, en welk verbruik niet van jou is. Voeg het verbruiksoverzicht toe. Of je iets terugkrijgt, beslist de provider. Een duidelijke tijdlijn en een key die al is ingetrokken helpen.
Waar het daarna nog misgaat
- De nieuwe key komt op dezelfde plek. De oude is ingetrokken, de nieuwe staat weer in
VITE_OPENAI_API_KEY. Binnen een week begint het opnieuw. De aanroep naar de AI-provider moet via je eigen server of een serverless functie lopen. - Alleen de laatste commit opschonen. De key staat er niet meer in, maar wel in de geschiedenis. Zolang de key niet is ingetrokken, is hij nog steeds bruikbaar.
- De service_role-key als oplossing. Een app die “toegang geweigerd” geeft, krijgt de service_role-key in de frontend en werkt dan wel. Dat is geen oplossing: daarmee vervalt elke regel in je database. Lees eerst hoe Row Level Security werkt.
- Eén key voor alles. Dezelfde key in de preview, op je laptop en in productie betekent dat je bij een lek alles tegelijk moet vervangen. Een key per omgeving maakt de schade kleiner.
Wanneer je hulp nodig hebt
Weet je niet waar de key nog meer gebruikt wordt, staat de aanroep naar de AI-provider in de frontend en weet je niet hoe je hem naar een server verplaatst, of zit er klantdata achter de key? Dan is dit meer dan een key vervangen. Een gelekte database-key kan een datalek zijn dat je binnen 72 uur bij de Autoriteit Persoonsgegevens moet melden.
In onze securitycheck zoeken we uit waar je keys staan, wat ze kunnen, en wat er in je database openstaat. De andere problemen die we in AI-apps vaak zien, staan in je website is met AI gebouwd: dit gaat er waarschijnlijk mis, en alles over AI-apps staat bij apps afmaken en beveiligen.
Veelgestelde vragen
Is de anon-key of publishable key van Supabase ook een lek?
Ik heb de key uit mijn code gehaald. Is het dan opgelost?
Krijg ik mijn geld terug?
Hoe voorkom ik dat het opnieuw gebeurt?
Verder lezen
Een app die je met Lovable, Bolt, v0, Cursor of Claude bouwde: dichtzetten, afmaken en online houden.
- Securitycheck voor je AI-app
- Een vaste check van je app uit Lovable, Bolt, v0, Cursor of Claude Code: databaserechten, keys, inloggen, webhooks en de AVG-basis. Met een rapport en de fixes.
- AI-app laten afmaken
- Je prototype uit Lovable, Bolt, v0, Cursor of Claude Code werkt, maar is nog niet klaar voor klanten. Wij bouwen de rest: betalingen, rollen, e-mail, beheer, hosting en onderhoud.
- Supabase RLS controleren
- Je database testen zoals een buitenstaander dat doet: met de publieke key, als tweede gebruiker en in je opslag. Met de SQL om te ruime policies te vinden.
- Werkt niet na deploy
- Een witte pagina, een 404 bij verversen of een inloglink naar localhost: de vijf oorzaken en hoe je ze een voor een uitsluit.
- Lovable-app zelf hosten
- Van Lovable naar je eigen GitHub, domein en hosting, met of zonder eigen Supabase-project. Wat er meekomt, wat achterblijft, en waar Bolt en v0 anders werken.
Wij zoeken uit waar de key nog meer staat
De kennismaking is gratis. We reageren binnen één werkdag.




