---
term: 'Seguridad de Claves de API'
seoTitle: 'Seguridad de Claves de API: almacenamiento, rotación, fugas'
headline: '¿Qué es la Seguridad de Claves de API?'
slug: seguridad-de-claves-de-api
category: auth-security
shortDefinition: 'Una clave de API es una cadena única que identifica a la app que llama a una API; la seguridad de claves de API es la disciplina de acotarla y protegerla.'
relatedTerms:
  - json-web-token-jwt
  - api-rate-limiting-throttling
  - cors-cross-origin-resource-sharing
  - data-encryption-at-rest-transit
contrastsWith:
  - json-web-token-jwt
aboutTerms:
  - 'Claves Publicables vs. Secretas'
  - 'Rotación de Claves'
  - 'Gestión de Secretos'
faq:
  - question: '¿Qué es una clave de API?'
    answer: 'Una cadena única que un proveedor de API emite para una aplicación registrada, enviada con cada solicitud — idealmente en un header — para que el servidor identifique al llamador, aplique sus permisos, mida el uso e imponga rate limits. Un detalle notable: ningún estándar la define — las claves de API son una convención, no un protocolo.'
  - question: '¿Una clave de API es una contraseña?'
    answer: 'Una clave secreta es funcionalmente de la misma categoría que las contraseñas: es una credencial bearer, así que cualquiera que la tenga es tratado como tú — misma disciplina de almacenamiento, mismas consecuencias de brecha. Las diferencias: las claves identifican aplicaciones, no personas, y muchas nunca expiran a menos que las rotes.'
  - question: '¿Cuál es la diferencia entre una clave de API y un token?'
    answer: 'Las claves identifican apps; los tokens autentican usuarios. Una clave es estática, generada por un admin y con alcance de aplicación; un access token de OAuth se emite en el login, tiene vida corta, es renovable y lleva los permisos de un usuario específico. La identificación server-to-server va con claves; cualquier cosa específica de un usuario pertenece a los tokens.'
  - question: '¿Dónde debo guardar las claves de API?'
    answer: 'Nunca en el código fuente. Las variables de entorno en un archivo fuera del versionado son el mínimo — con la salvedad de que se filtran por logs, volcados de proceso y definiciones de contenedor — y un gestor de secretos es el estándar de equipo: cifrado en reposo, con control de acceso, auditado y rotable.'
  - question: '¿Puedo poner una clave de API en el frontend o en una app móvil?'
    answer: 'Solo una clave publicable, diseñada para eso. Cualquier cosa en un bundle de JavaScript o en el binario de una app es pública — la extracción es rutinaria y la ofuscación solo la retrasa. Las claves secretas se quedan server-side; cuando un cliente necesita un servicio con clave secreta, enruta la llamada a través de tu propio backend.'
  - question: '¿Qué debo hacer cuando una clave de API se filtra?'
    answer: 'Inmediatamente: revoca la clave, despliega una sustituta, púrgala del código y del historial de git, audita los logs de uso en busca de abuso y rota todo lo que estaba almacenado junto a ella. Muévete rápido — los bots prueban claves commiteadas en repositorios públicos en cuestión de minutos — y recuerda: la revocación detiene el uso futuro, no los datos ya extraídos.'
  - question: '¿Cada cuánto deben rotarse las claves de API?'
    answer: 'Según el riesgo: cada 30–90 días para claves de alcance amplio o expuestas externamente, más tiempo para las internas de bajo riesgo, e inmediatamente ante una sospecha de exposición o la salida de alguien del equipo. La rotación sin downtime usa una ventana de superposición en la que la clave vieja y la nueva valen a la vez mientras los despliegues se actualizan.'
  - question: '¿Cómo se filtran las claves de API?'
    answer: 'En orden de infamia: commiteadas en repositorios git, embarcadas en bundles de cliente y binarios móviles, puestas en URLs donde los logs del servidor y el historial del navegador las capturan, impresas en logs de aplicación y de CI, y pegadas en chats y tickets. Cada vector es prevenible, que es lo que hace deprimente la lista.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'OWASP Secrets Management Cheat Sheet'
    url: 'https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html'
  - name: 'OWASP API Security Top 10 (2023)'
    url: 'https://owasp.org/API-Security/editions/2023/en/0x11-t10/'
  - name: 'OWASP Key Management Cheat Sheet'
    url: 'https://cheatsheetseries.owasp.org/cheatsheets/Key_Management_Cheat_Sheet.html'
  - name: 'RFC 6750 — OAuth 2.0 Bearer Token Usage'
    url: 'https://datatracker.ietf.org/doc/html/rfc6750'
  - name: 'API key — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/API_key'
cta:
  title: 'Claves diseñadas para embarcarse'
  text: 'Las client keys de Back4app son publicables por diseño — los datos están protegidos por CLPs y ACLs aplicadas server-side, no por el secreto de la clave — mientras la Master Key se queda donde pertenecen los secretos: en el servidor.'
  linkText: 'Empieza gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-09-03'
translationKey: api-key-security
---

**Una clave de API es una cadena única que identifica a la app que llama a una API; la seguridad de claves de API es la disciplina de acotarla y protegerla.** Precisión primero, porque la mayoría de las definiciones lo difumina: una clave *identifica* a la aplicación, ofrece solo *autenticación débil* (es una credencial bearer — quien la tiene, es tú) y lleva *autorización gruesa* (el alcance que se le adjuntó al crearla). Los usuarios se autentican con [tokens](/glossary/es/json-web-token-jwt/); las apps se identifican con claves — y ninguna RFC define la clave de API. Es una convención, y exactamente por eso su seguridad es tu configuración, no la garantía de un estándar.

## Puntos clave

| Pregunta | Respuesta |
| --- | --- |
| Qué hace una clave | Identifica la app · mide el uso · ancla los [rate limits](/glossary/api-rate-limiting-throttling/) |
| Los dos animales | Claves publicables (hechas para embarcarse) vs. claves secretas (categoría contraseña) |
| La escalera del almacenamiento | Hardcodeada: nunca → variables de entorno: el mínimo → gestor de secretos: el estándar |
| La ley de hierro | Todo lo que va en un bundle de cliente es público — planifica para la extracción |
| Respuesta a una fuga | Revocar → sustituir → purgar el historial → auditar — en minutos, no en días |

## La solicitud, y los dos tipos de clave

```text
GET /v1/search?q=espresso HTTP/1.1
Host: api.example.com
X-Api-Key: pk_live_7f2c…      ← en un HEADER — las URLs terminan en logs,
                                 historial y referrers

Dos animales distintos comparten un nombre:
clave publicable   se embarca en bundles web/móviles · identifica la app,
                   mide el uso · diseñada sabiendo que SERÁ extraída
clave secreta      solo server-side · credencial bearer categoría contraseña ·
                   quien la tiene eres tú
```

El modelo publicable en la práctica — claves que se embarcan porque la seguridad vive en otra parte:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
Parse.initialize(APP_ID, JS_KEY); // both ship in your bundle — by design
Parse.serverURL = 'https://parseapi.back4app.com';
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request

// The one key that never ships: the Master Key bypasses every ACL and CLP.
// Server-only (Cloud Code / trusted backend), read from env or secret manager.
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
await Parse().initialize(
  appId, // ships in the app — by design
  'https://parseapi.back4app.com',
  clientKey: clientKey, // publishable, extractable, NOT a secret
);
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request
// The Master Key bypasses every ACL and CLP: server-only, never in the app.
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
ParseSwift.initialize(
    applicationId: appId,  // ships in the IPA — by design
    clientKey: clientKey,  // publishable, extractable, NOT a secret
    serverURL: URL(string: "https://parseapi.back4app.com")!
)
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request
// The Master Key bypasses every ACL and CLP: server-only, never in the app.
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// Publishable keys: safe to ship BECAUSE authorization lives server-side
Parse.initialize(
    Parse.Configuration.Builder(context)
        .applicationId(APP_ID) // ships in the APK — by design
        .clientKey(CLIENT_KEY) // publishable, extractable, NOT a secret
        .server("https://parseapi.back4app.com")
        .build()
)
// What protects data isn't key secrecy — it's CLPs + ACLs checked per request
// The Master Key bypasses every ACL and CLP: server-only, never in the app.
```

## Claves de API vs. tokens vs. JWTs

| | Clave de API | Access token de OAuth | JWT |
| --- | --- | --- | --- |
| Identifica | La aplicación | El usuario (y el grant) | Lo que digan sus claims |
| Emisión | Una vez, por un admin | En cada login, por un flujo | Es un *formato*, no una emisión |
| Vida útil | Hasta que se rota (a menudo nunca) | Minutos a horas | Lo que diga `exp` |
| Alcance | Fijo al crearla | Scopes por grant | Definido por las claims |
| Estándar | Ninguno — convención | [OAuth 2.0](/glossary/es/oauth-2-login-social/) | RFC 7519 |
| Trabajo correcto | Identificación server-to-server, medición | Acceso a API delegado por el usuario | Transporte de claims firmadas |

La comparación colapsa en una frase que vale memorizar: **las claves identifican apps; los tokens autentican usuarios.** Usar una clave donde importa la identidad del usuario es reconstruir mal la autenticación; usar tokens por usuario para medición anónima de apps es maquinaria sin propósito.

## Dónde viven las claves: la escalera del almacenamiento

**Hardcodeada — nunca.** El código fuente se copia, se forkea y se commitea; git recuerda para siempre, y los bots de escaneo de secretos encuentran claves en commits públicos en cuestión de minutos. **Variables de entorno — el mínimo**, con la salvedad sobre la que el [cheat sheet de OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html) es directo: las variables de entorno se filtran por logs de error, volcados de proceso y definiciones de contenedor; mantienen los secretos fuera de git, no fuera de problemas. **Un gestor de secretos — el estándar de equipo**: cifrado en reposo, con acceso controlado por servicio, auditado por lectura, rotable centralmente (las opciones open-source incluyen Vault, SOPS e Infisical). Suma la higiene que hace sobrevivibles las fugas: claves generadas con aleatoriedad criptográfica, *prefijadas* (estilo `sk_live_…`) para que los escáneres las reconozcan, guardadas con hash del lado del proveedor como contraseñas, una clave por app por entorno — y escaneo de secretos (gitleaks, trufflehog) conectado al CI, para que el commit que filtra una clave falle antes de aterrizar.

## El problema del client-side, con honestidad

Todo explicador dice "no pongas claves secretas en el código del cliente"; casi ninguno dice la segunda mitad: **tu bundle es público.** El JavaScript web es legible por definición; los binarios móviles se desempaquetan y se les extraen strings de forma rutinaria; la ofuscación eleva el esfuerzo de minutos a horas, una sola vez. Se siguen dos consecuencias. Primera: las únicas claves que pertenecen a los clientes son las *publicables* — diseñadas para identificar, no para proteger, con la autorización real aplicada server-side en cada solicitud. Segunda: cuando un cliente debe usar un servicio de terceros con clave secreta, el secreto se queda detrás de tu propio backend — el patrón proxy:

```mermaid
flowchart LR
  accTitle: Patrón proxy manteniendo las claves secretas server-side
  accDescr: La app cliente guarda solo una clave publicable y llama a tu backend. El backend, que guarda la clave secreta en un gestor de secretos, llama a la API de terceros y devuelve los resultados, así que el secreto nunca se embarca en el cliente.
  C["App cliente<br/>solo clave publicable"] -->|"tu API"| B["Tu backend<br/>clave secreta desde el<br/>gestor de secretos"]
  B -->|"X-Api-Key: sk_live_…"| T["API de terceros"]
  T --> B --> C
  X["Un atacante desempaqueta el bundle"] -.->|"no encuentra nada<br/>que valga la pena robar"| C
```

## Cuando una clave se filtra: el runbook

El reloj importa — los bots monitorean repositorios públicos y explotan claves commiteadas en **uno a cinco minutos**. En orden: **1 · Revoca** la clave en el proveedor — antes de investigar, antes de la daily. **2 · Sustituye** — emite la clave nueva y despliégala vía configuración, no código. **3 · Purga** — elimínala del código fuente *y del historial de git*; una línea borrada sigue viva en cada clon. **4 · Audita** — los logs del proveedor durante la ventana de la fuga: qué se leyó, se creó, se gastó. **5 · Amplía** — todo lo co-ubicado con la clave (el mismo .env, el mismo repo) se presume quemado; rótalo también. Y la salvedad que separa la respuesta real del ritual: **la revocación detiene el uso futuro — no des-exfiltra datos.** Lo que se llevaron durante la ventana es un incidente, no una rotación.

## Rotación sin downtime

La rotación acota el valor de las fugas no detectadas — una clave robada con 60 días de vida restante es un activo distinto de una válida para siempre. Cadencia basada en riesgo: 30–90 días para claves de alcance amplio o compartidas externamente, hasta un año para las internas de alcance estrecho, *inmediatamente* ante una sospecha de exposición o la salida de cualquiera que la haya tenido. La jugada de cero downtime es la **superposición de clave dual**: emite la clave nueva mientras la vieja sigue válida, migra los despliegues con calma y luego revoca la vieja — el mismo truco que los sistemas de refresh tokens formalizan. Los regímenes de compliance exigen cada vez más el calendario; el argumento de seguridad nunca lo necesitó.

## Casos de uso comunes

- **Integración server-to-server** — el hábitat nativo de la clave: un servicio identificándose ante otro.
- **Medición de uso y facturación** — la clave como la unidad que los proveedores cuentan, limitan y facturan.
- **Identificación publicable de clientes** — bundles de apps llevando claves hechas para la exposición, con la autorización en otra parte.
- **Separación de entornos** — claves de prueba y de producción manteniendo los accidentes de staging fuera de los datos de producción.
- **Contención de abuso** — [rate limits](/glossary/api-rate-limiting-throttling/) por clave y revocación como los controles de radio de daño.

## ¿Qué credencial deberías usar? Matriz de decisión

| Situación | Usa |
| --- | --- |
| Backend llamando a una API de terceros | Clave secreta, en un gestor de secretos |
| Identificar tu app desde web/móvil | Clave publicable + autorización server-side |
| Actuar en nombre de un usuario con sesión | Tokens OAuth, no claves |
| Claims firmadas entre servicios | [JWTs](/glossary/es/json-web-token-jwt/) |
| El cliente necesita un servicio con clave secreta | Tu backend como proxy — el secreto nunca se embarca |
| Máquina-a-máquina con auth estilo usuario | Flujo client credentials de OAuth |

## Limitaciones y trade-offs

- **Las claves no prueban posesión.** Una cadena bearer no ofrece vínculo criptográfico con el llamador; para auth de servicio de alta garantía, el TLS mutuo y las solicitudes firmadas existen por algo.
- **Las credenciales estáticas envejecen mal.** Sin expiración, cada fuga queda abierta hasta que alguien la nota; la rotación es el sustituto manual del ciclo de vida que los tokens obtienen gratis.
- **Los alcances gruesos comparten de más.** Una clave con permisos amplios es una llave maestra; el alcance granular cuesta administración y paga en radio de daño.
- **Las claves identifican, no autentican.** Construir confianza a nivel de usuario sobre identificación a nivel de app es el patrón de [broken authentication](https://owasp.org/API-Security/editions/2023/en/0x11-t10/) que los auditores buscan primero.
- **La deriva de inventario es real.** Las claves sin uso de integraciones viejas siguen válidas hasta que se borran — la prima credencial-zombi de los endpoints zombis.

## Claves de API en Back4app

Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. Su modelo de claves es la sección del client-side hecha concreta: el Application ID y las client keys **se embarcan dentro de tus apps por diseño** — la propia documentación de Back4app es explícita: las client keys no son mecanismos de seguridad — porque la autorización nunca depende de ellas: cada solicitud se verifica server-side contra los [permisos a nivel de clase](/glossary/es/permisos-de-clase-clp/) y las [ACLs](/glossary/es/listas-de-control-de-acceso-acl/), así que una clave extraída le concede a un atacante exactamente lo que obtiene un usuario anónimo. El único secreto de verdad es la **Master Key**, que se salta toda ACL y CLP: vive solo server-side — Cloud Code, backends confiables, variables de entorno o gestor de secretos — y nunca en un bundle. Las pestañas de código muestran la división en la práctica; el runbook aplica solo a la master key, y ese es el punto: un secreto que cuidar es una postura de seguridad, cuarenta son una hoja de cálculo.
