Documentation
¶
Overview ¶
Package access supplies resource-neutral ACL contracts and evaluation for Studio and embedding applications. Authentication providers own fact issuance.
Index ¶
- Constants
- Variables
- func HasPermission(grants []EntityPermission, entityType string, id EntityID, permission string) bool
- func ParseGrantedScopes(claim string) ([]string, error)
- func PoliciesContentHash(policies map[string]Policy) (string, error)
- func PolicyContentHash(action string, policy Policy) (string, error)
- func ResolveNamedDocument(ctx context.Context, source Store, document Document) (Document, []NamedDependency, error)
- func RuleContentHash(rule Rule) (string, error)
- func ValidateDocument(doc Document) error
- func ValidateEntityPermissions(grants []EntityPermission) error
- func ValidatePolicy(action string, p Policy) error
- type Administration
- func (a *Administration) CanReplace(ctx context.Context, resource Resource) (bool, error)
- func (a *Administration) Create(ctx context.Context, doc Document) (Document, error)
- func (a *Administration) Get(ctx context.Context, resource Resource) (Document, error)
- func (a *Administration) Replace(ctx context.Context, doc Document) (Document, error)
- type Choice
- type Choices
- type Creator
- type Decision
- type DecisionProvider
- type Directory
- type Document
- type EditorContext
- type Entity
- type EntityGroups
- type EntityID
- type EntityPermission
- type EntityPermissionIndex
- type Facts
- type NamedAdministration
- func (s *NamedAdministration) Archive(ctx context.Context, ref NamedReference) (Document, error)
- func (s *NamedAdministration) Assign(ctx context.Context, asset Resource, expected int64, actions []string, ...) (Document, error)
- func (s *NamedAdministration) Create(ctx context.Context, id string, definition NamedDefinition) (NamedPolicy, error)
- func (s *NamedAdministration) Impact(ctx context.Context, resource Resource) ([]NamedImpact, error)
- func (s *NamedAdministration) List(ctx context.Context) ([]NamedPolicy, error)
- func (s *NamedAdministration) Update(ctx context.Context, ref NamedReference, definition NamedDefinition) (NamedPolicy, []NamedImpact, error)
- type NamedDefinition
- type NamedDependency
- type NamedImpact
- type NamedPolicy
- type NamedReference
- type Policy
- type PolicyChoiceBinding
- type PolicyInventory
- type PreparedFacts
- type Provider
- type Request
- type Resource
- type ResourceFamily
- type RevisionSelection
- type Rule
- type SelectedResource
- type SelectedScopeDecision
- type SelectedScopeProvider
- type SelectionDocument
- type SelectionRequest
- type SelectionStore
- type Selector
- type Service
- func (s *Service) Authorize(ctx context.Context, request Request) (Decision, error)
- func (s *Service) AuthorizeSelectionWithStatus(ctx context.Context, request Request, selected []Entity) (Decision, Facts, int64, error)
- func (s *Service) AuthorizeWithFacts(ctx context.Context, request Request) (Decision, Facts, error)
- func (s *Service) AuthorizeWithRevision(ctx context.Context, request Request) (Decision, Facts, int64, error)
- func (s *Service) AuthorizeWithStatus(ctx context.Context, request Request) (Decision, Facts, int64, error)
- func (s *Service) EditorContext(ctx context.Context, r Resource) (EditorContext, error)
- func (s *Service) EditorContextWithStatus(ctx context.Context, r Resource) (EditorContext, error)
- func (s *Service) Get(ctx context.Context, resource Resource) (Document, error)
- func (s *Service) GetWithStatus(ctx context.Context, resource Resource) (Document, error)
- func (s *Service) Replace(ctx context.Context, candidate Document) (Document, error)
- type StaticDirectory
- type StaticSelectionStore
- type StaticStore
- type Store
- type VersionOverride
Constants ¶
const NamedDefinitionAction = "$definition"
NamedReference follows a reusable policy's current head. Revision is the minimum reviewed revision, not a frozen copy; every resolved head is returned separately for the caller's freshness fence. Resource IDs survive renaming.
Variables ¶
var ErrConflict = errors.New("policy revision conflict")
var ErrDenied = errors.New("access denied")
var ErrIdentityDenied = fmt.Errorf("%w: verified identity rejected", ErrDenied)
var ErrSelectionDenied = fmt.Errorf("%w: selected entity scope rejected", ErrDenied)
var ErrSelectionRequired = fmt.Errorf("%w: explicit entity selection required", ErrDenied)
Functions ¶
func HasPermission ¶
func HasPermission(grants []EntityPermission, entityType string, id EntityID, permission string) bool
HasPermission checks exact entity identity and permission membership only. It never treats a permission such as "admin" as a universal bypass.
func ParseGrantedScopes ¶
ParseGrantedScopes parses the standard space-delimited OAuth scope claim. An absent claim grants no scopes; malformed claims fail closed.
func PoliciesContentHash ¶
PoliciesContentHash identifies an action-policy map independently of resource identity and revision. JSON map keys are sorted; rule/scope slice order is preserved. Nil and empty maps both represent the same deny-all policy content. Callers must not mutate the input concurrently, as with policy evaluation.
func PolicyContentHash ¶
PolicyContentHash identifies validated policy content for an action. Action identity, priority, scopes, entity type and the complete ordered rule tree are included. Resource identity and revision must remain separate cache fences.
func ResolveNamedDocument ¶
func ResolveNamedDocument(ctx context.Context, source Store, document Document) (Document, []NamedDependency, error)
ResolveNamedDocument compiles reusable references into ordinary policies. It retains local restrictions and scopes, rejects ambiguous entity scope intersections, and uses exact-action-before-wildcard semantics at every level. Hosts must fence all returned dependencies before releasing protected data. This function neither resolves identity nor caches authorization decisions.
func RuleContentHash ¶
RuleContentHash identifies one validated, ordered rule tree. It contains no resource, policy revision or principal facts and grants no authority. The authored all/any order is retained; this is not logical-equivalence reduction.
func ValidateDocument ¶
ValidateDocument enforces resource-level reserved metadata boundaries.
func ValidateEntityPermissions ¶
func ValidateEntityPermissions(grants []EntityPermission) error
ValidateEntityPermissions validates trusted-provider data before it is used.
func ValidatePolicy ¶
Types ¶
type Administration ¶
type Administration struct {
Store Store
Provider Provider
EditorRoles []string
// EditorCheck is an optional trusted host binding for initial policy creation
// and role-based replacement. It replaces EditorRoles, runs only after the
// provider's identity, lease and tenant have been verified, and must not trust
// request-supplied identity or groups. Management still governs replacement
// when configured.
EditorCheck func(context.Context, Facts, Resource) (bool, error)
// Management selects a checked manageAccess policy for replacement.
// When nil, the configured EditorRoles are the replacement authority.
// Creation still requires EditorRoles because no resource policy exists yet.
Management *Service
}
Administration supplies deployment-owned policy administration permissions. Every authenticated principal may read policies in its tenant; only the configured roles or a trusted EditorCheck may create/replace them. With no EditorCheck, an empty EditorRoles denies writes. Protected resource execution remains a separate Service.Authorize decision.
func (*Administration) CanReplace ¶
CanReplace reports the same server rule used by Replace. Callers may show this in an editor context, but Replace independently repeats the check.
type Creator ¶
Creator adds an initial immutable policy revision; implementations must reject an existing resource atomically. Actor is supplied by the trusted provider.
type Decision ¶
func Evaluate ¶
func Evaluate(req Request, policies map[string]Policy, facts Facts, now time.Time) (Decision, error)
Evaluate checks one explicitly configured action. Callers resolve policies from trusted storage and compose dependency decisions separately.
func EvaluatePrepared ¶
func EvaluatePrepared(req Request, policies map[string]Policy, prepared *PreparedFacts, now time.Time) (Decision, error)
EvaluatePrepared uses the same immutable fact sets for every rule and policy. It preserves Evaluate's semantics without rebuilding role/exposure maps.
type DecisionProvider ¶
type DecisionProvider interface {
Evaluate(context.Context, Request, Document, Facts) (Decision, error)
}
DecisionProvider adds a trusted remote policy decision to local ACL rules. It can narrow or deny access; it cannot broaden a local decision.
type Directory ¶
Directory optionally supplies a tenant-scoped administrative catalog from the trusted identity provider. Implementations must authorize their own reads.
type EditorContext ¶
type Entity ¶
func NormalizeEntityGroups ¶
func NormalizeEntityGroups(groups EntityGroups) ([]Entity, error)
NormalizeEntityGroups returns the existing flat evaluator view. Malformed types, IDs, or duplicate IDs fail closed. Map keys are sorted for stable decision and editor output; the ID order within each type is preserved.
type EntityGroups ¶
EntityGroups is the canonical allowedEntities fact: entity type -> IDs. A missing type or an empty ID list grants no entity access.
func DecodeEntityGroups ¶
func DecodeEntityGroups(raw []byte) (EntityGroups, error)
DecodeEntityGroups parses the canonical JSON object without float64, rejecting duplicate keys, null ID lists and malformed or duplicate IDs.
func GroupEntities ¶
func GroupEntities(flat []Entity) (EntityGroups, error)
GroupEntities is the explicit compatibility conversion for legacy flat facts. Duplicate type/ID pairs are rejected rather than merged silently.
type EntityID ¶
type EntityID string
EntityID is an opaque authorized ID. JSON strings remain strings. Positive JSON integers through MaxUint64 become exact decimal strings; floats, exponents, negatives, zero and larger integers are rejected.
func (*EntityID) UnmarshalJSON ¶
type EntityPermission ¶
type EntityPermission struct {
Type string `json:"type"`
ID EntityID `json:"id"`
Permissions []string `json:"permissions"`
}
EntityPermission attaches opaque application-defined permissions directly to one entity. It implies neither ancestry nor a global role. Providers supply a list of verified grants; applications define what each permission permits.
type EntityPermissionIndex ¶
EntityPermissionIndex gives SQL criteria direct slices by type and permission. It is a runtime view; canonical provider/storage grants remain a record list.
func IndexEntityPermissions ¶
func IndexEntityPermissions(grants []EntityPermission, decision Decision) (EntityPermissionIndex, error)
IndexEntityPermissions intersects grants with the mandatory entity decision. Returned slices are detached from provider data and include no removed IDs.
type Facts ¶
type Facts struct {
// AuthorityRevision is an optional opaque fingerprint of verified identity
// and account context. It grants no permissions and excludes rolling leases.
AuthorityRevision string `json:"authorityRevision,omitempty"`
EntityPermissions []EntityPermission `json:"entityPermissions,omitempty"`
Subject string `json:"subject"`
Tenant string `json:"tenant"`
Issuer string `json:"issuer"`
Roles []string `json:"roles"`
// MembershipGroups are verified membership groups, distinct from application roles.
MembershipGroups []string `json:"membershipGroups,omitempty"`
Exposures []string `json:"exposures"`
// GrantedScopes are OAuth scopes from a verified credential, not entity bounds.
GrantedScopes []string `json:"grantedScopes,omitempty"`
// EntityGroups is the canonical typed authorization fact.
EntityGroups EntityGroups `json:"allowedEntities,omitempty"`
// Entities is a compatibility view for existing flat fact providers.
Entities []Entity `json:"-"`
ValidUntil time.Time `json:"validUntil"`
}
Facts must originate from a verified OAuth/OIDC identity and its configured authorization provider. Exposures are feature entitlements, not publications.
func (Facts) FlatEntities ¶
FlatEntities uses the canonical map when present. When both public and legacy views are populated, they must describe the same authority exactly.
func (Facts) IDsForType ¶
IDsForType exposes a typed auth-context field usable by native bindings. It returns no IDs for absent or empty types and never trusts a conflicting flat compatibility view.
func (Facts) MarshalJSON ¶
MarshalJSON always publishes the grouped contract, including when an older provider supplied only the flat compatibility view.
type NamedAdministration ¶
type NamedAdministration struct {
Policies *Administration
Inventory PolicyInventory
}
NamedAdministration reuses checked policy administration and existing CAS documents. Inventory is deployment-owned and must not omit assigned assets.
func (*NamedAdministration) Archive ¶
func (s *NamedAdministration) Archive(ctx context.Context, ref NamedReference) (Document, error)
Archive retains immutable history. Assigned policies cannot be archived. Atomic cross-process assignment/archive coordination belongs to the host's transaction boundary; a host without it must leave this operation disabled.
func (*NamedAdministration) Assign ¶
func (s *NamedAdministration) Assign(ctx context.Context, asset Resource, expected int64, actions []string, ref NamedReference) (Document, error)
func (*NamedAdministration) Create ¶
func (s *NamedAdministration) Create(ctx context.Context, id string, definition NamedDefinition) (NamedPolicy, error)
func (*NamedAdministration) Impact ¶
func (s *NamedAdministration) Impact(ctx context.Context, resource Resource) ([]NamedImpact, error)
func (*NamedAdministration) List ¶
func (s *NamedAdministration) List(ctx context.Context) ([]NamedPolicy, error)
func (*NamedAdministration) Update ¶
func (s *NamedAdministration) Update(ctx context.Context, ref NamedReference, definition NamedDefinition) (NamedPolicy, []NamedImpact, error)
type NamedDefinition ¶
type NamedDefinition struct {
DisplayName string `json:"displayName"`
Policies map[string]Policy `json:"policies"`
Archived bool `json:"archived,omitempty"`
}
NamedDefinition is the editable payload of a policy resource. Its policies never confer access to editing the policy resource itself.
func Definition ¶
func Definition(document Document) (NamedDefinition, error)
func (NamedDefinition) Validate ¶
func (d NamedDefinition) Validate() error
type NamedDependency ¶
type NamedDependency struct {
Resource Resource `json:"resource"`
Revision int64 `json:"revision"`
}
NamedDependency is an exact input revision, not an authorization decision.
type NamedImpact ¶
type NamedPolicy ¶
type NamedReference ¶
func (NamedReference) Valid ¶
func (r NamedReference) Valid() bool
type Policy ¶
type Policy struct {
// Definition is non-executable metadata, valid only at the reserved action
// of a reusable policy resource. It is stored in existing versioned JSON.
Definition *NamedDefinition `json:"definition,omitempty"`
// Named is valid only with mode named and narrows the optional local rule
// using the current head of a reusable policy.
// Unresolved references are never executable by Evaluate.
Named *NamedReference `json:"named,omitempty"`
// Priority orders revision-selection policies. Larger values are evaluated
// first; equal priorities are valid and the first evaluated match wins.
Priority int `json:"priority,omitempty"`
Mode string `json:"mode"` // public or protected
Rule *Rule `json:"rule,omitempty"`
// RequiredScopes are mandatory for a protected action, outside Rule's OR branches.
RequiredScopes []string `json:"requiredScopes,omitempty"`
// EntityType requires scoped authorization outside the rule's OR branches.
EntityType string `json:"entityType,omitempty"`
}
type PolicyChoiceBinding ¶
type PolicyChoiceBinding struct {
Resource Resource `json:"resource"`
Choices Choices `json:"choices"`
}
PolicyChoiceBinding is a server-owned editor directory for one exact policy resource. Its options are display choices, never identity facts or grants.
type PolicyInventory ¶
PolicyInventory is a trusted tenant-scoped inventory of existing policy resources, including working and published asset revisions.
type PreparedFacts ¶
type PreparedFacts struct {
// contains filtered or unexported fields
}
PreparedFacts is an immutable, request-owned snapshot of verified facts. It grants no authority: callers still supply verified identity and leases. Reuse one snapshot across an evaluation's rules, gates and candidate policies. Its maps are private and never retained in a global cache.
func PrepareFacts ¶
func PrepareFacts(facts Facts) *PreparedFacts
PrepareFacts copies the verified facts and builds each membership set once. Invalid entity/scope facts remain invalid for protected evaluation; public consumption retains Evaluate's existing behavior with those unused facts.
func (*PreparedFacts) Facts ¶
func (p *PreparedFacts) Facts() Facts
Facts returns a defensive copy; mutations cannot change this snapshot.
func (*PreparedFacts) HasExposureLiteral ¶
func (p *PreparedFacts) HasExposureLiteral(value string) bool
HasExposureLiteral checks an exact exposure, including a literal "*".
func (*PreparedFacts) HasGroup ¶
func (p *PreparedFacts) HasGroup(value string) bool
HasGroup checks exact verified membership, independently of roles/exposures.
func (*PreparedFacts) HasRoleLiteral ¶
func (p *PreparedFacts) HasRoleLiteral(value string) bool
HasRoleLiteral checks an exact role; "*" is literal in gate requirements.
type Provider ¶
Provider resolves facts using server-verified credentials in ctx. It must not trust a subject, role list or entity list supplied in an operation's payload.
type ResourceFamily ¶
type ResourceFamily struct {
Kind string `json:"kind"`
ID string `json:"id"`
Tenant string `json:"tenant"`
}
ResourceFamily identifies a logical resource before selecting its version. Publication endpoints and concrete runtime instances remain host-owned.
type RevisionSelection ¶
type RevisionSelection struct {
PolicyRevision int64 `json:"policyRevision,omitempty"`
Version string `json:"version"`
Policy Policy `json:"policy"`
}
RevisionSelection attaches exactly one selection policy to a content version. Priority belongs to Policy; Version is content identity and carries no order.
type SelectedResource ¶
type SelectedScopeDecision ¶
type SelectedScopeProvider ¶
type SelectedScopeProvider interface {
ResolveSelectedScope(context.Context, Request, Document, Facts) (SelectedScopeDecision, error)
}
SelectedScopeProvider is a host-configured authority for explicit selections. It never supplies general Facts or makes a whole-resource grant. Local ACL predicates are checked against the original verified facts before it is called. Configuring this provider explicitly replaces static entity-list bounds for selected requests; ordinary requests keep their existing scope behavior.
type SelectionDocument ¶
type SelectionDocument struct {
Action string `json:"action,omitempty"`
Resource ResourceFamily `json:"resource"`
Revision int64 `json:"revision"`
DefaultVersion string `json:"defaultVersion"`
Revisions []RevisionSelection `json:"revisions,omitempty"`
Overrides []VersionOverride `json:"overrides,omitempty"`
}
type SelectionRequest ¶
type SelectionRequest struct {
Resource ResourceFamily
Action string
Selection *[]Entity
}
type SelectionStore ¶
type SelectionStore interface {
GetSelection(context.Context, ResourceFamily) (SelectionDocument, error)
}
SelectionStore returns a current, host-owned mapping. Its revision describes the mapping, independently of the selected resource's policy revision.
type Selector ¶
type Selector struct {
Mappings SelectionStore
Service *Service
}
Selector chooses a version and authorizes that exact resource. A mapping never grants resource access. No fallback occurs after denial or an outage. Hosts use this same resolver for discovery and execution, and must enforce returned entity bounds. MCP routing and session pinning are host concerns.
func (*Selector) Authorize ¶
func (s *Selector) Authorize(ctx context.Context, request SelectionRequest) (SelectedResource, error)
func (*Selector) FindPolicy ¶
func (s *Selector) FindPolicy(ctx context.Context, resource ResourceFamily) (SelectedResource, Document, error)
FindPolicy returns the selected version's current policy document only after an unbounded viewAccess decision against that same document and identity. Execution permission does not imply policy inspection permission.
type Service ¶
type Service struct {
Store Store
Provider Provider
Directory Directory
Decisions DecisionProvider
SelectedScopes SelectedScopeProvider
}
Service separates policy inspection from policy administration. The provider supplies verified identity/facts; neither operation accepts them from a client.
func (*Service) Authorize ¶
Authorize evaluates current policy for execution. Callers must apply any returned entity scope before releasing data.
func (*Service) AuthorizeSelectionWithStatus ¶
func (s *Service) AuthorizeSelectionWithStatus(ctx context.Context, request Request, selected []Entity) (Decision, Facts, int64, error)
AuthorizeSelectionWithStatus applies a caller's explicit selection only when the exact loaded policy is entity-bounded. Unbounded ACLs keep their normal behavior; gates independently enforce their named entity permissions.
func (*Service) AuthorizeWithFacts ¶
AuthorizeWithFacts returns the verified facts used for this exact decision. A downstream component can bind the narrowed decision together with its principal roles/exposures without resolving a second, potentially different identity snapshot. Facts are never accepted from the request payload.
func (*Service) AuthorizeWithRevision ¶
func (s *Service) AuthorizeWithRevision(ctx context.Context, request Request) (Decision, Facts, int64, error)
AuthorizeWithRevision returns the exact immutable policy revision used for this decision so gate leases and UI snapshots can bind to policy changes.
func (*Service) AuthorizeWithStatus ¶
func (s *Service) AuthorizeWithStatus(ctx context.Context, request Request) (Decision, Facts, int64, error)
AuthorizeWithStatus retains denial versus infrastructure failure for hosts that must distinguish a missing/denied policy from an unavailable authority. The legacy Authorize methods keep their existing denial-shaped behavior.
func (*Service) EditorContext ¶
func (*Service) EditorContextWithStatus ¶
EditorContextWithStatus keeps identity and authority failures distinct from an explicit management denial. It rejects policy-revision or fact drift between the checked viewAccess and manageAccess decisions.
func (*Service) GetWithStatus ¶
GetWithStatus checks unbounded viewAccess against the exact document it returns, while preserving an authority outage separately from a denial.
type StaticDirectory ¶
type StaticDirectory struct {
// contains filtered or unexported fields
}
StaticDirectory rechecks viewAccess before returning configured choices. It is useful where the agreed IdP has no organization directory endpoint.
func NewStaticDirectory ¶
func NewStaticDirectory(bindings []PolicyChoiceBinding, access *Service) (*StaticDirectory, error)
type StaticSelectionStore ¶
type StaticSelectionStore struct {
// contains filtered or unexported fields
}
func NewStaticSelectionStore ¶
func NewStaticSelectionStore(documents []SelectionDocument) (*StaticSelectionStore, error)
func (*StaticSelectionStore) GetSelection ¶
func (s *StaticSelectionStore) GetSelection(ctx context.Context, resource ResourceFamily) (SelectionDocument, error)
type StaticStore ¶
type StaticStore struct {
// contains filtered or unexported fields
}
StaticStore serves immutable, server-owned ACL documents for configured resources such as existing file-backed windows. Configuration reloads build a new store; policy administration uses a writable CAS store instead.
func NewStaticStore ¶
func NewStaticStore(documents []Document) (*StaticStore, error)
type Store ¶
type Store interface {
Get(context.Context, Resource) (Document, error)
Replace(context.Context, Document, int64, string) (Document, error)
}
Store persists immutable policy revisions. Replace must compare the current revision atomically, preventing authorization against a stale policy snapshot. Initial policy provisioning is a separate server-owned bootstrap operation.
type VersionOverride ¶
type VersionOverride struct {
Version string `json:"version"`
RequiredExposures []string `json:"requiredExposures"`
Priority int `json:"priority"`
}
VersionOverride matches when all exposures are present. Larger Priority wins. Equal priorities are allowed; the first matching override wins.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
component
module
|
|
|
datly
module
|
|
|
Package gating composes account and entity requirements with authz ACLs.
|
Package gating composes account and entity requirements with authz ACLs. |
|
Package oauth resolves ACL facts from a dedicated, trusted OAuth/OIDC issuer.
|
Package oauth resolves ACL facts from a dedicated, trusted OAuth/OIDC issuer. |