API keys de empresas hijas
Emite, rota y revoca API keys acotadas a una sola empresa hija, derivando sus scopes de la key llamante — los endpoints api_keys bajo una empresa gestionada.
Cada empresa gestionada tiene su propio juego de API keys.
Una key hija autentica peticiones en nombre de esa única empresa — nunca
alcanza a las empresas hermanas ni al tenant maestro. Es la alternativa a manejar
una hija con el header X-Active-Profile: una key
hija queda ligada a una empresa para siempre, en vez de cambiarse por petición.
Cinco endpoints bajo /v1/companies/{id}/api-keys cubren su ciclo de vida.
| Operación | Endpoint | Scope |
|---|---|---|
| Listar keys hijas | GET /v1/companies/{id}/api-keys | api_keys:read |
| Crear una key hija | POST /v1/companies/{id}/api-keys | api_keys:write |
| Recuperar una key hija | GET /v1/companies/{id}/api-keys/{key} | api_keys:read |
| Rotar el secret | POST /v1/companies/{id}/api-keys/{key}/rotate-secret | api_keys:write |
| Revocar una key hija | DELETE /v1/companies/{id}/api-keys/{key} | api_keys:write |
Esto replica el autoservicio de API keys a nivel de cuenta,
pero acotado a una empresa hija en vez de a tu propia cuenta. Tanto {id} (la
empresa) como {key} (la API key) son valores UUID v7 opacos.
Crea una key hija
POST /v1/companies/{id}/api-keys emite una key para la empresa y devuelve su
secret en texto plano exactamente una vez. Requiere el scope
api_keys:write.
curl -X POST \
https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c/api-keys \
-H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "Producción Talleres García",
"scopes": ["invoices:read", "invoices:write"]
}'Respuesta (201):
{
"data": {
"object": "api_key",
"id": "0190f2c0-77aa-7b21-8c33-1d2e3f405162",
"name": "Producción Talleres García",
"prefix": "fact_live_1OSf9KdP",
"secret": "fact_live_1OSf9KdPR2VbY7TcA9eFmN5z",
"scopes": ["invoices:read", "invoices:write"],
"tier": "scale",
"environment": "live"
}
}El secret se muestra solo en esta respuesta 201 y tras una rotación.
Ningún endpoint lo devuelve después. Persístelo en un gestor de secretos en
cuanto lo recibas — nunca en un log ni en un repositorio. Si lo pierdes, rota
la key.
Los scopes deben ser un subconjunto de la key padre
Los scopes que pides para una key hija deben ser un subconjunto de los de la
key que hace la llamada. Pedir un scope que la key llamante no tiene devuelve
422 con errores por campo — sin recorte silencioso: la key no se crea con
una lista de scopes acortada, falla la petición entera.
{
"error": {
"type": "validation_error",
"code": "validation_failed",
"message": "No puedes conceder un scope que tu propia key no tiene.",
"param": "scopes"
}
}Así, una key con invoices:read invoices:write puede emitir keys hijas con
cualquier subconjunto de esos dos scopes, pero nunca con clients:write.
Aprovisiona primero una key maestra con scopes suficientes y deriva de ella keys
hijas más estrechas. El environment y el tier nunca se toman del cuerpo — se
heredan de la key llamante.
| Campo | Obligatorio | Notas |
|---|---|---|
name | sí | Etiqueta legible (1–120 caracteres). |
scopes | sí | Uno o más scopes, cada uno subconjunto de los de la key llamante. |
expires_at | no | Instante futuro ISO 8601 a partir del cual la key deja de autenticar. |
ip_allowlist | no | Lista opcional de IPs / CIDR permitidas (IPv4, IPv6, /N). |
Rota el secret
POST /v1/companies/{id}/api-keys/{key}/rotate-secret invalida de inmediato el
secret actual, genera un nuevo prefix + secret, y devuelve el nuevo secret en
texto plano exactamente una vez. Requiere el scope api_keys:write.
curl -X POST \
https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c/api-keys/0190f2c0-77aa-7b21-8c33-1d2e3f405162/rotate-secret \
-H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"La rotación surte efecto al instante: cualquier petición que siga usando el secret anterior deja de autenticar en cuanto rotas. Despliega el nuevo secret antes de — o de forma atómica con — la rotación para evitar downtime. Es irreversible.
Revoca una key hija
DELETE /v1/companies/{id}/api-keys/{key} revoca una key hija de forma
permanente. Las peticiones posteriores autenticadas con ella dejan de funcionar.
Requiere el scope api_keys:write.
curl -X DELETE \
https://api.factuarea.com/v1/companies/01931b3e-7c4a-7f2e-9a8b-4d6e7f8a9b0c/api-keys/0190f2c0-77aa-7b21-8c33-1d2e3f405162 \
-H "Authorization: Bearer fact_live_8KqW3pXnR2VbY7TcA9eFmN5z"La revocación es irreversible. Una vez revocada, la key no se puede restaurar — emite una nueva si la empresa todavía necesita acceso a la API.
Scopes y aislamiento
Las keys hijas se protegen con los scopes de api_keys:
api_keys:read— listar y recuperar keys hijas.api_keys:write— crear, rotar y revocar keys hijas.
Toda operación está acotada a tu tenant maestro. Un id de empresa que pertenece
a otro maestro devuelve 404 — nunca 403, ni un endpoint de key hija de una
empresa que no gestionas. Es el mismo aislamiento entre maestros que rige las
empresas en sí: un maestro solo ve y actúa sobre sus
propias empresas y sus keys.