> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pan.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Seguridad

> Mejores prácticas de seguridad para pan API

## Proteger tu API Key

<Warning>
  Tu API key es tan sensible como una contrasena. Nunca la expongas.
</Warning>

### Usar Variables de Entorno

<CardGroup cols={2}>
  <Card title="MAL" icon="xmark">
    ```javascript theme={null}
    // NUNCA hagas esto
    const pan = new Pan({
      apiKey: 'pan_sk_abc123...'
    });
    ```
  </Card>

  <Card title="BIEN" icon="check">
    ```javascript theme={null}
    // Siempre usa env vars
    const pan = new Pan({
      apiKey: process.env.PAN_API_KEY
    });
    ```
  </Card>
</CardGroup>

### Archivo .env

```env theme={null}
# .env (NUNCA commitear)
PAN_API_KEY=pan_sk_tu_api_key_aqui
```

### .gitignore

```gitignore theme={null}
# Siempre ignorar
.env
.env.local
.env.*.local
.env.production
```

## Keys por Entorno

Usa API keys diferentes para cada entorno:

```javascript theme={null}
// 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

```yaml theme={null}
# .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

```bash theme={null}
vercel secrets add pan_api_key pan_sk_...
```

### Docker

```dockerfile theme={null}
# 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):

1. Crea una nueva key en el dashboard
2. Actualiza tu aplicación con la nueva key
3. Verifica que todo funcione
4. Revoca la key anterior

```javascript theme={null}
// 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:

1. **Inmediatamente** ve al dashboard
2. **Revoca** la key comprometida
3. **Crea** una nueva key
4. **Actualiza** todas las aplicaciones
5. **Revisa** logs de uso sospechoso

## No Exponer en Frontend

<Warning>
  NUNCA uses tu API key en código del lado del cliente.
</Warning>

### Arquitectura Segura

```
┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐
│    Frontend      │ --> │    Tu Backend    │ --> │    pan API       │
│ (sin API key)    │     │ (con API key)    │     │                  │
└──────────────────┘     └──────────────────┘     └──────────────────┘
```

### Ejemplo con Next.js

```typescript theme={null}
// 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);
}
```

```typescript theme={null}
// 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();
}
```

## Validar Inputs

Siempre válida datos antes de enviar a pan:

```typescript theme={null}
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:

```typescript theme={null}
// MAL
console.log('Request:', { apiKey, userId, amount });

// BIEN
console.log('Request:', { userId, amount });
```

```typescript theme={null}
// 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

```typescript theme={null}
// 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

<CardGroup cols={2}>
  <Card title="API Key">
    * [ ] En variables de entorno
    * [ ] No en código fuente
    * [ ] Keys diferentes por entorno
    * [ ] Rotacion programada
  </Card>

  <Card title="Arquitectura">
    * [ ] API key solo en backend
    * [ ] Frontend sin acceso directo
    * [ ] Validación de inputs
    * [ ] Logging sanitizado
  </Card>
</CardGroup>
