Skip to main content
Reference for security reviews and conversations with the Security team. As always: the IdP authenticates, it does not authorize applications.

1. Token model

Key distinction: ES256 tokens prove identity and are consumed by the client app — they never reach the B Brands APIs. The HS256 token is consumed by the B Brands APIs via the existing internal authorizer.

Canonical OAuth access token claims (identity + account dimension)

Inviolable rules: iss is always the per-environment auth.* URL; aud is always the fixed IdP audience bbrands-idp; the requesting client is carried in https://bbrands.io/client_handle; jti is always present and drives the blacklist; there is no permissions or role claim. The https://bbrands.io/profile claim carries tenancy context only: account is the account bound to the user strictly through the primary_user role (one primary user per account), odoo is that account’s external system id (null until the account is mapped by the migration API) and user mirrors sub. The UserInfo endpoint returns the same object.

Client-side validation

2. Where authorization lives

The exchange JWT grants the client the user’s full permissions in B Brands (no per-client least-privilege). Acceptable for trusted first-party clients; introduce scoping in the exchange if you need to narrow it.

3. Secret management

Storage rules: never in the repository, never in logs (mask Authorization headers), never in webhook payloads, encrypted at rest, access restricted to IdP admins.

client_secret rotation

1

Admin clicks Rotate

B Brands generates a new secret.
2

Grace period

Old and new are accepted simultaneously for a configurable grace window (default 24h).
3

Client updates config

At any point during the grace window.
4

Grace ends

The old secret stops being accepted; audit logs the rotation.

ES256 signing key rotation

The engine supports kid-based rotation. Generate the new key, keep both active, wait the max access-token TTL (30 min) + buffer (1h), retire the old key, then remove after retention. The JWKS endpoint must expose both during the window.

4. Threat model (mini-STRIDE)

5. Revocation levels

6. Audit requirements

  • Immutable: append-only, no UPDATE/DELETE.
  • Traceable: actor, ip, user_agent, correlation_id.
  • Retention: 12 months online, longer in cold storage.
  • Exportable: /idp/audit/users/:id/export for GDPR/compliance.
  • Never logged: full tokens (only jti prefix), plaintext secrets, passwords.

7. Defense in depth