// Package rbac provides permission provider implementations for the Einherjar // authorization system. All constructors return [security.PermissionProvider] // from contracts/security — no new types are defined here. // // # Permission providers // // Three strategies compose into a complete authorization pipeline: // // // Fast-path: reads pre-computed bitmasks from JWT claims in context. // // Pass authmw.GetClaims so rbac does not import authmw directly. // claims := rbac.NewClaimsPermissionProvider("perms", authmw.GetClaims) // // // DB + cache: wraps any provider with TTL caching. Cache key is // // automatically scoped by TenantID for multi-tenant deployments. // cached := rbac.NewCachedPermissionProvider(dbProvider, valkeyCache, 5*time.Minute) // // // Chain: tries claims first, falls through to DB on miss. // chain := rbac.NewChainPermissionProvider(claims, cached) // // # Cache key customization // // When additional bag attributes must be part of the cache key (e.g. hardware IDs): // // const KeyHardwareID = "hardware_id" // // cached := rbac.NewCachedPermissionProvider(dbProvider, cache, 5*time.Minute, // rbac.WithCacheKey(func(bag security.SecurityBag, uid, resource string) string { // hwID, _ := bag.Get(KeyHardwareID) // return fmt.Sprintf("rbac:%s:%s:%v:%s", bag.Identity().TenantID, uid, hwID, resource) // }), // ) // // # Cache interface // // [Cache] is satisfied by einherjar/cache-valkey via Go duck typing. // No import of auth/rbac is needed by the cache implementation. // // # Multi-tenant // // [NewCachedPermissionProvider] automatically includes TenantID in the cache key // when [security.Identity.TenantID] is non-empty in the request bag. // Populate TenantID via [authmw.WithTenantHeader] in EnrichmentMiddleware. package rbac