Skip to content

Authentication, Authorization & Identity Architecture

Status: ACCEPTED — I1-B4 Technology Decision Gate
Accepted: 2026-09-21
Depends on: Foundation v1.0, I1-B1, I1-B2, I1-B3

Core boundary

Touriffique separates authentication from business authorization.

Keycloak
  authenticates principals
        ↓
Touriffique Platform
  resolves User
  resolves tenant/platform context
  evaluates permissions + scopes
  evaluates entitlements
  applies domain policy

Keycloak is not the Tenant, membership, role-scope, Customer or entitlement database.

Identity provider

The accepted identity provider baseline is Keycloak 26.x.

Normal compatible security/patch upgrades within the accepted major line do not reopen I1-B4.

Keycloak persistence is operationally separate from Touriffique's application schemas and TypeORM migrations. The exact database/hosting topology for Keycloak is an infrastructure decision handled later.

Realm model

Use one Touriffique human-identity realm per environment.

development -> Touriffique development realm
staging     -> Touriffique staging realm
production  -> Touriffique production realm

Do not create one Keycloak realm per Tenant.

Tenant isolation and membership exist inside Touriffique application state.

Interactive authentication

Browser sign-in uses:

OpenID Connect
Authorization Code Flow
PKCE S256

Touriffique applications do not use:

  • OAuth Resource Owner Password Credentials / Direct Grant;
  • implicit browser flow.

Human passwords, password reset and configured identity-provider authentication factors remain Keycloak concerns.

Global User identity

The global authenticated principal is a Touriffique User.

An external identity is mapped by:

issuer + subject

Conceptually:

ExternalIdentity
├── issuer
├── subject
└── user_id

(issuer, subject) must be unique.

Email is contact/profile data and may be verification evidence, but it is not the primary external identity key.

User, Tenant Membership and Customer

Global User
├── TenantMembership(s)
├── PlatformStaffAssignment(s)
└── CustomerAccountLink(s)
       ├── Tenant A -> Customer 123
       └── Tenant B -> Customer 991

A CRM Customer remains tenant-owned. A User can link to a distinct Customer in more than one Tenant.

Guest Customers/Leads remain valid without an authenticated User.

Email equality alone never authorizes automatic User/Customer linking or Customer merging.

Tenant membership

A TenantMembership connects a User to a Tenant.

Membership has its own lifecycle, including states such as invited, active, suspended/revoked as refined during implementation.

Membership is Touriffique-owned, not inferred from Keycloak realm/groups.

Platform staff

Platform Administrator and Platform Support authority is represented by a separate Platform Staff assignment model.

Platform authority cannot be granted through a TenantMembership.

Permission model

Authorization uses stable machine-readable permissions.

Representative examples:

organization.member.read
organization.member.manage

capability.offering.read
capability.offering.manage

commerce.booking.read
commerce.booking.manage

finance.payment.read
finance.payment.refund

site.page.read
site.page.publish

marketing.campaign.manage

Roles are named bundles of permissions.

Application authorization checks permissions/policies rather than hard-coded role-name equality whenever the decision is capability-based.

Scoped assignments

Role/permission assignments can be scoped to:

TENANT
BUSINESS_UNIT
SITE
LOCATION

A User may hold multiple assignments.

The initial authorization model is allow-only, default-deny.

No explicit DENY grant language is introduced initially.

An applicable authorization decision evaluates:

authenticated User
+ active User state
+ active Tenant state
+ active TenantMembership / PlatformStaffAssignment
+ required permission
+ applicable resource scope
+ entitlement/capability availability
+ domain-specific policy
= ALLOW

Failure of any required condition denies the operation.

Permissions vs entitlements

Permission and entitlement are different dimensions.

Example:

User has:       marketing.campaign.manage
Tenant lacks:   advertising campaign entitlement
Result:         operation unavailable

Authorization cannot create a commercial capability that the Tenant does not own.

MFA

MFA is mandatory for every:

  • Platform Administrator;
  • Platform Support user;
  • Tenant Owner;
  • Tenant Administrator;
  • Business Manager;
  • Content Editor;
  • Translator/Locale Editor;
  • Marketing Manager;
  • Finance Manager;
  • Operations Staff;
  • any future tenant staff persona.

Customer MFA is optional initially.

Preferred factors:

  1. WebAuthn/passkey;
  2. TOTP fallback;
  3. recovery codes.

Account recovery must remain compatible with the mandatory staff-MFA policy.

Sensitive operations may require step-up authentication/stronger assurance. Candidate operations include:

  • payment-account changes;
  • ownership transfer;
  • credential/API-client management;
  • MFA/security-setting changes;
  • platform support impersonation;
  • high-risk financial actions.

Exact step-up rules are an implementation/security-policy refinement.

Browser credential protection

Durable refresh/session credentials must not be persisted in JavaScript-readable browser storage:

  • localStorage;
  • sessionStorage;
  • IndexedDB.

Tenant Admin and Platform Admin must use an architecture that protects durable credentials from ordinary frontend JavaScript.

The exact BFF/server-session mechanism is intentionally deferred to I1-B6 because it depends on the frontend runtime decision.

Social and enterprise identity

Keycloak is the identity-broker/federation boundary.

The architecture supports future login/federation with providers such as:

  • Google;
  • Apple;
  • Meta/Facebook where commercially required;
  • enterprise OIDC;
  • enterprise SAML.

The exact launch provider list is not frozen in I1-B4.

Machine-to-machine authentication

Trusted machine clients use OAuth 2.0 Client Credentials.

Touriffique retains application-side client metadata such as:

ApiClient
├── tenant_id?
├── site_id?
├── identity-provider client/subject reference
├── scopes
├── environment
└── status

Machine scope remains application-owned.

Provider webhooks are different: they use provider-specific signature/verification protocols.

Token responsibility

OIDC access tokens prove identity/session/authentication facts according to validated claims.

Touriffique does not encode its entire mutable tenant authorization model into long-lived identity-provider token claims.

Current memberships, scoped permission grants and entitlements are resolved by Touriffique so revocations/role changes do not depend solely on waiting for stale authorization claims to expire.

Invitations

Staff onboarding is invitation-based.

authorized inviter
      ↓
one-time short-lived invitation
      ↓
user authenticates/registers
      ↓
invitation identity verified
      ↓
TenantMembership activated

Application-owned invitation secrets are stored hashed.

Invitation creation, acceptance, expiry and cancellation are auditable.

An invitation addressed to an email does not become an identity assignment until the acceptance identity is verified.

Guest flows

Anonymous users may submit enquiries, requests/quotes and eligible guest bookings/checkouts.

Authentication is not a mandatory prerequisite for every conversion flow.

A guest Customer can later be linked to a User through an explicit verified process.

Support impersonation

Support/delegated access is an application-level temporary security context.

Conceptually:

real_actor_user_id
effective_user_or_tenant_context
reason / support reference
created_at
expires_at

Every affected audit event records both real actor and effective context.

Support access does not obtain or reuse the target user's Keycloak password, refresh token or browser session.

Sensitive operations may be blocked or require elevated approval during impersonation.

Domain/client redirects

Managed and Custom sites may authenticate users only through registered/verified redirect origins.

Custom-domain callbacks must be tied to verified Site/Domain state.

Arbitrary wildcard redirect URLs are not permitted as a tenant convenience feature.

Deferred decisions

I1-B4 intentionally does not freeze:

  • exact Keycloak hosting/deployment topology;
  • frontend BFF/session library;
  • access/refresh token TTLs;
  • exact passkey/TOTP enrollment UX;
  • exact launch social login providers;
  • enterprise SSO commercial packaging;
  • fine-grained permission catalogue contents;
  • step-up rules per endpoint;
  • cache strategy for authorization resolution.

Those belong to later implementation/security/frontend gates.