# ADR-001: Bit-Set Permissions **Status:** Accepted **Date:** 2026-03-18 ## Context Applications need to represent and check whether a user holds a specific capability on a resource. Common approaches include: role strings (e.g. `"admin"`, `"editor"`), permission string lists, or bit-set integers. Role strings require the application to know which capabilities each role implies, making capability checks indirect and requiring either a lookup table or a case statement everywhere. Permission string lists are flexible but expensive to check (linear scan) and verbose to store. ## Decision `Permission` is typed as `int64` and represents a named bit position (0–62). Applications define their own constants using this type: ```go const ( Read rbac.Permission = 0 Write rbac.Permission = 1 Delete rbac.Permission = 2 ) ``` `PermissionMask` is also typed as `int64` and holds the resolved OR-combination of granted permission bits. It is returned by `PermissionProvider.ResolveMask` and checked with `PermissionMask.Has(p Permission) bool`. The upper bound is 62 (not 63) to keep the value within the positive range of a signed 64-bit integer, avoiding sign-bit ambiguity. `Has` and `Grant` both return false/no-op for out-of-range values (`p < 0 || p >= 63`). `Grant(p Permission) PermissionMask` is provided for constructing masks in tests and in-memory provider implementations, returning a new mask with the bit set without mutating the receiver. ## Consequences - Permission checks are O(1) bitwise operations — no map lookup, no string comparison. - A single `int64` column stores up to 62 independent permission bits per user-resource pair in the database. - Applications must define their own named constants; this package does not enumerate domain permissions. This keeps `rbac` domain-agnostic. - The 62-bit limit is sufficient for all foreseeable use cases; if an application needs more than 62 orthogonal permissions on a single resource, a structural refactor (multiple resources or resource hierarchies) is the appropriate response. - `PermissionProvider` is the extension point for DB-backed resolution; the bit-set design does not constrain the storage schema.