Skip to content

ADR-0003. Temporarily skip authorization on License read routes

FieldValue
StatusAccepted
Date2026-04-15
Deciderslicensing-team, identity-team
Supersedes

Context

  • LicenseController is built from ControllerFactory.defineCrudController with per-route authorize permissions (License.find, License.findById, License.count, License.findOne).
  • Casbin authorization is per-merchant (domain = x-merchant-id). But a license is queried by entity (a User or Merchant) before a merchant is selected — e.g. during onboarding, the user has no active merchant domain yet.
  • With per-merchant authz enabled, these reads would 403 for legitimate pre-merchant flows (free-trial onboarding, license discovery by entity).
  • Write routes (create, updateById, deleteById, deleteBy) and the lifecycle actions are not affected — they keep their permission gates.

Decision

We will set authorize: { skip: true } on the four License read routes (find, findById, count, findOne), leaving them authenticate-only (JWT or Basic). The original authorize lines are kept commented in place so they can be restored when the per-merchant scoping design ("option B") lands.

This is explicitly temporary and marked TEMP(authz-skip) in the source.

Consequences

ProsCons
Pre-merchant onboarding flows work without 403License reads are authenticated but not authorized — any logged-in caller can read license rows
No IGNIS / ControllerFactory changes neededCarries a security-debt marker that must be paid down
Reversible — commented permissions document the target stateEasy to forget; relies on the TEMP comment + this ADR for tracking

Alternatives Considered

OptionProsConsWhy rejected
Keep authz on readsFully gatedBreaks pre-merchant onboarding (no domain to scope against)Blocks a core flow
Add a dedicated unauthenticated "discover by entity" routeNarrow surfaceNew route + schema; duplicates CRUDMore code for a temporary state
Implement per-entity (non-merchant) authz nowCorrect long-termLarger design ("option B"); not readyDeferred, not abandoned

References

  • licensing/src/controllers/license/license.controller.tsroutes.{find,findById,count,findOne}.authorize.skip + TEMP(authz-skip) comment
  • See user memory: per-merchant authorization re-enablement (Casbin domains, x-merchant-id)

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.