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.tech/v1'
},
staging: {
apiKey: process . env . PAN_API_KEY_STAGING ,
baseURL: 'https://api-staging.pan.tech/v1'
},
production: {
apiKey: process . env . PAN_API_KEY_PROD ,
baseURL: 'https://api.pan.tech/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
Rotación de Keys
Rota tus API keys periódicamente (cada 90 días recomendado):
Crea una nueva key en el dashboard
Actualiza tu aplicación con la nueva key
Verifica que todo funcione
Revoca la key anterior
// Script de verificación post-rotación
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 código 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 autenticación 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 válida 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 información 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 periódicamente 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.tech/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