Cheia ta către API-ul Anthropic (Claude). Plătită per-token de tine, fără cap.
Greșeala #1 a vibe coderilor: scapi cheia API. Bot-uri scrapează GitHub și Discord în continuu. În prima săptămână de proiect, 80% dintre developeri au făcut deja măcar o greșeală din cele 5 de mai jos. Hai să le facem vizibile — ca să te eviți.
Aceeași variabilă — același nume — poate să existe (sau NU) în 4 contexte cu reguli complet diferite. 80% din confuziile despre „de ce nu merge cheia mea?" și „de ce e expusă cheia mea?" vin din amestecul ăsta.
Fișierul pe care îl vezi tu când lucrezi local. Trăiește pe disk-ul tău, nu pleacă nicăieri (dacă l-ai .gitignore-uit).
vizibil doar localNext.js citește valorile la moment de build și le „îngheață” în output. Variabilele cu prefix NEXT_PUBLIC_ ajung în bundle JS livrat la browser.
NEXT_PUBLIC_ → publicPe serverul aihost (sau Vercel), variabilele se citesc la fiecare request. Server actions, API routes, getServerSideProps — toate aici.
private la serverBrowserul vede DOAR ce a fost compilat în bundle (NEXT_PUBLIC_ + ce-i pasezi explicit). Orice e aici e pentru ORICINE deschide DevTools.
vizibil oricuiNext.js are o regulă simplă: orice variabilă cu prefix NEXT_PUBLIC_ e inclusă în bundle-ul JavaScript livrat la browser. Asta înseamnă vizibilă oricui deschide DevTools. Iată ce poți / NU poți pune cu acest prefix.
| Variabilă | Cu NEXT_PUBLIC_? | Detaliu |
|---|---|---|
| Supabase ANON key | DA, sigur | Da — e public by design. RLS policies la nivel DB protejează datele. |
| URL aplicației (NEXT_PUBLIC_APP_URL) | DA, sigur | Da — e oricum vizibil în adresă. |
| Google Analytics / GTM ID | DA, sigur | Da — astea sunt PUBLICE prin natură (rulează în browser). |
| Stripe Publishable key | DA, sigur | Da — există anume pentru client (vs. secret key care NICIODATĂ). |
| Anthropic / OpenAI / Gemini API key | NU, NICIODATĂ | NU. Cu NEXT_PUBLIC_ → cheia ta în bundle JS → atacator face drain la cont $$. |
| Supabase SERVICE_ROLE key | NU, NICIODATĂ | NU. Bypass total RLS. Cu acces public = full DB read+write+delete. |
| DATABASE_URL | NU, NICIODATĂ | NU. Conține user+parolă Postgres. Atacator se conectează direct. |
| JWT_SECRET / BETTER_AUTH_SECRET | NU, NICIODATĂ | NU. Cu el atacatorul semnează tokens valide de oricare user. |
| GitHub Personal Access Token | NU, NICIODATĂ | NU. Permite push/pull la repo-urile tale, ștergeri, totul. |
Severity bazat pe pagube reale. Roșu sus = ești fript. Verde = poți lăsa public (cu RLS configurat). Pentru fiecare cheie: dacă e safe public, ce face și exact ce-ți strică un atacator.
Cheia ta către API-ul Anthropic (Claude). Plătită per-token de tine, fără cap.
Cheia OpenAI (GPT, Codex, embeddings). La fel — pay-as-you-go, fără limită implicită.
Cheia Google AI Studio / Gemini. Free tier mai generos, dar tot are quota.
Cheia publică Supabase. E proiectată să fie în browser. Securitatea reală vine din RLS policies pe tabele.
Cheia super-admin Supabase. BYPASS total la RLS. Toate restricțiile sunt ignorate.
postgres://user:parolă@host:5432/db — connection string complet. Cu el atacatorul se conectează direct la DB.
Cheia cu care semnezi cookie-urile de sesiune. Dacă o ai, generezi sesiuni valide pentru orice user.
Personal Access Token GitHub — conform scope-ului, poate face push/pull/delete la repo-urile tale.
Token Cloudflare cu permisiuni DNS. Folosit de Traefik pentru ACME DNS-01 challenge.
Credentialele cu care trimiți email. Magic link, parole reset, notificări.
Pe containerul aihost, cheia ta nu pleacă de pe server (decât când Claude o trimite la API-ul Anthropic, ca antet HTTP). Iată fluxul exact, pas cu pas.
source ~/.aihost/agent-keys.env automat la fiecare SSH-in. Cheia devine variabilă de mediu în shell-ul tău.claude, citește process.env.ANTHROPIC_API_KEY și o trimite în antet la API-ul Anthropic.process.env.X le accesează server-side. NEXT_PUBLIC_X ajunge în bundle JS la browser.~/.aihost/agent-keys.env e creat la provision cu permisiuni 600 (doar tu citești). ~/project/.env.local e în .gitignore-ul template-ului. Containerul nu expune process.env la rețea. Logs Anthropic — pe cont propriu (nu trimite cheia ta nimănui altui).Date concrete. Nu „ai putea pierde bani" — sume reale, cu timeline, văzute în comunitate în 2024-2025.
| Cheie scapată | Cost / pagubă | Cât de repede |
|---|---|---|
| ANTHROPIC_API_KEY scapată | 1000-5000$ overnight | drain în <8h |
| OPENAI_API_KEY scapată | 500-3000$ overnight | drain în <8h |
| SUPABASE_SERVICE_ROLE_KEY | data breach total | <5 minute |
| DATABASE_URL public | DROP/exfiltrate orice | <5 minute |
| GITHUB_TOKEN cu repo:write | cod rescris / repos furate | <10 minute |
| BETTER_AUTH_SECRET | spoof oricărui user | imediat |
spending limit în dashboard ca prim safety net. Dacă scapă cheia, măcar bill-ul e cap-ed la cât ai zis tu (50$, 100$, ce te face confortabil). Default-ul e UNLIMITED.Nu sunt teoretice. Toate cinci s-au întâmplat unor developeri pe care îi cunoști (sau ție, dar n-ai realizat încă). Pentru fiecare — fix concret.
Faci git add . fără să verifici. .env intră în repo. Crezi că-l ștergi cu un commit nou — NU FUNCȚIONEAZĂ. Git history păstrează blob-ul pentru totdeauna. GitHub indexează commit-uri vechi pentru bot-uri de scraping. În sub 30 minute primești un email „cheia ta a fost detectată într-un repo public”.
.env* în .gitignore ÎNAINTE de primul commit. Dacă deja ai commitat: rotezi imediat cheia (nu te baza pe `git rebase` sau `git filter-branch` — nu sunt suficiente). Folosește `gitleaks` ca pre-commit hook.Cer ajutor. Lipești tot blocul de cod cu DATABASE_URL real. Postul rămâne acolo. Bot-uri scrapează GitHub Issues, Discord public, Stack Overflow non-stop. Cheia ta e descoperită în câteva ore.
<REDACTED> sau sk-...xxx. La AI chat (ChatGPT/Claude direct), conversațiile pot fi folosite pentru training — la fel, redactează.Faci poză la ecran ca să arăți unui prieten un bug. În colțul terminalului — output-ul lui `env` cu toate variabilele. Posti pe Twitter/Telegram. Atacatorul face screenshot zoom + OCR.
clear && reset sau deschide un tab nou. Pentru video-uri/loom, folosește blur peste secțiunile cu chei.Vrei să folosești cheia într-un component React. Nu funcționează (e undefined). Adăugi NEXT_PUBLIC_ — funcționează acum. NU ai realizat că tocmai ai pus cheia secretă în bundle JS livrat la browser.
/api/foo) care rulează server-side. Niciodată nu rezolvi un „undefined” client cu NEXT_PUBLIC_ pentru chei sensibile.Throw error cu mesajul „Failed to call Anthropic with key sk-ant-...”. Sentry / Datadog / log file pe server captează stack trace-ul. Cheia ta e acum în log retention 30-90 zile, accesibilă oricui din echipă (sau atacator dacă scapă logs).
console.error("Anthropic call failed", err.message), nu err brut. Configurează Sentry să facă scrubbing pe pattern-uri ca sk-*, eyJ*.Exemple anonimizate, dar reprezentative. Recunoști vreunul în propriul trecut? E timpul să rotești cheile.
Developer entuziast: „Am construit un chatbot în 2 ore!" + screenshot cu cod în VS Code. În colțul ecranului — terminal cu output `env`.
Commit message: „temp config for testing". Body diff conține .env cu DATABASE_URL real către un Supabase project live.
Userul lipește tot middleware.ts cu BETTER_AUTH_SECRET hardcodat (nu citit din env). Postul are 200 views. Răspunsurile menționează problema, dar update-ul postului niciodată nu vine.
Creator face setup live. La minutul 12:34, terminalul lui arată clar comanda echo $ANTHROPIC_API_KEY cu output. Video-ul are 50k views înainte ca el să-l realizeze și să rotească cheia.
Loom 5 min cu „uite ce am făcut". `.env.local` apare deschis în VS Code în secțiunea side-by-side. Loom URL e public-by-link.
Userul lipește tot proiectul în chat (incluzând .env) ca AI-ul să aibă context. Conversația rămâne în istoric Anthropic/OpenAI per ToS.
Configurația minimă să nu te trezești cu un email de la Anthropic „cheia ta a generat 4321$ peste noapte".
.env, .env.local, .env.*.local ÎNAINTE de primul commit. Verifică cu git check-ignore .env.local.gitleaks sau trufflehog. Detectează automat pattern-uri sk-ant-*, sk-proj-*, eyJ* etc. înainte să commit-ezi.clear + tab nou.sk-*, eyJ*, ca să nu ajungă chei în error logs.chmod 600 ~/.aihost/agent-keys.env). Pe aihost setat by default.Realizezi că ai scăpat o cheie. Ordinea contează — fă-le în ordinea asta:
.env.local cu noua cheie pe toate mediile (local + container aihost).git filter-repo + force push, dar cheia e deja compromisă, asta e cleanup), șterge tweet-ul, redactează postul, actualizează screenshot-ul.Containerul tău vine cu ~/.aihost/agent-keys.env permisiuni 600, .gitignore corect, separare clară între cheile agent și cheile aplicației, niciodată expuse la internet. Nu-ți rezolvăm noi greșelile umane (lipirea cheii în chat) — dar default-ul e safe.
Vezi și stack-ul modern explicat · WordPress vs vibe coding · ghid migrare WordPress → Next.js