-
Release v1.0.0 Stable
released this
2026-05-07 22:51:01 -06:00 | 1 commits to main since this releasev1.0.0
code.nochebuena.dev/go/rbacOverview
rbacv1.0.0 commits the foundational identity and permission API as stable.
TheIdentityvalue type,PermissionMaskbit-set, context helpers, and
PermissionProviderinterface are unchanged from v0.9.0 and are now
production-validated acrosshttpauth,httpauth-firebase, andhttpauth-jwt.What Changed Since v0.9.0
New:
MaxPermissionconstantconst MaxPermission Permission = 62Makes the valid bit range explicit. Applications can use it in validation and
the constant is now referenced in thePermissiontype godoc alongside the
boundary behavior ofHasandGrant.Documentation: audit logging policy
PermissionProvidergodoc now documents that audit logging of permission checks
is out of scope for this package. Log denials and grants inside PermissionProvider
implementations or in the middleware layer that calls them.Full API (stable)
Permission int64— bit position (0–MaxPermission). Applications define their
own constants.HasandGrantsilently ignore values outside the valid range.MaxPermission Permission = 62— highest valid bit position.PermissionMask int64— resolved bit-set for a user on a resource.Has(p Permission) bool— O(1) check; returns false for out-of-rangepGrant(p Permission) PermissionMask— returns a new mask with bit set; receiver unchanged
Identity— value type carryingUID,TenantID,DisplayName,Email.NewIdentity(uid, displayName, email string) Identity(Identity).WithTenant(id string) Identity— returns copy; receiver unchanged
SetInContext(ctx, Identity) context.ContextFromContext(ctx) (Identity, bool)PermissionProviderinterface —ResolveMask(ctx, uid, resource string) (PermissionMask, error)Migration from v0.9.0
No breaking changes. The only addition is the
MaxPermissionconstant.go get code.nochebuena.dev/go/rbac@v1.0.0Downloads
-
Release 0.9.0 Stable
released this
2026-03-18 13:27:28 -06:00 | 2 commits to main since this releasev0.9.0
code.nochebuena.dev/go/rbacOverview
rbacprovides the foundational identity and permission types for role-based access control in a Go service. It defines theIdentityvalue type (the authenticated principal), thePermissionMaskbit-set type (a resolved set of capabilities for a user on a resource), and thePermissionProviderinterface (the contract for DB-backed permission resolution). Every other module that needs to carry or inspect an authenticated identity imports this package; it has no micro-lib dependencies of its own, only stdlib.What's Included
Permission—int64type representing a named bit position (0–62) for a single capabilityPermissionMask—int64type representing a resolved bit-set of permissionsPermissionMask.Has(p Permission) bool— O(1) check whether a permission bit is set; returns false for out-of-range valuesPermissionMask.Grant(p Permission) PermissionMask— returns a new mask with the given bit set; does not mutate the receiverIdentity— value type carryingUID,TenantID,DisplayName, andEmailfor an authenticated principalNewIdentity(uid, displayName, email string) Identity— constructs an Identity from token authentication data;TenantIDis left empty for later enrichmentIdentity.WithTenant(id string) Identity— returns a copy of the Identity withTenantIDset; does not mutate the receiverSetInContext(ctx, Identity) context.Context— stores an Identity in a context using a private keyFromContext(ctx) (Identity, bool)— retrieves the Identity stored bySetInContext; returns zero value and false if absentPermissionProviderinterface —ResolveMask(ctx, uid, resource string) (PermissionMask, error)for DB-backed permission resolution
Installation
require code.nochebuena.dev/go/rbac v0.9.0Design Highlights
- Permissions are bit positions packed into an
int64mask, giving O(1)Haschecks and compact storage; applications define their ownPermissionconstants — none are defined in this package (seedocs/adr/ADR-001-bitset-permissions.md). Identityis a value type (not a pointer) — it is copied on every enrichment call, preventing nil bugs and accidental mutation from concurrent middleware (seedocs/adr/ADR-002-identity-value-type.md).- The
rbacpackage owns the context key forIdentityvia an unexportedauthContextKey{}struct type, preventing collisions with keys from other packages (seedocs/adr/ADR-003-identity-context-ownership.md). TenantIDis an optional enrichment field;PermissionProviderimplementations retrieve the tenant fromFromContext(ctx)when needed, so multi-tenancy does not require threading an extra parameter through every call site.
Known Limitations & Edge Cases
- There is no audit logging of permission checks.
PermissionMask.Hasis a pure in-memory operation — denials and grants are not recorded anywhere by the framework. PermissionProvider.ResolveMaskresults are not cached by this package. Implementations that hit a database on every call must implement their own caching layer; a hot permission check path with no cache will produce one DB round-trip per check.- Permissions at bit positions 63 and above are silently ignored by
HasandGrant— no error or panic is produced. Applications must keep their constants in the range 0–62. - Role-to-permission mapping tables are out of scope. The bit-set model is deliberately flat; if role inheritance or hierarchical permissions are required, callers must implement that logic in their
PermissionProvider. FromContextreturns the zero-valueIdentityandfalsewhen no identity is present; callers must handle theok == falsecase, especially in unauthenticated paths.
v0.9.0 → v1.0.0 Roadmap
- Validate the
Identityvalue type andPermissionMaskbit-set model under production multi-tenant workloads, confirming that the context key collision policy holds across all imported packages. - Consider providing a reference caching wrapper for
PermissionProvider(e.g. TTL-based in-memory cache) to reduce DB pressure without requiring every application to implement its own. - Decide whether audit logging of permission checks (denials at minimum) belongs in this package, in a wrapper type, or in the application layer, and document the recommended pattern.
- Validate that 63 permission bits is sufficient for known use cases; document the upper bound explicitly in the package godoc.
- Achieve production validation of concurrent middleware enrichment via
WithTenantandSetInContext.
v0.9.0 rationale: The API is stable and intentional — designed through multiple architecture reviews and tested end-to-end via the todo-api POC (SQLite, RBAC, middleware stack, HTTP handlers). The module is not yet battle-tested in production for all edge cases, and the pre-1.0 designation preserves the option for minor API refinements based on real-world use.
Downloads