Proteger tu API Key
Tu API key es tan sensible como una contrasena. Nunca la expongas.
Usar Variables de Entorno
MAL // NUNCA hagas esto
const pan = new Pan ({
apiKey: 'pan_sk_abc123...'
});
BIEN // Siempre usa env vars
const pan = new Pan ({
apiKey: process . env . PAN_API_KEY
});
Archivo .env
# .env (NUNCA commitear)
PAN_API_KEY=pan_sk_tu_api_key_aqui
.gitignore
# Siempre ignorar
.env
.env.local
.env.*.local
.env.production
Keys por Entorno
Usa API keys diferentes para cada entorno:
// config/pan.js
const config = {
development: {
apiKey: process . env . PAN_API_KEY_DEV ,
baseURL: 'https://api-staging.pan.dev/v1'
},
staging: {
apiKey: process . env . PAN_API_KEY_STAGING ,
baseURL: 'https://api-staging.pan.dev/v1'
},
production: {
apiKey: process . env . PAN_API_KEY_PROD ,
baseURL: 'https://api.pan.dev/v1'
}
};
export default config [ process . env . NODE_ENV || 'development' ] ;
Secretos en CI/CD
GitHub Actions
# .github/workflows/deploy.yml
jobs :
deploy :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v4
- name : Deploy
env :
PAN_API_KEY : ${{ secrets.PAN_API_KEY }}
run : npm run deploy
Vercel
vercel secrets add pan_api_key pan_sk_...
Docker
# NO incluir secrets en Dockerfile
# Usar en runtime:
docker run -e PAN_API_KEY=$PAN_API_KEY myapp
Rotacion de Keys
Rota tus API keys periodicamente (cada 90 dias recomendado):
Crea una nueva key en el dashboard
Actualiza tu aplicacion con la nueva key
Verifica que todo funcione
Revoca la key anterior
// Script de verificacion post-rotacion
async function verificarKey () {
try {
const yields = await pan . yields . getAll ();
console . log ( 'Nueva key funciona correctamente' );
return true ;
} catch ( error ) {
console . error ( 'Error con nueva key:' , error . message );
return false ;
}
}
Revocar Keys Comprometidas
Si sospechas que una key fue expuesta:
Inmediatamente ve al dashboard
Revoca la key comprometida
Crea una nueva key
Actualiza todas las aplicaciones
Revisa logs de uso sospechoso
No Exponer en Frontend
NUNCA uses tu API key en codigo del lado del cliente.
Arquitectura Segura
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Frontend │ --> │ Tu Backend │ --> │ Pan API │
│ (sin API key) │ │ (con API key) │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
Ejemplo con Next.js
// app/api/wallet/route.ts (server-side)
import { Pan } from '@pan/sdk' ;
const pan = new Pan ({ apiKey: process . env . PAN_API_KEY ! });
export async function POST ( request : Request ) {
const { userId } = await request . json ();
// Verificar autenticacion del usuario aqui
const wallet = await pan . wallet . create ({ userId });
return Response . json ( wallet );
}
// Frontend - NO tiene acceso a la API key
async function createWallet ( userId : string ) {
const response = await fetch ( '/api/wallet' , {
method: 'POST' ,
body: JSON . stringify ({ userId })
});
return response . json ();
}
Siempre valida datos antes de enviar a Pan:
import { z } from 'zod' ;
const createWalletSchema = z . object ({
userId: z . string (). min ( 1 ). max ( 100 ),
email: z . string (). email (). optional (),
metadata: z . record ( z . string ()). optional ()
});
async function createWallet ( data : unknown ) {
const validated = createWalletSchema . parse ( data );
return await pan . wallet . create ( validated );
}
Logging Seguro
No loguees informacion sensible:
// MAL
console . log ( 'Request:' , { apiKey , userId , amount });
// BIEN
console . log ( 'Request:' , { userId , amount });
// Helper para logging seguro
function sanitizeLog ( obj : object ) : object {
const sensitiveKeys = [ 'apiKey' , 'password' , 'token' , 'secret' ];
return Object . fromEntries (
Object . entries ( obj ). map (([ key , value ]) => [
key ,
sensitiveKeys . includes ( key ) ? '[REDACTED]' : value
])
);
}
Monitorear Uso
Revisa el dashboard periodicamente para detectar:
Picos de uso inesperados
Requests desde IPs desconocidas
Patrones anomalos
// Alerta de uso alto
async function checkUsage () {
const usage = await fetch ( 'https://api.pan.dev/dashboard/usage' , {
headers: { Authorization: `Bearer ${ API_KEY } ` }
});
const data = await usage . json ();
if ( data . requestsToday > 1000 ) {
sendAlert ( 'Uso alto de API detectado' );
}
}
Checklist de Seguridad