Skip to main content
Todos los endpoints viven bajo el origen del issuer canónico auth.* del entorno. Ningún endpoint de cara al cliente apunta al motor subyacente — incluso /.well-known/* se sirve desde el issuer. Los ejemplos a continuación usan la URL base de producción https://auth.bbrands.io; sustituye por la base de cada entorno:

Convenciones

  • Content-Type: application/json, excepto los endpoints OAuth que usan application/x-www-form-urlencoded.
  • Transporte: solo HTTPS (TLS 1.2+).
  • Caché: Cache-Control: no-store en cada endpoint OAuth.
  • Errores: los endpoints OAuth devuelven {"error": "...", "error_description": "..."}.
  • Correlación: cada respuesta transporta X-Request-Id.

Discovery

GET /.well-known/openid-configuration

Devuelve el documento de discovery OIDC. Público, sin auth. Apunta la autoconfiguración de tu cliente a esta URL.
El iss en el discovery y en cada token de acceso emitido es la URL canónica auth.* por entorno — nunca la URL del motor subyacente. El registration_endpoint intencionalmente no se expone: el registro dinámico de clientes está desactivado; los clientes se dan de alta a través de la consola de administración de identidad.
id_token_signing_alg_values_supported lista ["ES256"] por defecto y ["ES256", "RS256"] en los entornos donde la vía RS256 del id_token está habilitada. ES256 es siempre el algoritmo por defecto; RS256 solo aplica a los clientes registrados con id_token_alg: "RS256" (p. ej. Odoo).

GET /.well-known/jwks.json

Devuelve las claves públicas para validar los JWT OAuth. Público. Servido por el IdP (proxy/caché del JWKS del motor); el cliente nunca ve la URL del motor.
Response headers
JWKS aplica solo a los tokens OAuth. El JWT interno HS256 de B Brands se valida con un secreto simétrico del lado del servidor y nunca se expone aquí.
En los entornos con la vía RS256 habilitada, el documento contiene la clave EC P-256 del motor más la clave pública RSA del IdP (ambas con kid). Los verificadores resuelven las claves por kid, así que la clave extra es transparente para los clientes ES256.

Endpoint de autorización

GET /api/v3/oauth/authorize

Inicia el flujo de authorization-code. Llamado por el navegador del usuario tras una redirección desde el cliente. La solicitud se valida estrictamente, se reenvía al motor, y el navegador se redirige a la UI de consentimiento en el mismo origen auth.*.
string
requerido
Debe ser code.
string
requerido
El identificador del cliente OAuth registrado (UUID provisto en el onboarding).
string
requerido
Debe coincidir exactamente con una de las redirect URIs registradas del cliente.
string
requerido
Lista separada por espacios. Debe incluir openid. Soportados: openid email profile.
string
requerido
Valor anti-CSRF del cliente, devuelto en la redirección.
string
requerido
Challenge PKCE. PKCE es obligatorio para cada cliente.
string
requerido
Debe ser S256 (plain se rechaza).
string
Recomendado. Valor anti-replay del ID-token.
Respuesta: redirección 302 a https://auth.bbrands.io/oauth/consent?... (la UI de consentimiento). Con una sesión válida y un cliente first-party habilitado, el consentimiento se autoaprueba y el navegador se redirige de vuelta al cliente con ?code&state. Los errores de validación se devuelven como JSON 400 (sin redirección, ya que el redirect_uri no puede considerarse confiable antes de la validación):

Consentimiento

UI de consentimiento — https://auth.bbrands.io/oauth/consent

Servida por la app de autenticación (no una API). Valida la sesión de B Brands (redirigiendo al login con ?next= cuando falta), muestra el nombre del cliente y los scopes OIDC solicitados, y ofrece Permitir / Denegar. Los usuarios first_party + habilitados se autoaprueban.

POST /api/v3/oauth/decision

Registra la decisión de consentimiento del usuario para auditoría. No continúa el flujo de código OAuth (el motor lo hace, vía el authorize_url).
string
requerido
Handle estable del cliente, p. ej. erp-prod.
string
requerido
approve o deny.
string[]
Scopes solicitados.
string
Identificador del usuario.
Un client_handle faltante o un decision inválido devuelve 400.

Endpoint de token

POST /api/v3/oauth/token

Intercambia un código de autorización por tokens, o refresca un token de acceso. Llamado servidor a servidor por el cliente. El gateway hace proxy de la solicitud al motor, que ejecuta el hook de token de acceso (verificación de habilitación + reescritura de iss/aud). Headers: Content-Type: application/x-www-form-urlencoded y Authorization: Basic <base64(client_id:client_secret)> (o el secreto en el cuerpo para client_secret_post).
El token de acceso transporta los claims de identidad canónicos — valídalo contra el issuer y el JWKS:
aud es la audiencia fija del IdP bbrands-idp; el cliente solicitante se identifica por https://bbrands.io/client_handle (y client_id). Valida iss, la firma ES256 vía JWKS, y que client_handle coincida con tu propio handle. El id_token conserva el issuer/audience del motor y está pensado para la verificación de nonce y los claims de perfil; usa el token de acceso como la aserción de identidad.
Vía RS256 del id_token: los clientes registrados con id_token_alg: "RS256" (p. ej. Odoo con el módulo OCA auth_oidc) reciben el mismo id_token re-firmado con la clave RSA del IdP — header alg: RS256 con un kid que resuelve vía /.well-known/jwks.json, con todos los claims preservados (nonce, at_hash, exp, …). El token de acceso siempre es ES256.
Errores típicos (mapeo OAuth):

Endpoint UserInfo

GET /api/v3/oauth/userinfo

Devuelve los claims de identidad del usuario, enriquecidos con la dimensión de cuenta de negocio. Con proxy al userinfo del motor. Headers: Authorization: Bearer <access_token> (obligatorio; un header faltante devuelve 401 invalid_token con WWW-Authenticate: Bearer).
Sin claim de permisos/roles. UserInfo es identidad más contexto de tenancy: el objeto https://bbrands.io/profile lleva la cuenta vinculada al usuario mediante el rol primary_user (account), el id del sistema externo de esa cuenta (odoo, null hasta que la API de migración la mapee) y el sujeto (user, igual a sub).

Endpoint de revocación

POST /api/v3/oauth/revoke

Invalida un token (RFC 7009), típicamente al cerrar sesión. Agrega el jti del token al store de blacklist local y hace proxy de la revocación al motor. Body (application/x-www-form-urlencoded): token, token_type_hint (access_token | refresh_token), client_id.
Según la RFC 7009 la respuesta es siempre 200 y opaca, independientemente de si el token existía.

Códigos de error personalizados

Más allá de los errores OAuth estándar, los endpoints específicos de B Brands pueden devolver estos en error.code:

Rate limiting

Las respuestas incluyen X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset; 429 transporta Retry-After.