Auth: GitHub OAuth, Keycloak/OIDC y RBAC

Objetivos del capítulo
  • Configurar GitHub OAuth como provider de dev.

  • Montar Keycloak como IdP para el laboratorio.

  • Aplicar RBAC con permission-backend.

  • Definir sign-in resolvers.

Identidad: quién entra al restaurante

Una IDP sin auth es un restaurante sin maître: cualquiera entra y nadie sabe a quién cobrarle. Necesitamos saber quién es cada developer (autenticación) y qué puede hacer (autorización). Backstage soporta OAuth/OIDC y RBAC.

Flujo OAuth/OIDC

Flujo OAuth/OIDC: del browser al Principal
Failed to generate image: Could not find the 'mmdc' executable in PATH; add it to the PATH or specify its location using the 'mmdc' document attribute
sequenceDiagram
  participant Browser
  participant IdP as IdP (GitHub/Keycloak)
  participant BS as Backstage
  participant Cat as Catalog
  Browser->>BS: GET /home
  BS->>Browser: 302 redirect to IdP
  Browser->>IdP: login + consent
  IdP->>Browser: code
  Browser->>BS: /auth/github/handler?code=...
  BS->>IdP: exchange code for token
  IdP->>BS: access_token + userinfo
  BS->>BS: resolver maps to User
  BS->>Cat: lookup User entity
  Cat->>BS: User metadata
  BS->>Browser: set session cookie, 200 OK

GitHub OAuth (desarrollo)

Para development, GitHub OAuth es lo más rápido:

Unresolved directive in chapters/cap-14-auth-github-keycloak-rbac.adoc - include::../../chapters/chapter-14-auth/config/auth-providers.yaml[tag=github-oauth-config]
Nunca pegues secrets en el repo
  • :code:`clientSecret` viene de variable de entorno, no del YAML en git.

  • Para desarrollo local, :code:`app-config.local.yaml` (gitignored).

  • Para producción, el secreto se inyecta por el sistema de deploy (sealed-secrets, external-secrets).

Sobre el callback

El callback es :code:`http://localhost:7007/auth/github/handler/development`. GitHub lo registra como OAuth app. En producción es :code:`https://idp.tuempresa.com/auth/github/handler`.

Keycloak/OIDC (laboratorio y producción)

Para una instalación seria, Keycloak te da SSO, MFA, grupos y proveedores federados.

Unresolved directive in chapters/cap-14-auth-github-keycloak-rbac.adoc - include::../../chapters/chapter-14-auth/config/auth-providers.yaml[tag=keycloak-config]
Por qué Keycloak y no GitHub en producción
  • MFA real (TOTP, WebAuthn).

  • Grupos en el token (claim groups) para mapear a Group del catalog.

  • SAML/OIDC federado con tu IdP corporativo (Okta, Azure AD, etc.).

  • Auditoría centralizada.

Sign-in resolvers

El signIn.resolver mapea el usuario autenticado a una entidad User del catalog. Sin esto, no hay identidad útil.

Resolvers comunes
  • :code:`emailLocalPartMatchingUserEntityName` — el prefijo del email coincide con metadata.name del User.

  • :code:`usernameMatchingUserEntityName` — el preferred_username coincide.

  • :code:`oidcEmailLocalPartMatchingUserEntityName` — para Keycloak y otros OIDC.

Buena práctica

En producción, crea un User en el catalog por cada developer que se loguee, con su spec.memberOf apuntando a sus `Group`s. El resolver los empareja por email; el catalog los enriquece con grupos.

RBAC con permission-backend

El plugin @backstage/plugin-permission-backend aplica políticas de autorización. Lo registras como un módulo del backend:

Unresolved directive in chapters/cap-14-auth-github-keycloak-rbac.adoc - include::../../chapters/chapter-14-auth/config/auth-providers.yaml[tag=rbac-policies]
¿Qué cubre RBAC?
  • Acciones sobre el catalog (entity.create, entity.delete, location.create).

  • Acciones sobre el scaffolder (template.execute).

  • Acciones sobre plugins custom que pidan PermissionsService.

No cubre: acceso a endpoints HTTP. Para eso, el endpoint usa PermissionsService directamente (ver :cap-07).

RBAC: policy + effect + condition
Failed to generate image: Could not find the 'mmdc' executable in PATH; add it to the PATH or specify its location using the 'mmdc' document attribute
flowchart LR
  Subject[Subject] --> Effect{allow/deny}
  Effect --> Action[Action]
  Effect --> Resource[Resource]
  Effect --> Condition{condition}
  Condition -->|true| Allow[allow]
  Condition -->|false| Deny[deny]

Cómo se aplica en el cliente

Una vez configurado, el frontend oculta botones según los permisos del usuario. La página /settings lista tus roles efectivos.

Example 14. Receta del capítulo
  1. Crea una GitHub OAuth app y registra el callback.

  2. Configura el provider en auth.providers.github.

  3. Añade un signIn.resolver para mapear a User.

  4. Para producción, monta Keycloak y configura el provider OIDC.

  5. Define políticas RBAC en permission.rbac.policies.

Resumen

  • Auth = OAuth/OIDC + sign-in resolver + User entity en el catalog.

  • GitHub OAuth vale para dev; Keycloak vale para producción.

  • RBAC aplica políticas declarativas sobre acciones y recursos.

  • output.visible: false y secretos fuera del repo son obligatorios.

Glosario del capítulo

OAuth

Protocolo de delegación de autorización (GitHub, Google, etc.).

OIDC

Capa de identidad sobre OAuth 2.0 (OpenID Connect).

IdP

Identity Provider. Servicio que autentica al usuario (GitHub, Keycloak, Okta).

signIn.resolver

Función que mapea el usuario autenticado a una entidad User.

RBAC

Role-Based Access Control. Modelo "allow/deny" sobre acciones y recursos.

PermissionPolicy

Función TypeScript que evalúa si una acción está permitida.

Próximo capítulo

Backstage en producción —despliegue con Docker Compose y kind, monitoring, y métricas de éxito.