Autenticacion
La API externa de Owem Pay utiliza un modelo de seguridad de tres capas: API Key + Secret, firma HMAC-SHA512 por solicitud y whitelist de IP obligatoria.
Vision General de las Capas
Solicitud HTTP
│
├─ 1. IP Whitelist ─── IP no autorizado? → 403 Forbidden
│
├─ 2. API Key + Secret ─── Credenciales invalidas? → 401 Unauthorized
│
└─ 3. HMAC-SHA512 ─── Firma invalida? → 401 Unauthorized
│
└─ Solicitud aceptada → Logica de negocioCapa 1 -- API Key + Secret
Todas las solicitudes deben incluir el header Authorization:
Authorization: ApiKey {client_id}:{client_secret}| Componente | Descripcion | Prefijo |
|---|---|---|
client_id | Identificador publico de la API Key | cli_ |
client_secret | Clave secreta (almacenamos solo el hash) | sk_ |
El secret nunca se almacena en texto plano. Cuando llega una solicitud, el secret enviado se compara con el hash almacenado. Si no coincide, la solicitud se rechaza antes de llegar a la logica de negocio.
Formato alternativo -- Basic Auth con base64:
Authorization: Basic {base64(client_id:client_secret)}Capa 2 -- HMAC-SHA512
Las solicitudes transaccionales (POST, PUT, PATCH) exigen firma HMAC-SHA512 del body en el header hmac. La validacion usa comparacion en tiempo constante (constant-time comparison) para impedir ataques de timing.
Vea HMAC-SHA512 para ejemplos de implementacion en 6 lenguajes.
Capa 3 -- IP Whitelist
Toda API Key debe tener al menos un IP en la whitelist. Las solicitudes desde IPs no autorizados se rechazan con 403 Forbidden, incluso con credenciales validas. Configure la whitelist en el Merchant Portal al crear o editar la API Key.
Soporta IPs individuales y notacion CIDR (ej: 172.20.16.0/20).
Headers Obligatorios
| Header | Valor | Obligatorio |
|---|---|---|
Authorization | ApiKey {client_id}:{client_secret} | Si -- todas las solicitudes |
Content-Type | application/json | Si -- solicitudes con body |
hmac | Firma HMAC-SHA512 en hexadecimal | Si -- solo POST/PUT/PATCH |
Idempotency-Key | Clave unica para deduplicacion (max 256 chars) | Opcional -- solo POST |
Ejemplo Completo
CLIENT_ID="cli_a1b2c3d4e5f6"
CLIENT_SECRET="sk_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"
# Consulta de saldo (GET -- sin HMAC)
curl -X GET https://api.owem.com.br/api/external/balance \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"
# PIX Cash-Out (POST -- con HMAC + Idempotency-Key)
BODY='{"amount":3000,"pix_key":"12345678901","pix_key_type":"cpf","description":"Pagamento"}'
HMAC=$(echo -n "$BODY" | openssl dgst -sha512 -hmac "$CLIENT_SECRET" | awk '{print $2}')
curl -X POST https://api.owem.com.br/api/external/pix/cash-out \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/json" \
-H "hmac: $HMAC" \
-H "Idempotency-Key: cashout-order-9876" \
-d "$BODY"Protecciones Adicionales
| Proteccion | Descripcion |
|---|---|
| Rate Limiting | 60.000 req/min por IP (autenticado). 5 req/min (sin autenticacion) |
| Cloud Armor (WAF) | Firewall de aplicacion protegiendo el cluster |
| HTTPS + TLS 1.2+ | Cifrado obligatorio en todas las conexiones |
| HSTS | Navegadores forzados a usar HTTPS |
Por que HMAC-SHA512 y no mTLS?
El mTLS (mutual TLS) autentica la conexion, no el contenido. Si la conexion esta autenticada, todas las solicitudes pasan sin validacion individual.
El HMAC valida cada solicitud por separado. Incluso dentro de una conexion valida, cualquier alteracion en el payload hace que la solicitud sea rechazada.
| Aspecto | mTLS | HMAC-SHA512 |
|---|---|---|
| Valida | Canal TLS | Payload de la solicitud |
| Gestion | Certificados X.509 (emision, rotacion, revocacion, CRL/OCSP) | Genera par, actualiza, invalida |
| Riesgo operacional | Certificados expirados -- causa frecuente de incidentes | Clave es string simple |
| Integridad del contenido | No | Si |
El TLS ya garantiza cifrado del transporte. El HMAC agrega integridad y autenticidad del payload -- algo que el mTLS por si solo no cubre.
Respuestas de Error
401 -- Credenciales Ausentes
{
"error": {
"status": 401,
"message": "Missing API key credentials. Use Authorization: ApiKey <client_id>:<client_secret>"
}
}403 -- IP no Autorizado
{
"error": {
"status": 403,
"message": "Request IP not in API key whitelist"
}
}429 -- Rate Limit Excedido
{
"error": {
"status": 429,
"message": "Too Many Requests"
}
}Seguridad
- Nunca exponga el
client_secreten codigo frontend o repositorios publicos - Utilice variables de entorno en su servidor
- La API Key es permanente -- no expira, pero puede ser revocada en el Merchant Portal
- Configure IPs permitidos en la whitelist