blackdark
Herramientasapi keygithubseguridad.envgitignoreopenaiclaudegemini

Claves de API en GitHub: cómo protegerlas antes de que te llegue la factura

Subes tu app a GitHub con la clave de OpenAI, Claude o Gemini dentro y alguien la usa a tu costa. Las 4 cosas que tienes que hacer: .env, .gitignore, límite de gasto y revocar la clave si ya la subiste. Con ejemplos para Node y Python.

Por BlackdarkActualizado el 8 min de lectura
Ir directo a las 4 cosas

Subes tu primera app a GitHub, contento. A los días te llega una factura de tu proveedor de IA que no cuadra con nada de lo que has hecho. El motivo casi siempre es el mismo: tu clave de API estaba dentro del código y alguien la ha usado a tu costa. Hay bots que rastrean los repositorios públicos buscando justo eso.

Una clave de API es como la tarjeta de crédito de tu cuenta de OpenAI, Claude o Gemini: quien la tiene, gasta a tu nombre. La buena noticia es que protegerla son 4 cosas y se hacen en diez minutos.

Las 4 cosas

  1. Saca la clave del código

    Guárdala en un archivo .env y haz que tu código la lea desde ahí.

  2. Añade .env al .gitignore

    Así el archivo con la clave nunca sale de tu ordenador.

  3. Pon un límite de gasto

    En OpenAI, en la Claude Console y en Google AI Studio. Si algo falla, la factura tiene techo.

  4. Si ya la subiste, revócala

    Anúlala y crea otra. Borrarla del código no sirve: queda en el historial de git.

1. Saca la clave del código y guárdala en un .env

Esto es lo que no tienes que hacer nunca:

// ❌ La clave escrita en el código: en cuanto haces push, es pública
const client = new OpenAI({ apiKey: "sk-proj-AbC123..." });

En su lugar, crea un archivo llamado .env en la raíz del proyecto con tus claves:

# .env — este archivo NO se sube a GitHub
OPENAI_API_KEY=sk-proj-tu-clave-aqui
ANTHROPIC_API_KEY=sk-ant-tu-clave-aqui
GEMINI_API_KEY=tu-clave-de-google-aqui

Una variable por línea, NOMBRE=valor, sin espacios alrededor del =. Y tu código lee la clave desde ahí.

En Node.js

Con Node 20.6 o superior no necesitas instalar nada: arranca tu script con --env-file y las variables aparecen en process.env.

node --env-file=.env index.js
// index.js
const apiKey = process.env.OPENAI_API_KEY;

Si prefieres la librería de siempre, dotenv:

npm install dotenv
import "dotenv/config"; // carga el .env en process.env

const apiKey = process.env.ANTHROPIC_API_KEY;

Si usas Next.js, no hace falta ninguna de las dos: carga los .env solo y tienes las variables en process.env en el servidor.

En Python

Instala python-dotenv:

pip install python-dotenv
import os
from dotenv import load_dotenv

load_dotenv()  # lee el .env y lo mete en os.environ

api_key = os.environ["GEMINI_API_KEY"]

Consejo

Usa los nombres estándar (OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY). Los SDK oficiales los buscan solos: muchas veces ni siquiera tienes que pasar la clave al crear el cliente.

Un truco que usan casi todos los proyectos: sube un archivo .env.example con los nombres de las variables pero sin valores. Así quien clone el repo sabe qué tiene que rellenar, sin ver tus claves.

# .env.example — este SÍ se sube
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
GEMINI_API_KEY=

2. Añade .env al .gitignore

El .gitignore es un archivo de texto en la raíz del proyecto donde le dices a git qué archivos no tiene que subir nunca. Créalo (o ábrelo) y añade:

# .gitignore
.env
.env.*
!.env.example
  • .env y .env.* ignoran tu archivo de claves y sus variantes (.env.local, .env.production…).
  • !.env.example es la excepción: ese sí quieres subirlo.

Comprueba que no se ha colado

Antes de tu primer commit, haz estas comprobaciones en la terminal:

# 1. ¿Git ve el .env? No debería salir en la lista
git status

# 2. ¿Lo está ignorando? Debe responder con la línea del .gitignore que lo ignora
git check-ignore -v .env

# 3. ¿Queda alguna clave escrita en el código?
git grep -n --untracked -e "sk-" -e "AIza"

Si git check-ignore no devuelve nada, el .env no está ignorado: revisa el .gitignore. Y si git grep encuentra algo, sácalo al .env antes de seguir. (sk- es el principio de las claves de OpenAI y de Anthropic; AIza, el de las claves de Google.)

Atención

Si el .env ya estaba en un commit anterior, añadirlo al .gitignore no lo saca del repositorio. Para dejar de seguirlo usa git rm --cached .env y haz commit. Pero ojo: sigue en el historial. Si ese commit llegó a GitHub, salta al paso 4.

La red de seguridad de GitHub

GitHub tiene dos ayudas que conviene conocer:

  • Escaneo de secretos (secret scanning): en repositorios públicos funciona automáticamente y gratis. Si encuentra una clave de un proveedor de su programa de socios, avisa al proveedor para que pueda actuar, por ejemplo revocándola.
  • Protección de push (push protection): la de usuarios viene activada por defecto y te frena si intentas subir una clave a un repositorio público. En cada repositorio también la puedes activar en Settings → Advanced Security → Push protection.

Úsalas como red, no como cinturón. Según la tabla oficial de patrones, la protección de push bloquea las claves de OpenAI y de Anthropic, pero las de Google y Gemini solo generan un aviso: no te frenan el push.

3. Pon un límite de gasto en tu cuenta

Aunque hagas todo bien, un descuido puede pasar. El límite de gasto hace que, si alguien usa tu clave, la factura tenga techo. Ponlo hoy, en todas las cuentas que uses.

ProveedorDónde se poneQué pasa al llegar
OpenAISettings → Organization limits → Spend → Edit spend limit. Activa «Enforce a hard limit». También hay límite por proyecto.Con límite duro, las peticiones empiezan a fallar con un error 429.
Anthropic (Claude Console)Página Billing (platform.claude.com/settings/billing) → Spend limits. Cada workspace puede tener su propio límite, siempre por debajo del de la organización.Las peticiones fallan con un error que te dice cuándo vuelves a tener acceso. Puedes subir o quitar el límite antes.
Google AI Studio (Gemini)Página Spend → Monthly spend cap → Edit spend cap, por proyecto.Es un tope mensual por proyecto. Google lo marca como experimental y avisa de que puede haber excesos durante unos 10 minutos.
Desliza para ver la tabla completa

Nota

No cuentes con un corte instantáneo. OpenAI avisa de que el gasto registrado puede pasarse un poco del límite, y Google habla de unos 10 minutos de margen en los que puede haber excesos. Pon el límite por debajo de lo que estás dispuesto a perder.

Fuentes: límites de gasto de OpenAI, límites de gasto de la API de Claude, workspaces en la Claude Console y facturación de la API de Gemini. Los nombres de los menús pueden cambiar: si no los encuentras, busca «limits» o «spend» en la configuración de tu cuenta.

4. Si ya la subiste: revócala y crea otra

Aquí está el error que más dinero cuesta: ver la clave en GitHub, borrarla del código, hacer commit y pensar que ya está.

No está. Git guarda todas las versiones anteriores de cada archivo. La clave sigue en el historial y cualquiera puede verla mirando los commits antiguos. La documentación de GitHub lo dice claro: si se filtra un secreto, lo primero es revocarlo o rotarlo. Aunque reescribas el historial, el commit puede seguir accesible en clones, en forks y en vistas en caché de GitHub. Y si había bots mirando, puede que ya la tengan.

Así que la única solución segura es anular esa clave para que deje de funcionar y crear una nueva:

Qué hacer si tu clave ha estado en público

  1. Revoca la clave

    Bórrala o desactívala en la consola del proveedor. Desde ese momento ya no sirve para nada, la tenga quien la tenga.

  2. Crea una nueva

    Genera otra clave y guárdala solo en tu .env (y en las variables de entorno de tu hosting).

  3. Actualiza tu app

    Cambia la clave en local y donde tengas la app desplegada (Vercel, Railway, tu servidor…).

  4. Revisa el consumo

    Mira el uso y la facturación de los últimos días. Si ves algo raro, escribe al soporte del proveedor.

Dónde se revoca en cada uno:

Consejo

¿Quieres además limpiar el historial? GitHub recomienda la herramienta git-filter-repo. Pero es delicado (cambia todos los commits y rompe el trabajo de quien tenga el repo clonado) y no sustituye a revocar la clave. Primero revoca; lo demás es opcional.

Ojo si haces webs: las claves nunca en el navegador

Esto pilla a mucha gente que empieza con Next.js o Vite. Las variables que empiezan por NEXT_PUBLIC_ (Next.js) o VITE_ (Vite) se meten dentro del JavaScript que se descarga el navegador. Da igual que estén en el .env: cualquiera que abra tu web y las herramientas de desarrollador puede leerlas.

  • Next.js: las variables sin NEXT_PUBLIC_ solo existen en el servidor; las que lo llevan se copian en el código del cliente al compilar.
  • Vite: su documentación dice expresamente que las variables VITE_ no deben contener claves de API.
# ❌ Mal: acaba en el navegador
NEXT_PUBLIC_OPENAI_API_KEY=sk-proj-...

# ✅ Bien: solo la ve el servidor
OPENAI_API_KEY=sk-proj-...

La forma correcta: tu web llama a tu propio servidor (una ruta de API, una función serverless), y es ese servidor el que usa la clave para hablar con OpenAI, Claude o Gemini. El navegador nunca la ve.

Checklist antes de hacer push

  • Ninguna clave escrita en el código (git grep -n --untracked -e "sk-" -e "AIza" no devuelve nada).
  • Las claves están en .env y el código las lee con process.env u os.environ.
  • .env está en el .gitignore y git check-ignore -v .env lo confirma.
  • Subes un .env.example sin valores.
  • Nada de claves en variables NEXT_PUBLIC_ o VITE_.
  • Límite de gasto puesto en cada proveedor que uses.
  • Si una clave estuvo en público: revocada y sustituida.

Con esto, la próxima factura de IA será la que esperas.

FAQ

Cualquiera que vea el repositorio puede copiarla y hacer peticiones a tu cuenta de IA. Tú pagas ese consumo. Además, aunque borres la clave después, sigue en el historial de git y en cualquier clon o fork que se haya hecho. Por eso lo primero es revocarla y crear otra.

No. La propia documentación de GitHub dice que, si se filtra un secreto, lo primero es revocarlo o rotarlo. Reescribir el historial no lo elimina de los clones, de los forks ni de las vistas en caché. Si la clave estuvo en público aunque sea un rato, trátala como robada.

En repositorios públicos, el escaneo de secretos de GitHub funciona automáticamente y gratis. Si detecta una clave de un proveedor que forma parte de su programa de socios (OpenAI, Anthropic y Google lo son), avisa al proveedor para que pueda actuar. Además, la protección de push para usuarios viene activada por defecto y bloquea muchos tipos de claves antes de que lleguen a un repo público. Ayuda mucho, pero no cubre todos los tipos de clave: no lo uses como única protección.

En OpenAI: Settings, Organization limits, Spend, Edit spend limit, y activa la opción de límite duro. En la Claude Console: página de Billing, sección Spend limits. En Google AI Studio: página Spend, Monthly spend cap, Edit spend cap. OpenAI y Google avisan de que el corte no es instantáneo y puede haber un pequeño exceso, así que pon el límite con margen.

No. Esas variables se meten en el JavaScript que se descarga el navegador, así que cualquiera puede verlas abriendo las herramientas de desarrollador. Las claves de IA se usan siempre desde el servidor (una ruta de API, una función serverless) y el navegador llama a tu servidor, no al proveedor.

Sigue profundizando en el mismo tema.

Compartir
Newsletter

Recibe las próximas guías en tu correo

Ideas y recursos de IA y marketing, sin relleno. Lo que funciona y cómo aplicarlo.

Ideas y recursos sin spam. Cancela cuando quieras.

¿Te sirve esta guía?

Suscríbete