Saltar al contenido
Guía de cátedra 2026: API Gateway + Auth/Authz

Guía de cátedra 2026: API Gateway + Auth/Authz

3 de abril de 2026

En corto

  • Elegí auth propia si identidad, sesión y garantías demostrables forman parte del problema que el equipo quiere resolver.
  • Elegí IdP externo si querés delegar login y sesión, pero asumí desde el día uno que el dominio igual tendrá que resolver bloqueo de usuarios, ownership y fine-grained authorization.
  • Referencias rápidas: gateways e IdP externos.

El problema

En un monolito, login, sesión y permisos suelen sentirse como un único problema porque todo vive en la misma aplicación y comparte estado. En microservicios no: un mismo request cruza identidad, borde y dominio. Por eso no alcanza con “poner auth en el gateway”. (Microservices Auth Intro, Microsoft APIM Auth)

Por ejemplo, tomemos esta request: POST /orders/123/cancel.

  • Identidad. El usuario inicia sesión contra un IdP o auth service y obtiene una sesión y un bearer token.
  • Borde. El cliente llama a la API de entrada y el gateway o BFF (backend-for-frontend) decide si el request supera la primera barrera.
  • Dominio. El servicio de orders consulta ownership, estado del pedido, usuario bloqueado y rol efectivo. Recién ahí decide si la operación está permitida.

El borde autentica y filtra; el dominio autoriza de verdad. En un sistema distribuido no participa una sola identidad, la confianza cambia varias veces y la decisión real necesita datos que no viven todos en el mismo lugar. (Microservices Auth Intro, Google Identity Propagation, NIST API Protection)

Un segundo caso muestra otra clase de regla: POST /admin/users/123/block. Ahí ya no manda ownership, sino rol administrativo, alcance sobre la organización o tenant y trazabilidad de la acción. El token puede traer contexto inicial, pero la decisión real sigue dependiendo de política y estado actual.

    flowchart LR
    Client([Cliente])
    IdP([IdP])
    DOM[(Estado actual del dominio)]

    subgraph Borde
        GW["gateway o BFF<br/>PEP de borde"]
        TVL["validación de token"]
    end

    subgraph Plataforma
        AL["Authorization layer<br/>(opcional, PDP)"]
        DS["Domain service<br/>PEP final"]
    end

    Client -->|"bearer token"| GW
    GW -->|"firma / exp / formato"| TVL
    TVL -->|"JWKS / introspection"| IdP
    GW -->|"request + contexto"| AL
    AL -->|"blocked / roles"| DOM
    AL -->|"allow preliminar"| DS
    DS -->|"ownership / estado del recurso"| DOM
    DS -->|"allow / deny"| GW
    GW --> Client
  

Preguntas clave

  1. ¿Qué identidades participan en este request?
  2. ¿Dónde cambia la confianza dentro del sistema?
  3. ¿Cómo se propaga la identidad hasta el servicio que decide?
  4. ¿Quién toma la decisión de autorización real?
  5. ¿Qué datos necesita esa decisión y quién es dueño de esos datos?
  6. ¿Qué queda en el token y qué obliga a consultar el estado actual del dominio?

Qué resuelve cada capa

CapaResuelveNo resuelve
IdP / auth servicelogin, sesión, recupero y emisión de tokenpermisos reales de dominio
gateway / BFFvalidación inicial, rate limiting y filtro gruesoownership, bloqueo de usuarios, reglas de negocio
Servicio de dominioautorización real sobre el recursologin o manejo de sesión
Datos de dominioestado real: roles efectivos, ownership, flagsenforcement por sí solos

Vocabulario mínimo

  • AuthN: verificar quién es.
  • AuthZ: decidir qué puede hacer sobre un recurso.
  • BFF: backend-for-frontend; una capa backend pensada para una app o canal específico.
  • Claim: dato portable dentro del token.
  • Scope: permiso amplio, útil para filtros iniciales.
  • Coarse-grained authorization: “¿en principio este request podría pasar?”
  • Fine-grained authorization: “¿esta persona puede hacer esto, sobre este recurso, ahora?” (OAuth Resource Server, OPA, Keycloak Authz, Curity Claims)

Si la autorización empieza a repetirse o a cruzar muchos servicios, puede aparecer una Authorization Layer o policy engine. Ahí PDP decide y PEP hace cumplir. Conviene pensarlo como una opción de madurez, no como punto de partida. (OPA, Keycloak Authz)

Si necesitás la versión exhaustiva de esta tabla, está en el apéndice de matriz operativa.

Hasta acá separamos responsabilidades. El paso siguiente es entender quién actúa en cada tramo del request y dónde cambia la confianza.


Identidades y confianza

En auth distribuida no participa solo el usuario final. También existen el cliente, el BFF, el gateway y los servicios internos que se llaman entre sí.

Conviene distinguir explícitamente entre la autenticación y autorización del servicio llamador y la del usuario final. Esa diferencia importa porque un request puede transportar al mismo tiempo quién inició la acción y qué componente la está ejecutando en ese hop. (NIST API Protection)

En hops internos puede importar no solo la identidad del usuario, sino también la identidad del servicio que ejecuta la acción. User identity y service identity no son lo mismo, y conviene no mezclarlas.

Los puntos que más conviene marcar en el diseño son siempre los mismos: login, emisión del primer token, entrada por gateway o BFF, hops inter-servicio y cualquier token exchange u on-behalf-of flow. El diagrama de identidad y acceso tiene que mostrar dónde se emiten tokens, dónde cambia la confianza y dónde aparecen esos flujos. No alcanza con saber quién inició el request; también importa qué componente lo ejecuta en cada hop y bajo qué relación de confianza. (Azure Design Diagrams, NIST API Protection)

Propagación de identidad

Con ese mapa, la siguiente decisión ya no es quién participa sino cómo llega la identidad hasta el servicio que protege el recurso.

DiseñoQué viaja hasta backendVentaja principalCosto principal
External token propagationel token emitido por el IdPcontexto end-to-end, mejor auditoría, menos moving partsmás acoplamiento al proveedor
Token exchange / internal tokenun token interno de plataformadesacopla al IdP y normaliza credenciales dentro del sistemamás emisión, renovación y superficie de seguridad

External token propagation

El token emitido por el proveedor cruza el borde y sigue viaje hacia backend. Propagar el security context end-to-end mejora la auditoría, evita cuentas genéricas privilegiadas y habilita decisiones más ricas en backend. (Google Identity Propagation, Microservices JWT Authz)

    flowchart LR
    subgraph A["External token propagation"]
        direction LR
        IdP1[IdP] -->|token del IdP| Client1[cliente]
        Client1 -->|mismo token| Edge1[gateway o BFF]
        Edge1 -->|mismo token| Svc1[servicio]
    end
  

Token exchange / internal token

El borde o un auth service valida el token externo y lo intercambia por uno interno. Hay un mecanismo estándar para ese intercambio. También puede servir para cambiar de credencial cuando entra el request a la plataforma, desacoplar a los servicios del proveedor externo y fijar una semántica propia de plataforma. El costo es más serio: claves, expiración, renovación y más decisiones de seguridad. (Token Exchange, NIST API Protection)

    flowchart LR
    subgraph B["Token exchange / internal token"]
        direction LR
        IdP2[IdP] -->|token del IdP| Client2[cliente]
        Client2 -->|token externo| Edge2[gateway o auth service]
        Edge2 -->|valida y reemite| Internal[token interno]
        Internal --> Svc2[servicio]
    end
  

En la práctica, esta decisión define cuánto contexto viaja end-to-end y cuánto costo operativo asumís para desacoplar la plataforma del proveedor.


Autenticación en el borde

PatrónQué hace el bordeCuándo encajaLímite principal
Validación local de JWT/JWKSverifica firma y claims localmenteaccess token JWT y baja latenciano ve estado fresco por sí solo
Introspection remotaconsulta online si el token está activotokens opacos o necesidad de validación revocation-awaremás latencia y dependencia de red
Delegación a servicio externo de authpregunta a un auth service propiocuando el gateway OSS no resuelve nativamente lo que hace faltaotro hop y contrato propio
Login/sesión mediado por gateway o BFFel borde participa más directamente del flujo OAuth/OIDCapps web o BFFs que concentran sesiónmás moving parts en el borde

Validación local de JWT/JWKS

Elegila cuando priorizás latencia y el access token ya trae suficiente contexto inicial. El patrón clásico del resource server: firma, expiración, formato y claims básicos se verifican localmente. Si el access token es un JWT, existe un perfil interoperable para ese caso. Lo que no resuelve por sí solo es revocación, usuario bloqueado, rol efectivo, ownership o reglas de negocio. (OAuth Resource Server, JWT Access Token Profile)

Introspection remota

Conviene cuando necesitás estado más fresco o trabajás con tokens opacos. El borde le pregunta online al authorization server si el token está activo. Ese camino tiene un estándar claro, pero aumenta la dependencia de red y disponibilidad. (Token Introspection)

External auth

Encaja cuando querés unificar lógica común sin meterla entera en el gateway. Un patrón común es delegar la decisión inicial a un endpoint externo, por ejemplo con ext_authz o ForwardAuth. Es útil cuando el gateway OSS no trae capacidades nativas suficientes o cuando el equipo quiere concentrar autenticación común en un servicio propio. (Envoy ext_authz, Traefik ForwardAuth)

gateway/BFF como cliente OIDC

Tiene sentido cuando el borde también administra login o sesión de una app web. El borde participa más directamente del flujo de login o sesión y puede actuar como cliente OAuth/OIDC o Relying Party. Conviene especialmente en aplicaciones web y BFFs. No es sinónimo de validar un bearer token ya emitido. (OpenID Connect, API Gateway Pattern)

Si querés bajar estos patrones a herramientas concretas, fijate el apéndice de gateways.

Hasta acá definiste qué contexto viaja y cómo lo valida el borde. Falta lo más difícil: con qué datos decide el dominio.


Autorización distribuida

La responsabilidad primaria de autorización sigue estando en los servicios, porque son quienes protegen recursos concretos y quienes pueden acceder a datos de aplicación. En el borde solo ves el request; en el dominio ves el recurso, su estado y sus relaciones. (Microservices JWT Authz)

Ojo con esto. Un bearer token válido no prueba que una operación esté permitida. Prueba identidad y contexto de acceso. El permiso real puede depender de ownership, estado del recurso, tenant, suspensión del usuario o reglas de negocio.

Claims y scopes

Un claim es un dato que viene dentro del token. Un scope es un permiso de alto nivel que también puede viajar en el token y suele expresarse como una cadena tipo orders.read. claims y scopes sirven para coarse-grained authorization. Funcionan bien cuando el dato es chico, estable y suficientemente genérico para viajar en el token:

  • scope=payments.read
  • role=admin
  • aud=orders-api
Esto es un ejemplo de access token
{
  "iss": "https://iam.example.com",
  "sub": "user_123",
  "aud": "orders-api",
  "exp": 1765197600,
  "iat": 1765194000,
  "nbf": 1765194000,
  "jti": "01HT8M9Y7K4Q2R6W8X1Z3A5B7C",
  "client_id": "mobile-app",
  "scope": "orders.read orders.cancel",
  "role": "customer",
  "user_id": 123,
  "tenant_id": "tenant_42",
  "organization_id": "org_7",
  "amr": ["pwd", "mfa"],
  "delegation_id": "9c4b4d1a-6a66-4e56-8f76-2c5031d9a41b"
}

No todos los tokens llevan todos esos campos, y los nombres cambian según el IdP o el diseño de la plataforma. tenant_id, organization_id, amr o delegation_id son ejemplos opcionales. Lo importante no es memorizar nombres, sino distinguir qué conviene llevar en el token y qué sigue dependiendo del estado actual del dominio.

Los claims y scopes sirven para filtros iniciales y para parte de la autorización, pero no para todo. Cuando la autorización es muy cambiante o depende de permisos de negocio volátiles, el token por sí solo no alcanza. (Curity Claims, Microservices JWT Authz)

Datos para decidir

Un isAllowed(user, operation, resource) necesita más que identidad. Para tomar esa decisión conviene separar tres categorías. (Microservices JWT Authz)

  • built-in: identidad y roles que vienen del token;
  • local: datos del propio servicio;
  • remote: datos que pertenecen a otros servicios.

Ahí aparece la parte realmente distribuida del problema. Ownership, estado de bloqueo, relaciones, flags y permisos volátiles obligan a consultar el estado actual del dominio o a mantener una estrategia explícita para obtener esos datos. Conviene usar claims estables para filtrar y combinarlos con business permissions volátiles cuando la regla real depende del dominio. (Curity Claims, Microservices JWT Authz, OPA, Keycloak Authz)


Quién resuelve identidad

Antes de discutir Firebase, Clerk o Keycloak, hay que entender qué están eligiendo: quién resuelve login, sesión y emisión de tokens. Eso no incluye fine-grained authorization de negocio, que sigue siendo responsabilidad propia independientemente del proveedor.

También conviene separar tres piezas que suelen mezclarse:

  • ID token: le dice al cliente quién es el usuario.
  • access token: sirve para llamar APIs.
  • refresh token: renueva la sesión sin volver a autenticarse.

Un error clásico es usar el ID token como si fuera el token de autorización de la API. Para la API, el token relevante suele ser el access token. (OpenID Connect, OAuth Refresh Tokens, OAuth Resource Server)

Si querés comparar proveedores concretos de identidad, está el apéndice de IdP externos.

auth propia

Conviene cuando el equipo necesita controlar de punta a punta cómo se resuelven login, sesión, emisión de tokens y manejo de credenciales, o cuando esa implementación forma parte de lo que después va a tener que defender técnicamente. Eso incluye registro, login, hashing, recupero, refresh tokens y emisión de JWT.

No implica escribir todo desde cero —Spring Authorization Server, las utilidades OAuth2/JWT de FastAPI o node-oidc-provider cubren una parte importante del trabajo commodity— pero la seguridad, la operación y las garantías siguen siendo del equipo. (Spring Auth Server, FastAPI Security, node-oidc-provider)

Vale distinguir también entre auth para la propia app y un authorization server OAuth/OIDC reutilizable para terceros. Lo segundo involucra mucho más superficie, y mezclar los dos objetivos es una fuente frecuente de scope creep en el proyecto.

Trade-offDetalle
A favorControl total sobre identidad, sesiones y claims. Es la opción correcta si el equipo necesita flujos propios, independencia del proveedor o demostrar garantías que ellos mismos implementaron.
A favorCon librerías modernas, el volumen de código commodity es bastante menor de lo que sugiere la intuición inicial.
En contraSeguridad, sesiones, recupero, almacenamiento seguro, revocación, auditoría y mitigaciones de abuso quedan bajo responsabilidad del equipo. (OWASP AuthN, OWASP Passwords)

IdP externo

Si el equipo no quiere construir login, sesión y recuperación desde cero, puede delegar esa parte en un IdP externo. La decisión real no es “usar Firebase o no”, sino qué parte de identidad resuelve el proveedor y qué parte sigue siendo responsabilidad de la plataforma.

Lo que ningún proveedor resuelve por ustedes es si el usuario está bloqueado, qué recursos son suyos, qué flags de negocio aplican y cómo se decide la fine-grained authorization. Eso sigue siendo responsabilidad del equipo y debe persistirse en el sistema independientemente de quién emite el token. Si quieren comparar proveedores concretos, vean el apéndice de IdP externos. (Firebase Auth, Clerk Quickstart, Keycloak, Supabase Auth)

Criterio de validez

La regla es simple: la cátedra pide un piso de controles. Si hacen auth propia, ustedes lo implementan. Si usan un IdP externo, tienen que poder demostrar que ese proveedor cubre ese mismo piso.

Como mínimo:

Elegir un IdP externo no se justifica solo por ir más rápido. Si ese piso no puede demostrarse con precisión y con evidencia oficial, delegar identidad no alcanza como defensa arquitectónica. En ese caso, la opción que queda bien defendida es auth propia.

Checklist ADR

  • ¿Qué valida el borde y qué necesita decidir el servicio que ejecuta la operación?
  • ¿Qué decisiones se toman con claims del token y cuáles dependen del estado actual del dominio?
  • ¿Qué datos externos al token necesita la autorización y de qué servicio salen?
  • ¿Cómo llega la identidad al backend: token original, token intercambiado o contexto propagado?
  • ¿Qué componente toma la decisión final y por qué ese componente tiene los datos correctos para tomarla?
  • ¿Qué parte se delega al IdP y qué parte sigue siendo responsabilidad propia?
  • ¿Qué limitación concreta de la solución elegida aceptamos a cambio de sus beneficios?

Apéndice: Matriz operativa

Si necesitás una referencia más exhaustiva para ADR o corrección, esta es la versión detallada de responsabilidades por capa.

Responsabilidad¿Pasa por el gateway?Dónde se implementa
Login federado con Google (optativo)No (valida el token después)IdP externo
Login con email/passwordNoIdP externo o auth propia
Registro con email/passwordNoIdP externo o auth propia
Recupero de contraseñaNoIdP externo o auth propia
Hash de contraseñas (ej. BCrypt o scrypt)NoDelegado al IdP o resuelto por auth propia
Reglas mínimas de contraseñaNoDepende de la opción de identidad elegida
Renovación de sesiónNoDepende de la opción de identidad elegida
Emisión del token de APINo (solo valida)IdP o auth service propio
Validación del token de APIgateway
Decisión de fine-grained authorizationNoDomain services o Authorization Layer
Rate limiting por IPgateway
Rate limiting por cuenta/emailParcial (ver nota)auth service
Bloqueo de usuarioNoBackend + DB de dominio
Roles básicos (user/admin)Parcial (claims/scopes)Estado real en DB propia
Ownership y fine-grained authorizationNoEnforcement final en backend con datos del dominio
Minimización de datosNoBackend del dominio
Ocultar recursos de usuario bloqueadoNoBackend + queries de dominio
Idempotencia de operaciones críticasNoServicios de dominio
/livez y /readyzNoCada servicio, incluido auth/user

Nota. Rate limiting por cuenta/email suele caer en auth service porque el identificador viene en el body. claims y scopes sirven para coarse-grained authorization, pero no reemplazan fine-grained authorization ni el estado real del dominio. (KrakenD Rate Limit, OAuth Resource Server)


Apéndice: Gateways

Con el diseño claro, recién tiene sentido bajar a productos.

ProductoModelo mentalEncaja mejor cuando…Ojo con…
Traefik OSS + ForwardAuthapplication proxy con auth delegadaquerés delegar autenticación a un servicio externo y mantener el gateway simpleForwardAuth está en OSS, pero la historia fuerte de OIDC aparece en Traefik Hub. (Traefik Features, Traefik ForwardAuth, Traefik Docker, Traefik Hub OIDC)
KrakenD CEBFF / API gateway declarativobuscás validación local de JWT y agregación/BFF con pocas piezasno es el caso más natural para una arquitectura basada en auth service externo por request. (KrakenD JWT, KrakenD Docker, API Gateway Pattern)
Tyk OSSgateway más “batteries included”querés buen encaje con IdP externo y una superficie más fuerte de policiesarrastra Redis como costo operativo. (Tyk OSS, Tyk Install, Tyk OIDC)
Kong OSSgateway plugin-basedte sirve validación local de JWT/JWKS, routing y rate limitingel plugin JWT OSS encaja bien; OpenID Connect e introspection figuran como capacidades Enterprise. (Kong DB-less, Kong JWT, Kong JWT Claims, Kong OIDC, Kong Introspection)
Apache APISIXgateway cloud-native de pluginsquerés flexibilidad con openid-connect, introspection y RP flowla flexibilidad viene con más configuración explícita. (Apache APISIX, APISIX Deploy)

Sin Kubernetes: todas estas opciones corren con contenedores. (KrakenD Docker, Tyk OSS, Kong Docker, Traefik Docker, APISIX Deploy)


Apéndice: IdP externos

Esto sirve como referencia rápida de opciones concretas. Primero definan el criterio de validez; recién después comparen proveedor.

OpciónTipoQué simplificaTrade-off principal
ClerkIdP gestionadoUI prearmada para sign-in, perfil y flujos comunes; integración rápida. (Clerk Pricing, Clerk SignIn, Clerk UserProfile)Muy poca fricción, pero más dependencia de un servicio cerrado.
Firebase AuthenticationIdP gestionado, muy usado en mobileEmail/password, reset, proveedores federados y buen encaje con apps mobile. (Firebase Auth)Muy práctico, pero varias garantías finas siguen delegadas al proveedor.
Supabase AuthAuth integrada a plataforma backendPassword, magic link, OTP, social login y buen fit si también usan DB/storage de Supabase. (Supabase Auth, Supabase Billing)Cómodo, pero suma dependencia de plataforma, no solo de identidad.
Auth0Plataforma de identidad más enterprisePasswordless, social login, custom domains y conexiones enterprise. (Auth0 Pricing, Auth0 Custom Domains, Auth0 Passwordless)Muy completo, pero puede sentirse más pesado que otras opciones de esta guía.
KeycloakIdP self-hosted / auth serverOIDC, OAuth2, SAML, consola admin y Authorization Services. (Keycloak, Keycloak Admin, Keycloak Authz)Resuelve mucho sin auth propia, pero hay que operarlo: contenedor, DB y configuración propia. (Keycloak Container, Keycloak DB)

Apéndice: Caso Firebase

Firebase aparece mucho en proyectos mobile y por eso tiende a colonizar el vocabulario del diseño. Vale entender bien qué resuelve y qué no.

  • verifyIdToken() no chequea revocación. Un gateway que valida offline tampoco ve disabled=true de forma inmediata. Un usuario bloqueado puede seguir pasando la barra práctica si su token no venció. (Firebase Verify, Token Introspection)
  • Los custom claims sirven para coarse-grained authorization, no como depósito de datos de negocio. Los cambios se propagan solo cuando el usuario reautentica o refresca el token. (Firebase Claims, OAuth Resource Server)
  • Hashing y reset son controles delegados. Si la cátedra exige garantías precisas sobre TTL máximo, single-use o almacenamiento del token de reset, hay que poder demostrarlas con documentación oficial. Si no, hay que implementarlas. (Firebase Scrypt, Firebase REST Auth, Firebase Admin)