Files
rbac/CHANGELOG.md
Rene Nochebuena 0864f031a1 feat(rbac): initial stable release v0.9.0
Foundational identity and permission types for role-based access control — bit-set PermissionMask, immutable Identity value type, and PermissionProvider interface.

What's included:
- `Identity` value type with NewIdentity / WithTenant constructors and SetInContext / FromContext context helpers
- `Permission` (int64 bit position) and `PermissionMask` (int64 bit-set) with O(1) Has and non-mutating Grant
- `PermissionProvider` interface for DB-backed ResolveMask(ctx, uid, resource) resolution

Tested-via: todo-api POC integration
Reviewed-against: docs/adr/
2026-03-18 13:25:43 -06:00

29 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to this module will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.9.0] - 2026-03-18
### Added
- `Permission``int64` type representing a named bit position (062) for a single capability; applications define their own constants using this type
- `PermissionMask``int64` type representing a resolved bit-set of capabilities for a user on a resource
- `PermissionMask.Has(p Permission) bool` — O(1) check whether a permission bit is set; returns false for out-of-range values (p < 0 or p >= 63)
- `PermissionMask.Grant(p Permission) PermissionMask` — returns a new mask with the given bit set without mutating the receiver; silently ignores out-of-range values
- `Identity` — value type (not a pointer) carrying `UID`, `TenantID`, `DisplayName`, and `Email` for an authenticated principal
- `NewIdentity(uid, displayName, email string) Identity` — constructs an Identity from token authentication data; `TenantID` is intentionally left empty for later enrichment
- `Identity.WithTenant(id string) Identity` — returns a copy of the Identity with `TenantID` set; does not mutate the receiver, safe for concurrent middleware use
- `SetInContext(ctx context.Context, id Identity) context.Context` — stores an Identity in a context using a private unexported key type to prevent collisions
- `FromContext(ctx context.Context) (Identity, bool)` — retrieves the Identity stored by `SetInContext`; returns the zero-value Identity and false if no identity is present
- `PermissionProvider` interface — `ResolveMask(ctx context.Context, uid, resource string) (PermissionMask, error)` for DB-backed or in-memory permission resolution
### Design Notes
- `Identity` is a value type throughout — every enrichment call (e.g. `WithTenant`) returns a new copy, eliminating nil-pointer bugs and preventing accidental mutation of a shared context value across concurrent middleware.
- Permissions are bit positions (062) packed into an `int64` mask; applications define their own named `Permission` constants — none are prescribed by this package — keeping the bit-set model flat and free of role-hierarchy complexity.
- This package owns the context key for `Identity` via an unexported `authContextKey{}` struct, so any module that needs to carry an authenticated identity imports only `rbac`; zero micro-lib dependencies (stdlib only).
[0.9.0]: https://code.nochebuena.dev/go/rbac/releases/tag/v0.9.0