Las API HTTP autentican a los llamantes con una credencial en el header Authorization —una clave de API o bearer token (Authorization: Bearer <token>)—. Los esquemas más fuertes firman cada petición con HMAC sobre una petición canónica para que las credenciales nunca sean repetibles, usan OAuth 2.0 client-credentials para tokens máquina a máquina y añaden TLS mutuo donde se requiere identidad a nivel de transporte.
Bearer tokens y claves de API
La autenticación más simple es una credencial bearer: el cliente presenta un token secreto en el header Authorization y el servidor lo valida. RFC 9110 define el header Authorization y su prefijo de esquema, y OAuth 2.0 define el esquema Bearer —Authorization: Bearer <token>— cuya propiedad definitoria es que la mera posesión concede acceso, por lo que el token debe viajar solo sobre TLS y no aparecer nunca en una URL, un log o un mensaje de error. Una clave de API es la misma idea con un secreto más longevo, a menudo sin caducidad. Como una credencial bearer es repetible si se captura, es la base y no el techo: es fácil de integrar y perfectamente adecuada sobre TLS para la mayoría del tráfico, pero las operaciones de alto valor suelen superponer firma de peticiones.
POST /v1/messages HTTP/1.1
Host: api.example
Authorization: Bearer eyJhbGciOi... # secret; TLS only, never logged
Content-Type: application/jsonFirma de peticiones HMAC
La firma de peticiones eleva el listón: en lugar de enviar el secreto, el cliente lo usa para calcular un HMAC sobre una representación canónica de la petición y envía solo la firma. El servidor, que posee el mismo secreto, recalcula la firma y compara. Como la firma cubre el método, la ruta, los headers clave y un hash del cuerpo, una firma capturada no puede repetirse contra una petición distinta, y como el propio secreto nunca abandona el cliente, capturar una petición no revela la credencial. La construcción refleja la firma de webhooks en la dirección opuesta y es la misma primitiva HMAC-SHA256 (RFC 2104 / RFC 6234). La parte delicada es la petición canónica: ambos lados deben coincidir byte a byte en cómo serializarla, o toda firma discrepará.
canonical =
HTTP-METHOD + '\n' +
URI-PATH + '\n' +
SORTED-QUERY + '\n' +
SIGNED-HEADERS (name:value, sorted, '\n'-joined) + '\n' +
HEX(SHA256(raw_body))
signature = HMAC_SHA256(secret, canonical)
Authorization: SIGV1 Credential=<key-id>,
SignedHeaders=host;x-date;content-type, Signature=<hex>Headers firmados y la fecha de la petición
Dos detalles hacen sólida la firma de peticiones. Primero, una lista SignedHeaders explícita nombra exactamente qué headers están cubiertos, para que un intermediario que añada o reordene headers no relacionados no invalide la firma, mientras que cualquier header que el cliente eligió firmar queda a prueba de manipulaciones. Segundo, una fecha de petición (un X-Date firmado o el header Date estándar) forma parte de la petición canónica y se compara con el reloj del servidor dentro de una tolerancia —la misma defensa contra repetición que los webhooks, aplicada a las llamadas API entrantes—. Juntos significan que una petición firmada queda ligada a su contenido exacto, a sus headers declarados y a una ventana de tiempo estrecha; una petición capturada es inútil unos minutos después.
Alcance y rotación de claves
Las credenciales deberían portar el menor privilegio que funcione y ser rotables sin caída de servicio. El alcance adjunta permisos a una clave —qué operaciones puede invocar, desde qué origen, a qué tasa— para que una clave que solo envía mensajes no pueda leer ajustes de cuenta, y el radio de impacto de una clave filtrada quede acotado. La rotación sigue el patrón de claves solapadas: emitir una nueva credencial, ejecutar ambas en paralelo mientras los clientes migran, y luego revocar la antigua, para que nada se rompa a mitad de vuelo. Las claves deberían ser identificables (un id de clave no secreto viaja en la petición para que el servidor sepa contra qué secreto verificar y qué alcance aplicar) y revocables individualmente, para cortar una integración comprometida sin perturbar el resto.
| Esquema | Qué se transporta | Fortaleza / uso |
|---|---|---|
| Clave API | Secreto de larga duración en Authorization | Base simple; solo sobre TLS; fácil de filtrar en los registros |
| Token Bearer (OAuth 2.0) | Token de acceso de corta duración | Con caducidad y ámbito limitado; renovado mediante el punto final de token |
| Firma HMAC de solicitudes | Firma (el secreto permanece local) | Resistente a la repetición y con detección de manipulación, por solicitud |
| mTLS | Certificado de cliente X.509 | Identidad a nivel de transporte; robusta pero con operación más pesada |
TLS mutuo
El TLS mutuo autentica al cliente en la capa de transporte: además de que el servidor presente un certificado, el cliente presenta su propio certificado X.509 durante el handshake, y el servidor admite solo conexiones cuyo certificado encadene a una CA de confianza y coincida con una identidad registrada. Esto liga la identidad de la API a una clave criptográfica gestionada a nivel de conexión en vez de a un secreto bearer en un header, lo que resulta atractivo para enlaces máquina a máquina de alta garantía y para fijar a un socio a certificados específicos. El coste es operativo —emisión, distribución, rotación y revocación de certificados—, así que el mTLS suele reservarse para las integraciones más sensibles, a menudo combinado con un bearer token o una firma para una autorización de grano fino sobre la identidad de transporte gruesa.
OAuth 2.0 client-credentials para M2M
Para integraciones servidor a servidor sin ningún usuario final presente, OAuth 2.0 (RFC 6749) define el grant client-credentials. El cliente se autentica ante un token endpoint con su client_id y client_secret (o un certificado de cliente) y recibe un access token de corta duración, que luego presenta como bearer token en las llamadas API hasta que caduca y se renueva. La ventaja sobre una clave de API estática es la duración y el alcance: los tokens son de corta vida, así que un token capturado caduca rápido, y portan alcances explícitos, así que un token acuñado para enviar no puede usarse para administrar la cuenta. Este es el patrón estándar para el acceso a API máquina a máquina y el mecanismo que la guía de autenticación de BroadNet documenta de forma concreta para sus endpoints.
POST /oauth/token HTTP/1.1
Host: auth.example
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=<id>
&client_secret=<secret>
&scope=messages:send
-> { "access_token": "...", "token_type": "Bearer",
"expires_in": 3600, "scope": "messages:send" }Preguntas frecuentes
¿Cuál es la diferencia entre un bearer token y la firma HMAC?
Un bearer token se envía en cada petición y concede acceso por posesión, así que un token capturado es repetible hasta que caduca. La firma HMAC nunca envía el secreto: el cliente firma una petición canónica y envía solo la firma, así que una petición capturada no puede repetirse contra otra llamada y la credencial misma nunca queda expuesta.
¿Por qué la firma HMAC necesita una petición canónica?
Porque ambos lados deben calcular la cadena idéntica para obtener firmas coincidentes. La petición canónica fija exactamente cómo se serializan el método, la ruta, la query ordenada, los headers firmados y el hash del cuerpo. Cualquier discrepancia —orden de headers, espacios en blanco, un cuerpo reencodeado— produce una firma distinta y la petición se rechaza aunque nada se haya manipulado.
¿Qué me da OAuth 2.0 client-credentials frente a una clave de API?
Corta duración y alcance explícito. El cliente intercambia sus credenciales en un token endpoint por un access token de corta vida y con alcance (RFC 6749). Un token capturado caduca rápido, y un token acuñado para enviar no puede administrar la cuenta. Una clave de API estática, en cambio, es longeva y normalmente amplia.
¿Cómo deberían acotarse y rotarse las claves de API?
Concede el menor privilegio: restringe cada clave a las operaciones, orígenes y tasa que necesita, para que una fuga quede contenida. Rota con claves solapadas: emite una nueva credencial, ejecuta ambas en paralelo mientras los clientes migran, y luego revoca la antigua. Las claves deberían portar un id de clave no secreto y ser revocables individualmente para cortar una integración comprometida por sí sola.
¿Cuándo compensa el TLS mutuo su coste operativo?
Cuando necesitas una identidad criptográfica a nivel de transporte para un enlace máquina a máquina de alta garantía, o para fijar a un socio a certificados específicos. El mTLS admite solo clientes cuyo certificado X.509 encadena a una CA de confianza. Es más pesado de operar —emisión, rotación, revocación—, así que suele reservarse para las integraciones más sensibles, a menudo con un token o una firma superpuestos para la autorización.
¿Por qué las credenciales bearer nunca deben aparecer en una URL o un log?
Porque una credencial bearer concede acceso solo por posesión. Las URL las registran los proxies, se almacenan en el historial del navegador y se filtran vía el header Referer, y los logs de aplicación son ampliamente legibles, así que un token en cualquiera de ellos queda efectivamente divulgado. Las credenciales bearer deben viajar solo en el header Authorization sobre TLS y depurarse de los logs.
Especificaciones de la fuente
Las normas publicadas en las que se basa esta página. Se abre en una pestaña nueva.