authz

package module
v0.0.0-...-af2e488 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 8, 2026 License: Apache-2.0 Imports: 13 Imported by: 19

README

Authz

Authz is a Go authorization library for resources, principals, roles, feature entitlements and entity permissions. Embed it in a service to evaluate policies and return decisions with mandatory entity bounds. Your application supplies trusted identity facts and enforces the result before returning protected data.

Why Authz

  • One authorization model for reports, tools, agents, UI resources and data APIs.
  • Explicit data boundaries: entity grants constrain access even when a role or another branch of a policy matches.
  • Host-owned trust: configure your identity provider, tenant mapping, policy store and administration roles for your application.
  • Small core: the root package uses only the Go standard library. OAuth and Datly integration are available when your host needs them.

Features

  • Public and protected action policies with subject, role, exposure, entity, all and any rules
  • Mandatory OAuth scope checks and typed entity bounds outside any branches
  • Exact per-entity permissions without implicit inheritance
  • Immutable policy revisions and atomic replacement with conflict detection
  • Verified JWT/JWKS with injected identity and entity authorities
  • Account-bound gates, entitlement checks and an optional durable file registry
  • Datly HTTP/MCP components, SQLite/MySQL persistence and a runnable host

Packages and modules

Import path Purpose Go module
github.com/viant/authz Core types, evaluation, scope intersection, policy services and administration Core
github.com/viant/authz/oauth Verified JWT/JWKS and generic host bindings Core
github.com/viant/authz/gating Mandatory gates, versioned decisions, administration and an optional single-process file registry Core
github.com/viant/authz/component Authz Components, persistence and host Separate nested module

oauth and gating are packages in the core module; component has its own go.mod. Datly and Studio are not dependencies of the core. Studio and agently-core consume the shared core types directly.

Installation

The core module requires Go 1.25.5 or newer; the optional component module requires Go 1.25.8 or newer. To build and test a source checkout:

git clone https://github.com/viant/authz.git
cd authz
go test ./...

Import github.com/viant/authz in your Go application. Consumer integration currently uses local module mappings while releases are prepared; see local development before integrating from an independent checkout.

Quick start

This runnable example shows a role policy constrained to the caller's allowed projects. Save it as main.go in a temporary directory and run go run with its absolute file path from the checkout. The facts are a fixture for this example; a service must obtain them from a trusted Provider after verifying credentials.

package main

import (
    "fmt"
    "time"

    "github.com/viant/authz"
)

func main() {
    resource := authz.Resource{
        Kind: "report", ID: "usage", Version: "1", Tenant: "team-a",
    }
    policies := map[string]authz.Policy{
        "execute": {
            Mode: "protected",
            Rule: &authz.Rule{Kind: "role", Value: "analyst"},
            EntityType: "project",
        },
    }
    facts := authz.Facts{
        Subject: "alice", Tenant: "team-a", Issuer: "https://idp.example.com",
        Roles: []string{"analyst"},
        EntityGroups: authz.EntityGroups{"project": {"101", "102"}},
        ValidUntil: time.Now().Add(time.Minute),
    }
    decision, err := authz.Evaluate(authz.Request{
        Resource: resource, Action: "execute",
    }, policies, facts, time.Now())
    if err != nil {
        panic(err) // Deny the operation on any authorization error.
    }

    // Example enforcement: release only rows within the returned bounds.
    allowed := make(map[authz.Entity]bool)
    for _, entity := range decision.Entities {
        allowed[entity] = true
    }
    for _, projectID := range []string{"101", "102", "999"} {
        if decision.Bounded && !allowed[authz.Entity{Type: "project", ID: projectID}] {
            continue
        }
        fmt.Println("allowed project:", projectID)
    }
}

Output:

allowed project: 101
allowed project: 102

For stored policies and request-scoped identity, use Service.Authorize with Store and Provider. NewStaticStore serves immutable policy documents; mutable administration needs a writable store. Push entity constraints into the data query when possible, and reject bounded decisions if your operation cannot enforce them.

Security boundary

Authz evaluates authorization; the host verifies credentials, selects the resource and tenant, resolves trusted facts, and enforces decisions. Never copy roles, entity grants or identity from an operation request into Facts. Treat any authorization error as a denied operation. Reading a policy or hiding a UI control does not authorize execution. A successful bounded decision grants only the returned entities.

The optional OAuth adapters verify host-configured issuers, audiences and keys. Private identity payloads, account-to-tenant mappings, permission vocabulary and business inheritance belong to host-owned providers. Public code has no Viant ID-token, user-info or selected-evaluation wire contract.

Authorization

A resource is identified by kind, ID, tenant and version. Service.Authorize checks one action against its stored policy using server-resolved Facts. Policies support subject, role, exposure, entity, all and any conditions. Protected policies may also declare requiredScopes, a list of OAuth scope names checked together with the rule and outside its any branches. Every required scope must be present in Facts.GrantedScopes; absent scopes deny. These credential grants are distinct from the entity bounds in Decision. Decision.Bounded means callers must enforce the returned entity IDs. An empty or incompatible intersection denies access. Client-supplied filters cannot widen server-owned entity grants. Reading a policy does not authorize its resource. Service.AuthorizeWithStatus retains the immutable revision and distinguishes explicit denial or a missing policy from provider/store outages for gate hosts; the original Authorize methods retain their existing compatibility behavior.

Facts.EntityGroups is the canonical allowedEntities map. Entity IDs preserve strings and full-width integers; they are never rounded through float64. Providers must verify the credential and supply subject, tenant, issuer and an expiry lease. The library does not trust roles or entity IDs from operation request bodies. The signed OAuth fact-token provider reads granted scopes from its verified space-delimited scope claim. A user-info binding must not promote displayed scopes to credential authority.

oauth.VerifyToken verifies generic JWT claims supplied by a host; it never interprets private identity fields. oauth.NewIdentity returns registered subject/issuer/expiry only and grants no tenant, role or entity authority. oauth.NewStaticAuthorization requires an injected IdentityAuthority and an explicit policy-tenant validator. Entity checks use an injected gating.EntityPermissionProvider; capability projections can retain source leases through NewLeasedCapabilityPermissionResolver. Numeric user/account claims and provider HTTP DTOs are intentionally outside this module. Unknown JWKS key IDs cannot force per-request fetches; rotation becomes visible at the configured refresh lease.

Permissions per entity

Facts.EntityPermissions is a list of EntityPermission records, with type, ID and a list of opaque permissions beside each ID. It is not a map or an entity hierarchy. HasPermission checks exact identity and permission membership; a permission named admin does not imply a global role, ancestor inheritance or cross-namespace access. Business logic defines the meaning of permission names. Signed OAuth facts can carry this list; clients cannot supply verified grants. An optional oauth.NewEntityRoleResolver projects only explicitly mapped permissions on the exact selected entity into UI resource-role labels. Global user roles and unrelated entity permissions are not copied into that list.

[{"type":"advertiser","id":"123","permissions":["read"]},
 {"type":"advertiser","id":"456","permissions":["read","edit"]}]

Policy administration

Administration.Get currently permits every authenticated caller within its tenant. Anonymous access is disabled. Policy reads are available to signed-in callers in the same tenant; execution permissions are evaluated separately.

Administration.Create and Replace require membership in the configured EditorRoles. No editor roles are enabled by default. The server owns this list; a policy document or client request cannot change it. Creation cannot overwrite an existing resource. Replacements compare an expected revision atomically in storage. A policy's execute/discover rules remain independent of administration.

administration := &authz.Administration{
    Store: store,
    Provider: verifiedProvider,
    EditorRoles: []string{"policy_admin"}, // deployment-defined example
}

Authz Components

The components are the SDK endpoints. HTTP and MCP use the same input/output contracts, handlers, trusted capabilities and policy rules. Other Datly projects can import the components into their bootstrap/runtime; exposure and providers remain the host's configuration. See Authz Components.

Agently

agently-core's service/policy.AuthzResolver consumes the shared core types and a host-configured resource mapping. It never treats request context metadata as identity facts. Its whole-resource consumer rejects bounded decisions because it cannot enforce a row/entity scope. This adapter does not change existing policy configuration or automatically enable authorization on an agent.

Verification and local development

go test ./...
go test -race ./...
cd component
go test ./...
go build -o bin/authz ./cmd/authz

The extracted reader/writer components have SQLite persistence/transaction tests and an authorized local MySQL integration test. Native HTTP/MCP tests cover reads, configured-role creation/modification, forged role input, bounded decisions and revision conflicts. MySQL integration uses AUTHZ_MYSQL_TEST_DSN and creates a unique disposable database; do not point it at a production server.

Consumer repositories currently use explicit local module mappings for source development. Publish/version both Go modules and replace those mappings with release pins before deployment from an independent checkout. Root go test ./... does not traverse the nested component module, so run its checks separately.

License

Apache License 2.0 — see LICENSE and NOTICE.

This product includes software developed at Viant (http://viantinc.com/).

Resource version selection

Selector resolves one resource version from a trusted SelectionStore and then authorizes that exact version through the existing policy service. It is generic: an MCP server, component, skill or other resource can be selected. The host owns endpoint routing, publication, runtime loading and session pinning. Mapping revisions, resource versions and policy revisions remain separate.

family := authz.ResourceFamily{Kind: "mcp", ID: "studio", Tenant: "team"}
mappings, err := authz.NewStaticSelectionStore([]authz.SelectionDocument{{
    Resource: family, Revision: 1, DefaultVersion: "v1",
    Overrides: []authz.VersionOverride{{
        Version: "v2", RequiredExposures: []string{"studio-preview"}, Priority: 10,
    }},
}})
if err != nil { return err }
selector := authz.Selector{Mappings: mappings, Service: policyService}
selected, err := selector.Authorize(ctx, authz.SelectionRequest{
    Resource: family, Action: "execute",
})
if err != nil { return err }
// Route only to selected.Resource.Version and enforce selected.Decision bounds.

Each mapping has exactly one default version. All listed exposures on an override must match verified provider facts; the highest matching priority wins. Override priorities are unique, so multiple matching features are deterministic. Without matching features the default is selected. An alternate's missing or denied policy never causes fallback to a less restrictive default. Missing mappings deny; provider/store outages fail closed. A mapping with overrides requires verified, unexpired identity even when the default is ultimately selected. A mapping with no overrides and a public * tenant policy supports anonymous access.

The selector resolves identity once per operation, preventing different identity snapshots for selection and policy evaluation. Authorize returns the selected resource, mapping revision, policy revision and entity decision. Hosts should use it consistently for discovery and execution; differing client schemas across versions may require a host-owned session pin or separate tool names.

selector.FindPolicy(ctx, family) finds the selected version's current policy and checks unbounded viewAccess against that same document and identity before returning it. It does not treat execution permission as policy-read permission. Static mappings are cloned and immutable; reload configuration by constructing a new store. Dynamic persistence can implement SelectionStore with atomic, versioned mapping snapshots; this package does not add an endpoint table or SQL migration for the host.

Documentation

Overview

Package access supplies resource-neutral ACL contracts and evaluation for Studio and embedding applications. Authentication providers own fact issuance.

Index

Constants

This section is empty.

Variables

View Source
var ErrConflict = errors.New("policy revision conflict")
View Source
var ErrDenied = errors.New("access denied")
View Source
var ErrIdentityDenied = fmt.Errorf("%w: verified identity rejected", ErrDenied)
View Source
var ErrSelectionDenied = fmt.Errorf("%w: selected entity scope rejected", ErrDenied)
View Source
var ErrSelectionRequired = fmt.Errorf("%w: explicit entity selection required", ErrDenied)
View Source
var ErrUnavailable = errors.New("authorization service unavailable")

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

func ParseGrantedScopes(claim string) ([]string, error)

ParseGrantedScopes parses the standard space-delimited OAuth scope claim. An absent claim grants no scopes; malformed claims fail closed.

func ValidateEntityPermissions

func ValidateEntityPermissions(grants []EntityPermission) error

ValidateEntityPermissions validates trusted-provider data before it is used.

func ValidatePolicy

func ValidatePolicy(action string, p Policy) error

Types

type Administration

type Administration struct {
	Store       Store
	Provider    Provider
	EditorRoles []string
	// 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 may create/replace them. An empty EditorRoles denies writes. Protected resource execution remains a separate Service.Authorize decision.

func (*Administration) CanReplace

func (a *Administration) CanReplace(ctx context.Context, resource Resource) (bool, error)

CanReplace reports the same server rule used by Replace. Callers may show this in an editor context, but Replace independently repeats the check.

func (*Administration) Create

func (a *Administration) Create(ctx context.Context, doc Document) (Document, error)

func (*Administration) Get

func (a *Administration) Get(ctx context.Context, resource Resource) (Document, error)

func (*Administration) Replace

func (a *Administration) Replace(ctx context.Context, doc Document) (Document, error)

type Choice

type Choice struct {
	ID     string  `json:"id,omitempty"`
	Label  string  `json:"label"`
	Entity *Entity `json:"entity,omitempty"`
}

type Choices

type Choices struct {
	Subjects    []Choice `json:"subject"`
	Roles       []Choice `json:"role"`
	Exposures   []Choice `json:"exposure"`
	Entities    []Choice `json:"entity"`
	EntityTypes []string `json:"entityTypes"`
}

type Creator

type Creator interface {
	Create(context.Context, Document, string) (Document, error)
}

Creator adds an initial immutable policy revision; implementations must reject an existing resource atomically. Actor is supplied by the trusted provider.

type Decision

type Decision struct {
	Entities []Entity
	Bounded  bool
}

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 Intersect

func Intersect(left, right Decision) (Decision, error)

Intersect combines mandatory scopes without ever widening either decision. A bounded empty result, malformed entity or incompatible dimension denies.

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

type Directory interface {
	Choices(context.Context, Resource, Facts) (Choices, error)
}

Directory optionally supplies a tenant-scoped administrative catalog from the trusted identity provider. Implementations must authorize their own reads.

type Document

type Document struct {
	Resource Resource          `json:"resource"`
	Revision int64             `json:"revision"`
	Policies map[string]Policy `json:"policies"`
}

type EditorContext

type EditorContext struct {
	Choices   Choices `json:"choices"`
	CanManage bool    `json:"canManage"`
	Source    string  `json:"source"`
}

type Entity

type Entity struct {
	Type string `json:"type"`
	ID   string `json:"id"`
}

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

type EntityGroups map[string][]EntityID

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

func (id *EntityID) UnmarshalJSON(raw []byte) error

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

type EntityPermissionIndex map[string]map[string][]string

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"`
	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

func (f Facts) FlatEntities() ([]Entity, error)

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

func (f Facts) IDsForType(entityType string) ([]EntityID, error)

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

func (f Facts) MarshalJSON() ([]byte, error)

MarshalJSON always publishes the grouped contract, including when an older provider supplied only the flat compatibility view.

type Policy

type Policy struct {
	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 Provider

type Provider interface {
	Resolve(context.Context) (Facts, error)
}

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 Request

type Request struct {
	Resource Resource
	Action   string
	// Nil selection expands to all allowed entities; empty explicitly denies.
	Selection *[]Entity
}

type Resource

type Resource struct {
	Kind    string `json:"kind"`
	ID      string `json:"id"`
	Version string `json:"version"`
	Tenant  string `json:"tenant"`
}

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 Rule

type Rule struct {
	Kind   string  `json:"kind"` // subject, role, exposure, entity, all, any
	Value  string  `json:"value,omitempty"`
	Entity *Entity `json:"entity,omitempty"`
	Rules  []Rule  `json:"rules,omitempty"`
}

type SelectedResource

type SelectedResource struct {
	Resource        Resource `json:"resource"`
	MappingRevision int64    `json:"mappingRevision"`
	PolicyRevision  int64    `json:"policyRevision"`
	Decision        Decision `json:"decision"`
}

type SelectedScopeDecision

type SelectedScopeDecision struct {
	Entities   []Entity
	ValidUntil time.Time
}

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 {
	Resource       ResourceFamily    `json:"resource"`
	Revision       int64             `json:"revision"`
	DefaultVersion string            `json:"defaultVersion"`
	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

func (s *Service) Authorize(ctx context.Context, request Request) (Decision, error)

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

func (s *Service) AuthorizeWithFacts(ctx context.Context, request Request) (Decision, Facts, error)

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 (s *Service) EditorContext(ctx context.Context, r Resource) (EditorContext, error)

func (*Service) EditorContextWithStatus

func (s *Service) EditorContextWithStatus(ctx context.Context, r Resource) (EditorContext, error)

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) Get

func (s *Service) Get(ctx context.Context, resource Resource) (Document, error)

func (*Service) GetWithStatus

func (s *Service) GetWithStatus(ctx context.Context, resource Resource) (Document, error)

GetWithStatus checks unbounded viewAccess against the exact document it returns, while preserving an authority outage separately from a denial.

func (*Service) Replace

func (s *Service) Replace(ctx context.Context, candidate Document) (Document, error)

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)

func (*StaticDirectory) Choices

func (d *StaticDirectory) Choices(ctx context.Context, resource Resource, expected Facts) (Choices, 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)

func (*StaticStore) Get

func (s *StaticStore) Get(ctx context.Context, resource Resource) (Document, error)

func (*StaticStore) Replace

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. Priorities must be unique so overlapping grants select deterministically.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL