Documentation
¶
Overview ¶
Package access provides adapter-independent capability policies for DALgo.
Access policies are default-deny and distinguish point reads, existence checks, queries, individual mutation kinds, and the reserved truncate operation. Rules inherit through structural DAL paths; the most-specific rule wins within one policy, while multiple policies compose by intersection.
Secured sessions and databases enforce policies before delegating to an adapter. Policies may be attached globally, carried by context.Context, or captured in a bound database handle. YAML and JSON codecs load the same versioned policy model from any io.Reader.
A denial returns a DeniedError matching ErrAccessDenied. The decision includes the operation, resource, policy name and source, winning rule, and explanation for trusted logs, tests, and administrative tooling.
Index ¶
- Constants
- Variables
- func BindDB(db dal.DB, ctx context.Context) dal.DB
- func CanInspectPolicy(policy Policy) bool
- func Capture(name string) any
- func EncodeAccessPolicy(writer io.Writer, codec Codec, policy *AccessPolicy) error
- func EncodeAuditPolicy(writer io.Writer, codec Codec, policy *AuditPolicy) error
- func EncodePrincipalPolicySet(writer io.Writer, codec Codec, set *PrincipalPolicySet) error
- func MarshalAccessPolicyJSON(policy *AccessPolicy) ([]byte, error)
- func MarshalAccessPolicyYAML(policy *AccessPolicy) ([]byte, error)
- func MarshalAuditPolicyJSON(policy *AuditPolicy) ([]byte, error)
- func MarshalAuditPolicyYAML(policy *AuditPolicy) ([]byte, error)
- func MarshalPrincipalPolicySetJSON(set *PrincipalPolicySet) ([]byte, error)
- func MarshalPrincipalPolicySetYAML(set *PrincipalPolicySet) ([]byte, error)
- func MarshalTugQLPolicyJSON(document TugQLDocument) ([]byte, error)
- func MarshalTugQLPolicyYAML(document TugQLDocument) ([]byte, error)
- func MustSecureDB(db dal.DB, options ...DBOption) dal.DB
- func SecureDB(db dal.DB, options ...DBOption) (dal.DB, error)
- func SecureReadSession(session dal.ReadSession, policies ...Policy) dal.ReadSession
- func SecureReadwriteSession(session dal.ReadwriteSession, policies ...Policy) dal.ReadwriteSession
- func SecureWriteSession(session dal.WriteSession, policies ...Policy) dal.WriteSession
- func ValidateDocumentCondition(condition DocumentCondition) error
- func WithCurrentUser(ctx context.Context, userID any) context.Context
- func WithNativeTableNamespace(ctx context.Context, namespace string) (context.Context, error)
- func WithPolicy(ctx context.Context, policies ...Policy) context.Context
- func WithPrincipal(ctx context.Context, principal Principal) context.Context
- func WithVariables(ctx context.Context, variables map[string]any) context.Context
- type AccessPolicy
- func DecodeAccessPolicy(reader io.Reader, codec Codec, options ...DecodeOption) (*AccessPolicy, error)
- func MustPolicy(name string, rules ...Rule) *AccessPolicy
- func NewPolicy(name string, rules ...Rule) (*AccessPolicy, error)
- func NewPolicyForRealm(realm, name string, rules ...Rule) (*AccessPolicy, error)
- func UnmarshalAccessPolicyJSON(data []byte, options ...DecodeOption) (*AccessPolicy, error)
- func UnmarshalAccessPolicyYAML(data []byte, options ...DecodeOption) (*AccessPolicy, error)
- func (p *AccessPolicy) Authorize(ctx context.Context, request Request) error
- func (p *AccessPolicy) Decide(ctx context.Context, request Request) Decision
- func (*AccessPolicy) InspectionPure() bool
- func (p *AccessPolicy) Name() string
- func (p *AccessPolicy) PolicyMetadata() PolicyMetadata
- func (p *AccessPolicy) Source() string
- type Assessment
- type AssessmentOutcome
- type AssessmentRestriction
- type AuditDecision
- type AuditPolicy
- func DecodeAuditPolicy(reader io.Reader, codec Codec, options ...DecodeOption) (*AuditPolicy, error)
- func MustAuditPolicy(name string, rules ...Rule) *AuditPolicy
- func NewAuditPolicy(name string, rules ...Rule) (*AuditPolicy, error)
- func UnmarshalAuditPolicyJSON(data []byte, options ...DecodeOption) (*AuditPolicy, error)
- func UnmarshalAuditPolicyYAML(data []byte, options ...DecodeOption) (*AuditPolicy, error)
- type AuthorizedFieldEvidence
- type AuthorizedPointEvidence
- type Bindings
- type CandidateValidator
- type Codec
- type CompiledMask
- type DBOption
- type Decision
- type DecisionScope
- type DecisionSlot
- type DecodeOption
- type DeniedError
- type Document
- type DocumentBindings
- type DocumentCondition
- type DocumentExpression
- type DocumentMetadata
- type DocumentRule
- type DocumentScope
- type EnforcementCoordinator
- type ExecutionClass
- type ExecutionEntry
- type ExecutionGate
- type ExecutionReceipt
- type ExecutionSession
- type ExecutionTarget
- type FilePolicyConfig
- type InspectionPurePolicy
- type InspectionSession
- type JSONCodec
- type MandatoryParticipant
- type Mask
- type MaskKind
- type MaskStage
- type Operations
- type PathPattern
- type Policy
- func DeclareInspectionPure(policy Policy) (Policy, error)
- func DecodePolicy(reader io.Reader, codec Codec, options ...DecodeOption) (Policy, error)
- func LoadPolicyFiles(root string, config FilePolicyConfig) ([]Policy, error)
- func WithPolicyMetadata(policy Policy, metadata PolicyMetadata) (Policy, error)
- type PolicyAssessment
- type PolicyLease
- type PolicyLeaseProvider
- type PolicyMetadata
- type PolicyMetadataProvider
- type PolicyProvider
- type PolicyProviderError
- type PolicyVisibility
- type Principal
- type PrincipalKind
- type PrincipalPolicySet
- func DecodePrincipalPolicySet(reader io.Reader, codec Codec, options ...DecodeOption) (*PrincipalPolicySet, error)
- func MustPrincipalPolicySet(name string, ruleSets map[string][]Rule, bindings Bindings) *PrincipalPolicySet
- func NewPrincipalPolicySet(name string, ruleSets map[string][]Rule, bindings Bindings) (*PrincipalPolicySet, error)
- func NewPrincipalPolicySetForRealm(realm, name string, ruleSets map[string][]Rule, bindings Bindings) (*PrincipalPolicySet, error)
- func UnmarshalPrincipalPolicySetJSON(data []byte, options ...DecodeOption) (*PrincipalPolicySet, error)
- func UnmarshalPrincipalPolicySetYAML(data []byte, options ...DecodeOption) (*PrincipalPolicySet, error)
- func (p *PrincipalPolicySet) Authorize(ctx context.Context, request Request) error
- func (p *PrincipalPolicySet) Decide(ctx context.Context, request Request) Decision
- func (*PrincipalPolicySet) InspectionPure() bool
- func (p *PrincipalPolicySet) Name() string
- func (p *PrincipalPolicySet) PolicyMetadata() PolicyMetadata
- func (p *PrincipalPolicySet) Source() string
- type PrincipalRef
- type ProtectedEvidence
- type ProtectedExecutionStorage
- type ProtectedInspectionStorage
- type ProtectedOperation
- func NewProtectedDelete(id string, key *record.Key, revision string) (ProtectedOperation, error)
- func NewProtectedEvidenceRead(id string, action Operations, key *record.Key, fields [][]string) (ProtectedOperation, error)
- func NewProtectedInsert(id string, key *record.Key, data map[string]any) (ProtectedOperation, error)
- func NewProtectedRead(id string, action Operations, key *record.Key) (ProtectedOperation, error)
- func NewProtectedSet(id string, key *record.Key, data map[string]any, revision string) (ProtectedOperation, error)
- func NewProtectedUpdate(id string, key *record.Key, updates []update.Update, revision string) (ProtectedOperation, error)
- func (o ProtectedOperation) Action() Operations
- func (o ProtectedOperation) CanonicalTarget() string
- func (o ProtectedOperation) Columns() [][]string
- func (o ProtectedOperation) Data() map[string]any
- func (o ProtectedOperation) ID() string
- func (o ProtectedOperation) IfDataRevision() string
- func (o ProtectedOperation) Key() *record.Key
- func (o ProtectedOperation) Updates() []ProtectedUpdate
- type ProtectedStorage
- type ProtectedUpdate
- type ReasonCode
- type Request
- type Resource
- type ResourceKind
- type Rule
- func Allow(operations Operations, name ...string) Rule
- func Audit(operations Operations, name ...string) Rule
- func Collection(collection string, rules ...Rule) Rule
- func CollectionGroupScope(name string, rules ...Rule) Rule
- func Deny(operations Operations, name ...string) Rule
- func IgnoreAudit(operations Operations, name ...string) Rule
- func OpaqueQueryScope(rules ...Rule) Rule
- func Root(rules ...Rule) Rule
- func Scope(collection string, id any, rules ...Rule) Rule
- func TableScope(table TableName, rules ...Rule) Rule
- func Under(pattern PathPattern, rules ...Rule) Rule
- type TableName
- type TugQLDocument
- type TugQLMetadata
- type TugQLRule
- type TugQLScope
- type TugQLTarget
- type WriteAlternative
- type WriteResidual
- type YAMLCodec
Constants ¶
const ( // DocumentAPIVersion is the first stable portable policy document version. DocumentAPIVersion = "dalgo.io/access/v1" // AccessPolicyKind is the document kind for an access policy. AccessPolicyKind = "AccessPolicy" // AuditPolicyKind is the document kind for an audit policy. AuditPolicyKind = "AuditPolicy" )
const ( // NameMask is a mask over single-segment names. NameMask MaskKind = "name" // FieldMask is a mask over dotted field paths. FieldMask MaskKind = "field" // MaxMaskStages is the maximum number of raw mask stages CompileMask accepts. MaxMaskStages = 1024 // MaxMaskPatterns is the maximum number of raw patterns CompileMask accepts. MaxMaskPatterns = 4096 // MaxMaskPatternBytes is the maximum byte length of one mask pattern. MaxMaskPatternBytes = 128 )
const (
// TugQLDocumentAPIVersion is the portable TugQL policy document version.
TugQLDocumentAPIVersion = "tugql.org/access/v1"
)
Variables ¶
var ( // ErrAccessDenied is matched by all authorization denials. ErrAccessDenied = errors.New("dalgo access denied") // ErrNotSerializable indicates a policy uses a construct that cannot be // represented by a portable policy document. ErrNotSerializable = errors.New("dalgo access policy is not serializable") )
var AnyID = anyIDValue{}
AnyID matches any record ID, including an incomplete insert key whose ID is not assigned yet.
var ErrDataRevisionConflict = errors.New("access: data revision conflict")
ErrDataRevisionConflict is returned when a protected operation's expected data revision does not match the stored revision.
var ErrNestingTooDeep = errors.New("dalgo access: queries nested too deeply")
ErrNestingTooDeep is matched by the error a secured session returns for a query with nested queries put to it from inside more than a small number of nested routes: the session and the query engine do not re-enter each other without bound. The error also matches ErrAccessDenied.
var ErrProtectedRecordExists = errors.New("access: protected record already exists")
ErrProtectedRecordExists is returned when a protected insert refers to a record that already exists.
ErrProtectedResourceUnavailable is returned when a protected get, exists, update, or delete refers to a record that does not exist.
Functions ¶
func BindDB ¶
BindDB captures context policies on the returned DB handle. Passing a later operation context cannot remove them or a native table namespace bound with WithNativeTableNamespace, while additional policies still narrow the capability. A handle over a database that was not secured denies every request when the context it is bound to, and the context of the request, holds no policy.
func CanInspectPolicy ¶ added in v0.80.0
CanInspectPolicy reports whether plan and inspection APIs may safely call the policy's Decide method.
func Capture ¶ added in v0.77.0
Capture matches any record ID like AnyID and binds the matched value to the variable $path.<name> for the conditions of rules under this pattern, so a rule on /spaces/{spaceID}/ext/trackus/** can say `spaceID == $path.spaceID`. The name is a plain identifier; it must be unique within one pattern.
func EncodeAccessPolicy ¶
func EncodeAccessPolicy(writer io.Writer, codec Codec, policy *AccessPolicy) error
EncodeAccessPolicy validates and writes one AccessPolicy through codec.
func EncodeAuditPolicy ¶
func EncodeAuditPolicy(writer io.Writer, codec Codec, policy *AuditPolicy) error
EncodeAuditPolicy validates and writes one AuditPolicy through codec.
func EncodePrincipalPolicySet ¶ added in v0.78.0
func EncodePrincipalPolicySet(writer io.Writer, codec Codec, set *PrincipalPolicySet) error
EncodePrincipalPolicySet validates and writes one principal policy set through codec.
func MarshalAccessPolicyJSON ¶
func MarshalAccessPolicyJSON(policy *AccessPolicy) ([]byte, error)
MarshalAccessPolicyJSON encodes policy as JSON.
func MarshalAccessPolicyYAML ¶
func MarshalAccessPolicyYAML(policy *AccessPolicy) ([]byte, error)
MarshalAccessPolicyYAML encodes policy as YAML.
func MarshalAuditPolicyJSON ¶
func MarshalAuditPolicyJSON(policy *AuditPolicy) ([]byte, error)
MarshalAuditPolicyJSON encodes policy as JSON.
func MarshalAuditPolicyYAML ¶
func MarshalAuditPolicyYAML(policy *AuditPolicy) ([]byte, error)
MarshalAuditPolicyYAML encodes policy as YAML.
func MarshalPrincipalPolicySetJSON ¶ added in v0.78.0
func MarshalPrincipalPolicySetJSON(set *PrincipalPolicySet) ([]byte, error)
MarshalPrincipalPolicySetJSON encodes set by delegating to EncodePrincipalPolicySet with JSONCodec.
func MarshalPrincipalPolicySetYAML ¶ added in v0.78.0
func MarshalPrincipalPolicySetYAML(set *PrincipalPolicySet) ([]byte, error)
MarshalPrincipalPolicySetYAML encodes set by delegating to EncodePrincipalPolicySet with YAMLCodec.
func MarshalTugQLPolicyJSON ¶ added in v0.94.0
func MarshalTugQLPolicyJSON(document TugQLDocument) ([]byte, error)
MarshalTugQLPolicyJSON emits the normalized document as indented JSON.
func MarshalTugQLPolicyYAML ¶ added in v0.94.0
func MarshalTugQLPolicyYAML(document TugQLDocument) ([]byte, error)
MarshalTugQLPolicyYAML emits normalized policy text. Formatting and comments from the original document are deliberately not preserved in this version.
func MustSecureDB ¶
MustSecureDB wraps db and panics when configuration is invalid.
func SecureDB ¶
SecureDB wraps db with adapter-independent access-policy enforcement. A request is denied while no policy is in force for it: no database policy, no policy bound with BindDB and none in the context of the request. An enforcement coordinator governs the protected write profile only; it does not by itself allow a read.
func SecureReadSession ¶
func SecureReadSession(session dal.ReadSession, policies ...Policy) dal.ReadSession
SecureReadSession wraps a read session with database-bound policies. A session built with no policy, with a nil policy (an interface holding nothing, or a nil pointer) or with a list that holds one denies every request.
func SecureReadwriteSession ¶
func SecureReadwriteSession(session dal.ReadwriteSession, policies ...Policy) dal.ReadwriteSession
SecureReadwriteSession wraps a combined session with database-bound policies. A session built with no policy, with a nil policy (an interface holding nothing, or a nil pointer) or with a list that holds one denies every request.
func SecureWriteSession ¶
func SecureWriteSession(session dal.WriteSession, policies ...Policy) dal.WriteSession
SecureWriteSession wraps a write session with database-bound policies. A session built with no policy, with a nil policy (an interface holding nothing, or a nil pointer) or with a list that holds one denies every request.
func ValidateDocumentCondition ¶ added in v0.80.0
func ValidateDocumentCondition(condition DocumentCondition) error
ValidateDocumentCondition validates the portable condition shape without compiling or evaluating a policy.
func WithCurrentUser ¶ added in v0.75.0
WithCurrentUser sets the $currentUser variable.
func WithNativeTableNamespace ¶ added in v0.99.0
WithNativeTableNamespace adds canonical collection-path constraints to the original authorization of qualified tables in namespace. It never replaces the original assessment or grants permission. The trusted host must verify the exact namespace and ordinary table names on the actual native source before data dispatch; query/client input must not configure this option.
One immutable policy snapshot per authorized request is assessed against both resource forms. Each affected policy is assessed twice; AssessmentRestriction's PolicyIndex indexes Assessment.Policies, which includes canonical delegates. A canonical delegate sees a path-kind resource carrying the original table identity, so an explicit collection-path denial also constrains a table rule. BindDB and transaction handles retain the namespace when later operation contexts omit it, and refuse conflicting namespaces. Bind at the outermost secured handle or on the operation context: binding only an inner handle cannot constrain policies already evaluated by an outer handle. Every affected policy must declare InspectionPure. All original query, principal, execution and column information is retained, and all obligations from both assessments are enforced by the existing secured-read machinery. The canonical delegate is a complete path-kind assessment, not a deny-only probe. A missing path match denies. Matching table rules retain their usual precedence unless a collection-path denial settles the path; a path allow's row/field clauses are not additional constraints when a table rule wins. All obligations actually emitted by the two assessments are intersected. Other namespaces and opaque/unknown shapes retain their original policy semantics and must be refused by the host when native identity is unverified. Without this option all existing policy semantics remain unchanged. A nonnil context is required. An existing binding cannot be replaced.
func WithPolicy ¶
WithPolicy returns a child context carrying additional restrictive policies. Policies inherited from the parent context are preserved.
func WithPrincipal ¶ added in v0.78.0
WithPrincipal returns a child context carrying the caller's principal. It replaces any principal inherited from the parent context.
func WithVariables ¶ added in v0.75.0
WithVariables returns a child context carrying values for the parameters a conditional rule may reference: a rule conditioned on ownerID == $tenant reads the "tenant" entry. Variables inherited from the parent context are kept and same-named entries are replaced. $now resolves to the evaluation time unless a "now" variable is supplied.
Types ¶
type AccessPolicy ¶
type AccessPolicy struct {
// contains filtered or unexported fields
}
AccessPolicy is the declarative hierarchical Policy implementation.
func DecodeAccessPolicy ¶
func DecodeAccessPolicy(reader io.Reader, codec Codec, options ...DecodeOption) (*AccessPolicy, error)
DecodeAccessPolicy decodes and validates one AccessPolicy from any reader.
func MustPolicy ¶
func MustPolicy(name string, rules ...Rule) *AccessPolicy
MustPolicy constructs a policy and panics when its declaration is invalid.
func NewPolicy ¶
func NewPolicy(name string, rules ...Rule) (*AccessPolicy, error)
NewPolicy constructs a default-deny access policy.
func NewPolicyForRealm ¶ added in v0.80.0
func NewPolicyForRealm(realm, name string, rules ...Rule) (*AccessPolicy, error)
NewPolicyForRealm creates an application-owned declarative policy using typed principals in realm. Legacy NewPolicy remains unqualified.
func UnmarshalAccessPolicyJSON ¶
func UnmarshalAccessPolicyJSON(data []byte, options ...DecodeOption) (*AccessPolicy, error)
UnmarshalAccessPolicyJSON decodes an access policy by delegating to DecodeAccessPolicy with JSONCodec.
func UnmarshalAccessPolicyYAML ¶
func UnmarshalAccessPolicyYAML(data []byte, options ...DecodeOption) (*AccessPolicy, error)
UnmarshalAccessPolicyYAML decodes an access policy by delegating to DecodeAccessPolicy with YAMLCodec.
func (*AccessPolicy) Authorize ¶
func (p *AccessPolicy) Authorize(ctx context.Context, request Request) error
Authorize returns nil when Decide allows the request and a DeniedError otherwise.
func (*AccessPolicy) Decide ¶
func (p *AccessPolicy) Decide(ctx context.Context, request Request) Decision
Decide evaluates the request against the compiled rules. It denies when the principal realm, execution gate, operation, or resource list is not acceptable, and otherwise returns the combined decision for every resource.
func (*AccessPolicy) InspectionPure ¶ added in v0.80.0
func (*AccessPolicy) InspectionPure() bool
InspectionPure reports that the policy is safe for plan and inspection evaluation.
func (*AccessPolicy) PolicyMetadata ¶ added in v0.80.0
func (p *AccessPolicy) PolicyMetadata() PolicyMetadata
PolicyMetadata returns owner metadata, using private visibility when none is set.
func (*AccessPolicy) Source ¶
func (p *AccessPolicy) Source() string
Source returns an optional storage-neutral reference supplied while loading a policy document, such as an object key, URL, database key, or file path.
type Assessment ¶ added in v0.80.0
type Assessment struct {
Outcome AssessmentOutcome
Complete bool
Policies []PolicyAssessment
Restrictions []AssessmentRestriction
}
Assessment is the result of assessing a request: the outcome, whether evaluation completed, each policy's decision, and any outstanding restrictions.
func AssessContextPlan ¶ added in v0.98.0
func AssessContextPlan(ctx context.Context, request Request, options ...DBOption) (Assessment, error)
AssessContextPlan assesses the actual immutable request against every policy supplied by the existing SecureDB options AND inherited WithPolicy context. Database providers are required snapshots exactly as for secured reads; a provider failure, empty/nil snapshot or required missing context fails closed. All policies must be explicitly safe for inspection. Row/field obligations remain in Assessment; allow/conditional is not authority to skip enforcement. No DAL/storage operation is executed and no reusable authorization is minted. Callers supply the same trusted DB policy configuration used for the operation; this function cannot discover policies hidden in an unrelated wrapped handle. Request/options/policy implementations must be immutable during this call. Existing AssessPlan behavior is unchanged. Coordinator options convey no read permission and this call does not inspect protected write/storage evidence.
func AssessPlan ¶ added in v0.80.0
func AssessPlan(ctx context.Context, request Request, policies []Policy) Assessment
AssessPlan evaluates policy metadata only. It performs no DAL operation and never reads a stored row. Callers must pass an immutable policy snapshot.
type AssessmentOutcome ¶ added in v0.80.0
type AssessmentOutcome string
AssessmentOutcome is the combined result of assessing a request against policies.
const ( // AssessmentAllow is the outcome when every policy allows and no restriction remains. AssessmentAllow AssessmentOutcome = "allow" // AssessmentConditional is the outcome when policies allow with outstanding restrictions. AssessmentConditional AssessmentOutcome = "conditional" // AssessmentDeny is the outcome when a policy denies the request. AssessmentDeny AssessmentOutcome = "deny" // AssessmentIndeterminate is the outcome when evaluation does not complete. AssessmentIndeterminate AssessmentOutcome = "indeterminate" )
type AssessmentRestriction ¶ added in v0.80.0
type AssessmentRestriction struct {
OperationID string
PolicyIndex int // Index into Assessment.Policies, including opt-in canonical delegates.
ResourceIndex int
Rule string
Slot DecisionSlot
Condition dal.Condition
Expression *DocumentCondition
Write *WriteResidual
Fields []string
Opaque bool
}
AssessmentRestriction is an outstanding enforceable obligation. In plan mode it is complete metadata, not missing evidence.
func (AssessmentRestriction) DocumentCondition ¶ added in v0.80.0
func (restriction AssessmentRestriction) DocumentCondition() (*DocumentCondition, error)
DocumentCondition returns the portable representation of a row condition. A restriction whose condition is not portable returns ErrNotSerializable.
type AuditDecision ¶
type AuditDecision struct {
Audit bool
Operation Operations
Resource Resource
Policy string
PolicySource string
Rule string
Effect string
Explanation string
}
AuditDecision explains whether an operation should be emitted to an audit pipeline. It never changes authorization.
type AuditPolicy ¶
type AuditPolicy struct {
// contains filtered or unexported fields
}
AuditPolicy classifies operations with the same hierarchy as AccessPolicy. Its default is IgnoreAudit.
func DecodeAuditPolicy ¶
func DecodeAuditPolicy(reader io.Reader, codec Codec, options ...DecodeOption) (*AuditPolicy, error)
DecodeAuditPolicy decodes and validates one AuditPolicy from any reader.
func MustAuditPolicy ¶
func MustAuditPolicy(name string, rules ...Rule) *AuditPolicy
MustAuditPolicy constructs an audit policy and panics when NewAuditPolicy returns an error.
func NewAuditPolicy ¶
func NewAuditPolicy(name string, rules ...Rule) (*AuditPolicy, error)
NewAuditPolicy constructs an audit policy from rules that use audit and ignore-audit effects. An empty name is rejected.
func UnmarshalAuditPolicyJSON ¶
func UnmarshalAuditPolicyJSON(data []byte, options ...DecodeOption) (*AuditPolicy, error)
UnmarshalAuditPolicyJSON decodes an audit policy by delegating to DecodeAuditPolicy with JSONCodec.
func UnmarshalAuditPolicyYAML ¶
func UnmarshalAuditPolicyYAML(data []byte, options ...DecodeOption) (*AuditPolicy, error)
UnmarshalAuditPolicyYAML decodes an audit policy by delegating to DecodeAuditPolicy with YAMLCodec.
func (*AuditPolicy) Classify ¶
func (p *AuditPolicy) Classify(_ context.Context, request Request) AuditDecision
Classify classifies each resource by the first matching rule, or as ignore-audit when none match. An operation that is not a single leaf, or a request with no resources, is ignore-audit. The context is ignored.
func (*AuditPolicy) Source ¶
func (p *AuditPolicy) Source() string
Source returns the storage-neutral reference supplied while loading the policy document.
type AuthorizedFieldEvidence ¶ added in v0.80.0
AuthorizedFieldEvidence is one field value released from a protected read: its path, whether it was present, and the value.
type AuthorizedPointEvidence ¶ added in v0.80.0
type AuthorizedPointEvidence struct {
OperationID string
Exists bool
DataRevision string
Fields []AuthorizedFieldEvidence
}
AuthorizedPointEvidence is the authorized existence, data revision, and field values for one protected operation.
type Bindings ¶ added in v0.78.0
type Bindings struct {
Roles map[string][]string
Groups map[string][]string
Users map[string][]string
Everyone []string
}
Bindings map principals to named rule sets. A binding value is a list of rule-set names; Everyone applies to every principal, including an absent one.
type CandidateValidator ¶ added in v0.80.0
CandidateValidator performs pure schema/business validation of one complete final image. It runs inside the pinned storage boundary before ACL evaluation. Implementations must not mutate the image or cause effects.
type Codec ¶
type Codec interface {
// Decode reads one policy document from the reader into document.
Decode(io.Reader, *Document) error
// Encode writes document to the writer.
Encode(io.Writer, Document) error
}
Codec decouples policy loading from both its syntax and its storage. A caller may implement this interface for HCL or another representation.
type CompiledMask ¶ added in v0.80.0
type CompiledMask struct {
// contains filtered or unexported fields
}
CompiledMask is an immutable selection mask. Its canonical representation is returned as a copy so a caller cannot alter an active policy generation.
func CompileMask ¶ added in v0.80.0
func CompileMask(mask Mask, kind MaskKind) (*CompiledMask, error)
CompileMask validates and normalizes a scoped mask. Limits apply to raw input before adjacent-stage merging or pattern deduplication.
func (*CompiledMask) Allows ¶ added in v0.80.0
func (m *CompiledMask) Allows(path string) bool
Allows stops at the first stage which does not select the requested path. In particular, a later include can never escape its excluded parent set.
func (*CompiledMask) Canonical ¶ added in v0.80.0
func (m *CompiledMask) Canonical() Mask
Canonical returns a copy of the normalized mask. A nil receiver returns an empty mask.
func (*CompiledMask) CompleteSubtree ¶ added in v0.80.0
func (m *CompiledMask) CompleteSubtree(path string) bool
CompleteSubtree is deliberately conservative. A concrete leaf may be permitted when the corresponding whole object cannot safely be disclosed.
type DBOption ¶
type DBOption func(*secureDBOptions) error
DBOption configures SecureDB.
func RequireContextPolicy ¶
func RequireContextPolicy() DBOption
RequireContextPolicy makes missing context-bound authority fail closed.
func WithDatabasePolicies ¶
WithDatabasePolicies adds policies that apply to every operation through the secured DB and cannot be widened by a context policy.
func WithDatabasePolicyProvider ¶ added in v0.80.0
func WithDatabasePolicyProvider(provider PolicyProvider) DBOption
WithDatabasePolicyProvider configures a required dynamic owner snapshot.
func WithEnforcementCoordinator ¶ added in v0.80.0
func WithEnforcementCoordinator(coordinator *EnforcementCoordinator) DBOption
WithEnforcementCoordinator enables the bounded protected write profile.
type Decision ¶
type Decision struct {
Allowed bool
Operation Operations
Resource Resource
Policy string
PolicySource string
Rule string
Effect string
Explanation string
// Code, Scope, Slot, and Columns are stable machine-readable facts for
// authorization inspection. Explanation remains diagnostic text and must
// never be parsed to construct a public result.
Code ReasonCode
Scope DecisionScope
Slot DecisionSlot
Columns [][]string
// Condition is the source text of the row condition behind a conditional
// decision, with parameter names rather than resolved values.
Condition string
// Residuals holds, per request resource (same index as Request.Resources),
// the resolved row condition the caller must still enforce before the
// operation is complete: after the read for point operations, by query
// rewrite for Query. A nil entry means the resource is allowed outright.
// Residuals is nil for an unconditional decision.
Residuals []dal.Condition
// ResidualDocuments preserves source expressions with unresolved params.
ResidualDocuments []*DocumentCondition
// Writes holds, per request resource, the ordered alternatives that decide
// a write on that resource (see WriteResidual). A nil entry means the write
// is allowed outright, with no row or post-image constraint.
Writes []*WriteResidual
}
Decision explains an access-policy result.
func DecisionsFromError ¶ added in v0.80.0
DecisionsFromError returns an immutable copy of the policy decisions collected for a denied request. Legacy DeniedErrors yield Decision alone.
type DecisionScope ¶ added in v0.80.0
type DecisionScope string
DecisionScope names the part of a request a decision refers to.
const ( // DecisionScopeRequest is the decision scope for the request as a whole. DecisionScopeRequest DecisionScope = "request" // DecisionScopeDatabase is the decision scope for a database. DecisionScopeDatabase DecisionScope = "database" // DecisionScopeTable is the decision scope for a table or collection. DecisionScopeTable DecisionScope = "table" // DecisionScopeRow is the decision scope for a row condition. DecisionScopeRow DecisionScope = "row" // DecisionScopeColumn is the decision scope for a field. DecisionScopeColumn DecisionScope = "column" // DecisionScopeOperation is the decision scope for the operation. DecisionScopeOperation DecisionScope = "operation" // DecisionScopePrincipal is the decision scope for the caller. DecisionScopePrincipal DecisionScope = "principal" // DecisionScopeConfiguration is the decision scope for policy or request configuration. DecisionScopeConfiguration DecisionScope = "configuration" )
type DecisionSlot ¶ added in v0.80.0
type DecisionSlot string
DecisionSlot names the clause a restriction or denial refers to.
const ( // DecisionSlotWhere is the slot for a row where condition. DecisionSlotWhere DecisionSlot = "where" // DecisionSlotCheck is the slot for a post-image check. DecisionSlotCheck DecisionSlot = "check" // DecisionSlotFields is the slot for a field restriction. DecisionSlotFields DecisionSlot = "fields" )
type DecodeOption ¶
type DecodeOption func(*decodeOptions)
DecodeOption configures decoding of one policy document.
func WithSource ¶
func WithSource(reference string) DecodeOption
WithSource records where a policy document came from. It may be a file path, object key, URL, database key, or any application-defined reference.
type DeniedError ¶
type DeniedError struct {
Decision Decision
// Decisions contains every independently evaluated mandatory policy in
// configured order. Decision remains the first denial for legacy callers.
Decisions []Decision
}
DeniedError is returned when a policy rejects an operation.
func (*DeniedError) Error ¶
func (e *DeniedError) Error() string
func (*DeniedError) Unwrap ¶
func (e *DeniedError) Unwrap() error
type Document ¶
type Document struct {
APIVersion string `json:"apiVersion" yaml:"apiVersion"`
Kind string `json:"kind" yaml:"kind"`
Metadata DocumentMetadata `json:"metadata" yaml:"metadata"`
Default string `json:"default" yaml:"default"`
Scopes []DocumentScope `json:"scopes,omitempty" yaml:"scopes,omitempty"`
// RuleSets and Bindings describe a principal policy set: named rule sets
// (each a scope tree like Scopes) and the roles, groups, users and
// everyone they are bound to. A document has either Scopes or both
// RuleSets and Bindings.
RuleSets map[string][]DocumentScope `json:"ruleSets,omitempty" yaml:"ruleSets,omitempty"`
Bindings *DocumentBindings `json:"bindings,omitempty" yaml:"bindings,omitempty"`
}
Document is the storage-neutral representation shared by YAML, JSON, and third-party codecs. YAML is the canonical human-authored encoding.
type DocumentBindings ¶ added in v0.78.0
type DocumentBindings struct {
Roles map[string][]string `json:"roles,omitempty" yaml:"roles,omitempty"`
Groups map[string][]string `json:"groups,omitempty" yaml:"groups,omitempty"`
Users map[string][]string `json:"users,omitempty" yaml:"users,omitempty"`
Everyone []string `json:"everyone,omitempty" yaml:"everyone,omitempty"`
}
DocumentBindings maps principals to rule-set names.
type DocumentCondition ¶ added in v0.75.0
type DocumentCondition struct {
Op string `json:"op,omitempty" yaml:"op,omitempty"`
Left *DocumentExpression `json:"left,omitempty" yaml:"left,omitempty"`
Right *DocumentExpression `json:"right,omitempty" yaml:"right,omitempty"`
And []DocumentCondition `json:"and,omitempty" yaml:"and,omitempty"`
Or []DocumentCondition `json:"or,omitempty" yaml:"or,omitempty"`
}
DocumentCondition is a row condition in a portable policy document. It uses the TugQL condition syntax so a policy and a saved query are written alike: a comparison sets op/left/right; a group sets and or or.
type DocumentExpression ¶ added in v0.75.0
type DocumentExpression struct {
Field string `json:"field,omitempty" yaml:"field,omitempty"`
Value any `json:"value,omitempty" yaml:"value,omitempty"`
Values any `json:"values,omitempty" yaml:"values,omitempty"`
Param string `json:"param,omitempty" yaml:"param,omitempty"`
}
DocumentExpression is one operand: exactly one of field, value, values or param is set.
type DocumentMetadata ¶
type DocumentMetadata struct {
Name string `json:"name" yaml:"name"`
}
DocumentMetadata holds the name of a portable policy document.
type DocumentRule ¶
type DocumentRule struct {
ID string `json:"id" yaml:"id"`
Effect string `json:"effect" yaml:"effect"`
Operations []string `json:"operations" yaml:"operations"`
// Where is an optional row condition on an allow rule, written in the
// TugQL condition syntax with a `param` expression for runtime variables.
Where *DocumentCondition `json:"where,omitempty" yaml:"where,omitempty"`
// Check is an optional post-image condition on an allow rule: what a row
// written under the rule must satisfy afterwards. Defaults to Where.
Check *DocumentCondition `json:"check,omitempty" yaml:"check,omitempty"`
// Fields is an optional allow-list of field patterns on an allow rule.
Fields []string `json:"fields,omitempty" yaml:"fields,omitempty"`
// contains filtered or unexported fields
}
DocumentRule is one portable rule: an id, an effect, the operations it covers, and optional where, check, and field constraints.
type DocumentScope ¶
type DocumentScope struct {
Path string `json:"path,omitempty" yaml:"path,omitempty"`
CollectionGroup string `json:"collectionGroup,omitempty" yaml:"collectionGroup,omitempty"`
OpaqueQuery bool `json:"opaqueQuery,omitempty" yaml:"opaqueQuery,omitempty"`
Table *TableName `json:"table,omitempty" yaml:"table,omitempty"`
Rules []DocumentRule `json:"rules,omitempty" yaml:"rules,omitempty"`
Scopes []DocumentScope `json:"scopes,omitempty" yaml:"scopes,omitempty"`
}
DocumentScope selects exactly one resource kind. Path is a structural path fragment; nested scopes append their path to the containing scope. Table names one table by schema, database or both (see TableScope); it is top-level only and holds rules, not scopes.
type EnforcementCoordinator ¶ added in v0.80.0
type EnforcementCoordinator struct {
// contains filtered or unexported fields
}
EnforcementCoordinator runs protected inspection and execution against mandatory policy participants and a trusted storage boundary.
func NewEnforcementCoordinator ¶ added in v0.80.0
func NewEnforcementCoordinator(storage ProtectedStorage, participants ...MandatoryParticipant) (*EnforcementCoordinator, error)
NewEnforcementCoordinator builds a coordinator with no candidate validator. It delegates to NewValidatedEnforcementCoordinator.
func NewValidatedEnforcementCoordinator ¶ added in v0.80.0
func NewValidatedEnforcementCoordinator(storage ProtectedStorage, validator CandidateValidator, participants ...MandatoryParticipant) (*EnforcementCoordinator, error)
NewValidatedEnforcementCoordinator builds a coordinator. storage is required, and participants must include at least one policy provider. Each participant needs a unique layer id and a provider, a validator, or both.
func (*EnforcementCoordinator) WithinExecution ¶ added in v0.80.0
func (c *EnforcementCoordinator) WithinExecution(ctx context.Context, operations []ProtectedOperation, execute func(ExecutionSession) error) error
WithinExecution validates the operations, then inside the storage execution boundary acquires policy leases, validates candidate images, and calls execute. It returns an error when the callback returns without a successful Execute.
func (*EnforcementCoordinator) WithinInspection ¶ added in v0.80.0
func (c *EnforcementCoordinator) WithinInspection(ctx context.Context, operations []ProtectedOperation, inspect func(InspectionSession) error) error
WithinInspection validates the operations, then inside the storage inspection boundary acquires policy leases, validates candidate images, and calls inspect with the inspection session.
type ExecutionClass ¶ added in v0.80.0
type ExecutionClass string
ExecutionClass names an execution surface a request or gate entry uses.
const ( // ExecutionTugQL is the TugQL execution class. ExecutionTugQL ExecutionClass = "tugql" // ExecutionNativeSQL is the native SQL execution class. ExecutionNativeSQL ExecutionClass = "native_sql" // ExecutionNativeGraphQL is the native GraphQL execution class. ExecutionNativeGraphQL ExecutionClass = "native_graphql" // ExecutionStoredProcedure is the stored-procedure execution class. ExecutionStoredProcedure ExecutionClass = "stored_procedure" )
type ExecutionEntry ¶ added in v0.80.0
type ExecutionEntry struct {
Class ExecutionClass `json:"class" yaml:"class"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Mask *Mask `json:"mask,omitempty" yaml:"mask,omitempty"`
}
ExecutionEntry is one execution surface an execution gate may allow.
type ExecutionGate ¶ added in v0.80.0
type ExecutionGate struct {
Allow []ExecutionEntry `json:"allow" yaml:"allow"`
}
ExecutionGate restricts the execution surfaces at this policy's owner. A present gate with an empty allow list permits no query execution surface.
type ExecutionReceipt ¶ added in v0.80.0
ExecutionReceipt is the data revision recorded for one executed operation.
type ExecutionSession ¶ added in v0.80.0
type ExecutionSession interface {
InspectionSession
// Execute performs the protected writes when the assessment allows them.
Execute(context.Context) (Assessment, error)
// Receipts returns per-operation data revisions after a successful Execute.
Receipts(context.Context) ([]ExecutionReceipt, error)
// Revisions maps operation ids to data revisions from Receipts.
Revisions(context.Context) (map[string]string, error)
// contains filtered or unexported methods
}
ExecutionSession is an InspectionSession that can also perform the protected writes.
type ExecutionTarget ¶ added in v0.80.0
type ExecutionTarget struct {
Class ExecutionClass
Namespace string
Name string
}
ExecutionTarget describes an assessment's execution surface. Real secured query sessions derive the class from the query; callers cannot relabel an opaque query as TugQL. Namespace and Name apply only to procedure assessment.
type FilePolicyConfig ¶ added in v0.80.0
type FilePolicyConfig struct {
Enabled bool `json:"enabled" yaml:"enabled"`
Database string `json:"database" yaml:"database"`
Realm string `json:"realm,omitempty" yaml:"realm,omitempty"`
Policies []string `json:"policies" yaml:"policies"`
}
FilePolicyConfig selects portable policy files relative to a trusted root. Loading is opt-in: a zero value disables file policies.
type InspectionPurePolicy ¶ added in v0.80.0
type InspectionPurePolicy interface {
Policy
// InspectionPure reports whether Decide is safe for plan and inspection evaluation.
InspectionPure() bool
}
InspectionPurePolicy declares that Decide is deterministic and free of externally observable side effects, so it may be evaluated by plan and inspection APIs without performing the represented operation.
type InspectionSession ¶ added in v0.80.0
type InspectionSession interface {
// Assess returns the assessment for the protected operations.
Assess(context.Context) (Assessment, error)
// Evidence returns authorized field evidence when the assessment allows it.
Evidence(context.Context) ([]AuthorizedPointEvidence, error)
// ReadVisibility reports which operation records are visible to the ingress principal.
ReadVisibility(context.Context) (map[string]bool, error)
// ReadVisibilityFor intersects ingress visibility with visibility for the given principal.
ReadVisibilityFor(context.Context, Principal) (map[string]bool, error)
// contains filtered or unexported methods
}
InspectionSession is the callback view of one protected inspection.
type JSONCodec ¶
type JSONCodec struct{}
JSONCodec decodes and encodes a policy document as JSON.
type MandatoryParticipant ¶ added in v0.80.0
type MandatoryParticipant struct {
LayerID string
Provider PolicyLeaseProvider
Validator CandidateValidator
}
MandatoryParticipant names one layer that supplies a policy lease, a candidate validator, or both.
func NewStaticParticipant ¶ added in v0.80.0
func NewStaticParticipant(layerID string, policies ...Policy) (MandatoryParticipant, error)
NewStaticParticipant returns a participant whose provider always yields the same static lease. layerID must be non-empty and policies must be acceptable to NewStaticPolicyLease.
type Mask ¶ added in v0.80.0
type Mask struct {
Stages []MaskStage `json:"stages" yaml:"stages"`
}
Mask is the portable TugQL scoped selection chain. Adjacent stages of the same action form one OR-list. Opposite-action stages select only within the set selected by all preceding stages; they are not independent rules.
type MaskKind ¶ added in v0.80.0
type MaskKind string
MaskKind selects whether a mask matches names or dotted field paths.
type MaskStage ¶ added in v0.80.0
type MaskStage struct {
Include []string `json:"include,omitempty" yaml:"include,omitempty"`
Exclude []string `json:"exclude,omitempty" yaml:"exclude,omitempty"`
}
MaskStage is one include or exclude step in a Mask.
type Operations ¶
type Operations uint16
Operations is a set of DAL operations. Leaf operation constants contain one bit; the group constants are immutable convenience unions of those leaves.
const ( // Get is the leaf operation that reads one record. Get Operations = 1 << iota // Exists is the leaf operation that checks whether a record exists. Exists // Query is the leaf operation that reads through a query. Query // Insert is the leaf operation that inserts a record. Insert // Set is the leaf operation that sets a record. Set // Update is the leaf operation that updates fields of a record. Update // Delete is the leaf operation that deletes a record. Delete // Truncate is reserved for collection-wide deletion. DALgo does not expose // a truncate session method yet, but policies can grant and evaluate it now. Truncate // Read is Get, Exists, and Query. Read = Get | Exists | Query // Write is Insert, Set, Update, Delete, and Truncate. Write = Insert | Set | Update | Delete | Truncate // ReadWrite is Read and Write. ReadWrite = Read | Write )
func (Operations) String ¶
func (o Operations) String() string
type PathPattern ¶
type PathPattern struct {
// contains filtered or unexported fields
}
PathPattern is a structural path prefix. Arguments alternate between a collection name and an ID matcher; a terminal collection name is valid.
func NewPath ¶
func NewPath(parts ...any) (PathPattern, error)
NewPath builds a structural path pattern.
func Path ¶
func Path(parts ...any) PathPattern
Path builds a structural path pattern and panics on a malformed shape.
func (PathPattern) String ¶
func (p PathPattern) String() string
type Policy ¶
type Policy interface {
// Name returns the policy name.
Name() string
// Decide evaluates the request and returns the authorization decision.
Decide(context.Context, Request) Decision
// Authorize returns an error when the request is not allowed.
Authorize(context.Context, Request) error
}
Policy is a named access capability. Every Policy applied to a secured request must allow every target resource.
func DeclareInspectionPure ¶ added in v0.80.0
DeclareInspectionPure explicitly opts a custom policy into plan and inspection evaluation. The caller is responsible for the purity claim.
func DecodePolicy ¶ added in v0.78.0
DecodePolicy decodes one AccessPolicy document as either an AccessPolicy or, when it declares rule sets and bindings, a PrincipalPolicySet.
func LoadPolicyFiles ¶ added in v0.80.0
func LoadPolicyFiles(root string, config FilePolicyConfig) ([]Policy, error)
LoadPolicyFiles loads enabled TugQL portable policy documents from root. Every configured file must be valid; errors fail the complete load closed.
func WithPolicyMetadata ¶ added in v0.80.0
func WithPolicyMetadata(policy Policy, metadata PolicyMetadata) (Policy, error)
WithPolicyMetadata attaches immutable owner snapshot metadata to a policy.
type PolicyAssessment ¶ added in v0.80.0
type PolicyAssessment struct {
OperationID string
LayerID string
Policy PolicyMetadata
Decision Decision
}
PolicyAssessment is one policy's metadata and decision within an assessment.
type PolicyLease ¶ added in v0.80.0
type PolicyLease interface {
// Policies returns the pinned policies.
Policies() []Policy
// Revision returns the snapshot revision.
Revision() string
// Release releases the lease.
Release()
}
PolicyLease is a pinned policy snapshot held for one protected inspection or execution.
func NewStaticPolicyLease ¶ added in v0.80.0
func NewStaticPolicyLease(policies ...Policy) (PolicyLease, error)
NewStaticPolicyLease returns a lease holding the given policies. It rejects an empty list and a nil policy.
type PolicyLeaseProvider ¶ added in v0.80.0
type PolicyLeaseProvider func(context.Context) (PolicyLease, error)
PolicyLeaseProvider acquires a policy lease for the call.
type PolicyMetadata ¶ added in v0.80.0
type PolicyMetadata struct {
ID string
Revision string
Visibility PolicyVisibility
Source string
}
PolicyMetadata is trusted owner metadata. Source is an internal storage reference and must not be projected to an ordinary HTTP response.
func DescribePolicy ¶ added in v0.80.0
func DescribePolicy(policy Policy) PolicyMetadata
DescribePolicy returns a defensive copy of a policy's trusted metadata. Policies without metadata are private by default.
type PolicyMetadataProvider ¶ added in v0.80.0
type PolicyMetadataProvider interface {
// PolicyMetadata returns the policy's trusted owner metadata.
PolicyMetadata() PolicyMetadata
}
PolicyMetadataProvider supplies a policy's trusted owner metadata.
type PolicyProvider ¶ added in v0.80.0
PolicyProvider returns one immutable owner policy snapshot for an operation.
type PolicyProviderError ¶ added in v0.80.0
type PolicyProviderError struct{ Err error }
PolicyProviderError is a fail-closed dynamic policy snapshot failure.
func (*PolicyProviderError) Error ¶ added in v0.80.0
func (e *PolicyProviderError) Error() string
func (*PolicyProviderError) Is ¶ added in v0.80.0
func (e *PolicyProviderError) Is(target error) bool
Is reports whether target is ErrAccessDenied.
func (*PolicyProviderError) Unwrap ¶ added in v0.80.0
func (e *PolicyProviderError) Unwrap() error
type PolicyVisibility ¶ added in v0.80.0
type PolicyVisibility string
PolicyVisibility is the owner visibility of a policy, public or private.
const ( // PolicyVisibilityPublic is public owner visibility. PolicyVisibilityPublic PolicyVisibility = "public" // PolicyVisibilityPrivate is private owner visibility. PolicyVisibilityPrivate PolicyVisibility = "private" )
type Principal ¶ added in v0.78.0
type Principal struct {
Subject *PrincipalRef
Actor *PrincipalRef
ID any // legacy untyped user identity, used only when Subject is nil
Roles []string
Groups []string
MembershipRevision string
}
Principal identifies the caller for principal bindings and for the $currentUser, $principal.roles and $principal.groups variables. Roles and groups are opaque strings the host assigns; DALgo never looks them up.
func NewPrincipal ¶ added in v0.80.0
func NewPrincipal(subject PrincipalRef, roles, groups []string) (Principal, error)
NewPrincipal validates subject and returns a principal holding a copy of it together with copies of roles and groups.
type PrincipalKind ¶ added in v0.80.0
type PrincipalKind string
PrincipalKind classifies a typed principal as a user, service, application, or agent.
const ( // PrincipalKindUser is a user principal. PrincipalKindUser PrincipalKind = "user" // PrincipalKindService is a service principal. PrincipalKindService PrincipalKind = "service" // PrincipalKindApplication is an application principal. PrincipalKindApplication PrincipalKind = "application" // PrincipalKindAgent is an agent principal. PrincipalKindAgent PrincipalKind = "agent" )
type PrincipalPolicySet ¶ added in v0.78.0
type PrincipalPolicySet struct {
// contains filtered or unexported fields
}
PrincipalPolicySet is a Policy that derives the caller's authority from who they are: the rule sets bound to the principal's ID, roles and groups (plus Everyone) are unioned and compiled as one AccessPolicy, so the parent feature's precedence resolves overlaps between bindings; that single policy then takes part in the ordinary intersection with database and context policies, so a binding can never widen what another policy denies.
func DecodePrincipalPolicySet ¶ added in v0.78.0
func DecodePrincipalPolicySet(reader io.Reader, codec Codec, options ...DecodeOption) (*PrincipalPolicySet, error)
DecodePrincipalPolicySet decodes and validates one AccessPolicy document that binds named rule sets to roles, groups, users and everyone.
func MustPrincipalPolicySet ¶ added in v0.78.0
func MustPrincipalPolicySet(name string, ruleSets map[string][]Rule, bindings Bindings) *PrincipalPolicySet
MustPrincipalPolicySet constructs a set and panics when it is invalid.
func NewPrincipalPolicySet ¶ added in v0.78.0
func NewPrincipalPolicySet(name string, ruleSets map[string][]Rule, bindings Bindings) (*PrincipalPolicySet, error)
NewPrincipalPolicySet validates that every binding names an existing rule set and that every rule set compiles on its own.
func NewPrincipalPolicySetForRealm ¶ added in v0.80.0
func NewPrincipalPolicySetForRealm(realm, name string, ruleSets map[string][]Rule, bindings Bindings) (*PrincipalPolicySet, error)
NewPrincipalPolicySetForRealm binds application-owned rule sets to typed principals in realm using the existing user/role/group composition rules.
func UnmarshalPrincipalPolicySetJSON ¶ added in v0.78.0
func UnmarshalPrincipalPolicySetJSON(data []byte, options ...DecodeOption) (*PrincipalPolicySet, error)
UnmarshalPrincipalPolicySetJSON decodes a principal policy set by delegating to DecodePrincipalPolicySet with JSONCodec.
func UnmarshalPrincipalPolicySetYAML ¶ added in v0.78.0
func UnmarshalPrincipalPolicySetYAML(data []byte, options ...DecodeOption) (*PrincipalPolicySet, error)
UnmarshalPrincipalPolicySetYAML decodes a principal policy set by delegating to DecodePrincipalPolicySet with YAMLCodec.
func (*PrincipalPolicySet) Authorize ¶ added in v0.78.0
func (p *PrincipalPolicySet) Authorize(ctx context.Context, request Request) error
Authorize returns nil when Decide allows the request and a DeniedError otherwise.
func (*PrincipalPolicySet) Decide ¶ added in v0.78.0
func (p *PrincipalPolicySet) Decide(ctx context.Context, request Request) Decision
Decide unions the rule sets bound to the principal on ctx and evaluates the request against them as one policy. Without any applicable binding the request is denied.
func (*PrincipalPolicySet) InspectionPure ¶ added in v0.80.0
func (*PrincipalPolicySet) InspectionPure() bool
InspectionPure reports that the policy set is safe for plan and inspection evaluation.
func (*PrincipalPolicySet) Name ¶ added in v0.78.0
func (p *PrincipalPolicySet) Name() string
Name returns the policy set name.
func (*PrincipalPolicySet) PolicyMetadata ¶ added in v0.80.0
func (p *PrincipalPolicySet) PolicyMetadata() PolicyMetadata
PolicyMetadata returns owner metadata, using private visibility when none is set.
func (*PrincipalPolicySet) Source ¶ added in v0.78.0
func (p *PrincipalPolicySet) Source() string
Source returns the storage-neutral reference supplied while loading the document, if any.
type PrincipalRef ¶ added in v0.80.0
type PrincipalRef struct {
Realm string `json:"realm" yaml:"realm"`
Kind PrincipalKind `json:"kind" yaml:"kind"`
ID string `json:"id" yaml:"id"`
}
PrincipalRef is a stable identity in an owner-configured realm.
func (PrincipalRef) Validate ¶ added in v0.80.0
func (reference PrincipalRef) Validate() error
Validate checks that the realm and id are canonical strings of at most 256 bytes and that the kind is one of the known principal kinds.
type ProtectedEvidence ¶ added in v0.80.0
type ProtectedEvidence struct {
OperationID, CanonicalTarget, SnapshotToken, DataRevision, CandidateRevision string
Exists, Complete bool
PreImage, CandidateImage map[string]any
PreparationError error
}
ProtectedEvidence is private storage evidence supplied only inside the trusted storage callback. PreparationError represents a row-dependent failure to construct complete evidence. Its cause remains private and the item must carry no images, revisions, or existence fact. ProtectedEvidence must never be copied into Assessment.
type ProtectedExecutionStorage ¶ added in v0.80.0
type ProtectedExecutionStorage interface {
ProtectedInspectionStorage
// Execute performs the protected writes.
Execute(context.Context) error
}
ProtectedExecutionStorage is a ProtectedInspectionStorage that can also perform the protected writes.
type ProtectedInspectionStorage ¶ added in v0.80.0
type ProtectedInspectionStorage interface {
// Evidence returns private storage evidence for the protected operations.
Evidence(context.Context) ([]ProtectedEvidence, error)
}
ProtectedInspectionStorage supplies private evidence inside a trusted inspection callback.
type ProtectedOperation ¶ added in v0.80.0
type ProtectedOperation struct {
// contains filtered or unexported fields
}
ProtectedOperation is a normalized immutable point operation passed to a trusted storage boundary. Construct it with the functions below.
func NewProtectedDelete ¶ added in v0.80.0
NewProtectedDelete builds a protected delete at key. revision is the expected data revision and may be empty.
func NewProtectedEvidenceRead ¶ added in v0.80.0
func NewProtectedEvidenceRead(id string, action Operations, key *record.Key, fields [][]string) (ProtectedOperation, error)
NewProtectedEvidenceRead builds a protected get that records the field paths to return as evidence. The action must be get, and fields must contain between 1 and 32 non-empty paths.
func NewProtectedInsert ¶ added in v0.80.0
func NewProtectedInsert(id string, key *record.Key, data map[string]any) (ProtectedOperation, error)
NewProtectedInsert builds a protected insert of data at key.
func NewProtectedRead ¶ added in v0.80.0
func NewProtectedRead(id string, action Operations, key *record.Key) (ProtectedOperation, error)
NewProtectedRead builds a protected get or exists operation. Any other action is rejected.
func NewProtectedSet ¶ added in v0.80.0
func NewProtectedSet(id string, key *record.Key, data map[string]any, revision string) (ProtectedOperation, error)
NewProtectedSet builds a protected set of data at key. revision is the expected data revision and may be empty.
func NewProtectedUpdate ¶ added in v0.80.0
func NewProtectedUpdate(id string, key *record.Key, updates []update.Update, revision string) (ProtectedOperation, error)
NewProtectedUpdate builds a protected update. Each update is normalized to a field path, and a value equal to update.DeleteField is recorded as a deletion. revision is the expected data revision and may be empty.
func (ProtectedOperation) Action ¶ added in v0.80.0
func (o ProtectedOperation) Action() Operations
Action returns the leaf operation.
func (ProtectedOperation) CanonicalTarget ¶ added in v0.80.0
func (o ProtectedOperation) CanonicalTarget() string
CanonicalTarget returns the key text captured when the operation was built.
func (ProtectedOperation) Columns ¶ added in v0.80.0
func (o ProtectedOperation) Columns() [][]string
Columns returns a clone of the evidence field paths.
func (ProtectedOperation) Data ¶ added in v0.80.0
func (o ProtectedOperation) Data() map[string]any
Data returns a clone of the operation data.
func (ProtectedOperation) ID ¶ added in v0.80.0
func (o ProtectedOperation) ID() string
ID returns the operation id.
func (ProtectedOperation) IfDataRevision ¶ added in v0.80.0
func (o ProtectedOperation) IfDataRevision() string
IfDataRevision returns the expected data revision, or an empty string when none was set.
func (ProtectedOperation) Key ¶ added in v0.80.0
func (o ProtectedOperation) Key() *record.Key
Key returns a clone of the record key.
func (ProtectedOperation) Updates ¶ added in v0.80.0
func (o ProtectedOperation) Updates() []ProtectedUpdate
Updates returns a clone of the normalized updates.
type ProtectedStorage ¶ added in v0.80.0
type ProtectedStorage interface {
// WithinProtectedInspection runs the callback inside the trusted inspection boundary.
WithinProtectedInspection(context.Context, []ProtectedOperation, func(ProtectedInspectionStorage) error) error
// WithinProtectedExecution runs the callback inside the trusted execution boundary.
WithinProtectedExecution(context.Context, []ProtectedOperation, func(ProtectedExecutionStorage) error) error
}
ProtectedStorage runs protected inspection and execution callbacks inside a trusted storage boundary.
type ProtectedUpdate ¶ added in v0.80.0
ProtectedUpdate is one normalized field change: a path, the value, and whether the field is deleted.
type ReasonCode ¶ added in v0.80.0
type ReasonCode string
ReasonCode is a stable authorization result code. Hosts may safely project it onto the TugQL authorization wire contract without inspecting prose.
const ( // CodeAccessDenied is the reason code used when a denial does not set its own code. CodeAccessDenied ReasonCode = "ACCESS_DENIED" // CodeRuleDenied is the reason code for a matching rule that denies the request. CodeRuleDenied ReasonCode = "ACL_RULE_DENIED" // CodeNoMatch is the reason code used when no rule allows the resource. CodeNoMatch ReasonCode = "ACL_NO_MATCH" // CodeRowPredicateFailed is the reason code used when a row fails a where condition. CodeRowPredicateFailed ReasonCode = "ACL_ROW_PREDICATE_FAILED" // CodePostImageFailed is the reason code used when a written row fails a check condition. CodePostImageFailed ReasonCode = "ACL_POST_IMAGE_FAILED" // CodeColumnDenied is the reason code used when a field is outside an allow-list. CodeColumnDenied ReasonCode = "ACL_COLUMN_DENIED" // CodeEvaluationFailed is the reason code used when a required policy evaluation fails. CodeEvaluationFailed ReasonCode = "ACL_EVALUATION_FAILED" // CodeConfigurationInvalid is the reason code used when the request or policy configuration is invalid. CodeConfigurationInvalid ReasonCode = "ACL_CONFIGURATION_INVALID" CodeSourceUnavailable ReasonCode = "ACL_SOURCE_UNAVAILABLE" // CodeEnforcementUnsupported is the reason code used when a policy cannot be enforced for the operation. CodeEnforcementUnsupported ReasonCode = "ACL_ENFORCEMENT_UNSUPPORTED" // CodePrincipalUnresolved is the reason code used when a realm-bound policy has no typed principal. CodePrincipalUnresolved ReasonCode = "ACL_PRINCIPAL_UNRESOLVED" // CodeCapabilityDenied is the reason code ACL_CAPABILITY_DENIED. CodeCapabilityDenied ReasonCode = "ACL_CAPABILITY_DENIED" // CodeExecutionClassDenied is the reason code used when an execution gate denies the request's execution class. CodeExecutionClassDenied ReasonCode = "ACL_EXECUTION_CLASS_DENIED" // CodeCallableDenied is the reason code used when an execution gate denies a stored procedure in an allowed namespace. CodeCallableDenied ReasonCode = "ACL_CALLABLE_DENIED" // CodeCollectionDenied is the reason code used when a collection mask denies the resource. CodeCollectionDenied ReasonCode = "ACL_COLLECTION_DENIED" )
func (ReasonCode) IsIndeterminate ¶ added in v0.80.0
func (code ReasonCode) IsIndeterminate() bool
IsIndeterminate reports codes that represent failed or unavailable required evaluation rather than a definitive policy denial.
type Request ¶
type Request struct {
Operation Operations
Resources []Resource
// Query retains the structured or opaque query for custom policies and
// future predicate, projection, index, and cost constraints. It is nil for
// non-query operations; v1 declarative policies authorize query sources.
Query dal.Query
// Execution is trusted assessment metadata, never a caller override of Query.
Execution *ExecutionTarget
// Columns is the normalized set of fields explicitly read or touched by a
// non-query operation. Paths use one string per segment.
Columns [][]string
}
Request describes one DAL operation over one or more resources.
type Resource ¶
type Resource struct {
// contains filtered or unexported fields
}
Resource is a policy target. Construct resources through RecordResource, CollectionResource, CollectionGroup, or OpaqueQuery.
func CollectionGroup ¶
CollectionGroup returns an explicit collection-group query resource.
func CollectionResourceFor ¶
CollectionResourceFor returns the structural collection path under parent. A nil parent denotes a root collection.
func OpaqueQuery ¶
OpaqueQuery returns a query resource that cannot safely match a structural path rule. This includes non-structured queries and structured sources whose namespace is not represented by PathPattern.
func RecordResourceForKey ¶
RecordResourceForKey builds the structural path resource for key.
func ResourcesForQuery ¶ added in v0.97.0
ResourcesForQuery returns the resources analysed by DALgo for query execution. This is inspection metadata, not an authorization decision. Every returned resource still requires policy evaluation when the operation executes. An opaque entry without Table metadata represents opaque or incomplete analysis; callers must not authorize only the known subset. Qualified table resources retain DALgo's opaque kind with Table metadata; inspect both rather than treating kind alone as an unknown source. Nil queries are represented as opaque. DALgo executes no query here. Query-supplied methods are invoked and must be side-effect free; custom Go implementations are not sandboxed.
func (Resource) Table ¶ added in v0.90.0
Table returns the identity of the table the resource's source denotes, and false when the resource carries none. A source that writes a schema or a database carries one: the parts it wrote, as written. The kind and the text of the resource are the same as they are for a source that carries no identity, so a policy that does not read the identity decides as it always did. A resource built by RecordResourceForKey, CollectionResourceFor, CollectionGroup or OpaqueQuery, a collection-group source and a part of a query that cannot be read carry none. A session that resolves no name, which is every session of this version, gives none to a collection source with neither a schema nor a database, and none to a key. WithNativeTableNamespace additionally assesses internal canonical path-kind resources carrying the original table identity, without changing the original resource assessment or the public resource constructors.
type ResourceKind ¶
type ResourceKind string
ResourceKind distinguishes ordinary hierarchical paths from query resources that cannot safely match a path rule.
const ( // PathResource is a structural path resource. PathResource ResourceKind = "path" // CollectionGroupResource is a collection-group query resource. CollectionGroupResource ResourceKind = "collection-group" // OpaqueQueryResource is a query resource that cannot safely match a path rule. OpaqueQueryResource ResourceKind = "opaque-query" )
type Rule ¶
type Rule struct {
// contains filtered or unexported fields
}
Rule is a declarative policy rule. Use Allow, Deny, Audit, IgnoreAudit, Scope, Collection, Under, Root, CollectionGroupScope, OpaqueQueryScope, or TableScope.
func Allow ¶
func Allow(operations Operations, name ...string) Rule
Allow permits operations at the containing scope. The optional name appears in explanations; a deterministic name is generated when omitted.
func Audit ¶
func Audit(operations Operations, name ...string) Rule
Audit selects matching operations for an application's audit pipeline. It does not grant access and does not persist an audit record itself.
func Collection ¶
Collection adds a terminal collection segment beneath its containing scope.
func CollectionGroupScope ¶
CollectionGroupScope attaches rules to an explicit collection-group query.
func Deny ¶
func Deny(operations Operations, name ...string) Rule
Deny rejects operations at the containing scope.
func IgnoreAudit ¶
func IgnoreAudit(operations Operations, name ...string) Rule
IgnoreAudit excludes matching operations from audit selection.
func OpaqueQueryScope ¶
OpaqueQueryScope attaches rules to queries that cannot safely match a structural path, including non-structured and schema-qualified queries. It is an intentionally explicit and potentially broad capability. An access policy that holds a table rule does not consult it for a source that writes a schema; see TableScope.
func TableScope ¶ added in v0.90.0
TableScope attaches rules to one table, named by its schema, by its database, or by both. It is a top-level scope that holds directives only; the rules it holds may carry Where, Check, Fields and a field mask, as the rules of a path scope do. A condition that uses $path.x is refused, because a table scope captures nothing.
An access policy that holds a table rule decides a source that writes a schema by its table rules alone: a rule for opaque queries is not consulted for it, and a source that writes a schema which no table rule names is denied. An audit policy that holds a table rule classifies such a source by the table rule that names it, an ignore-audit rule included, and otherwise by its rule for opaque queries, as it did before it held a table rule. A policy that holds no table rule decides every source as it always did. WithNativeTableNamespace preserves this original decision and intersects it with a complete canonical path assessment: missing path grants deny and a collection-path denial can also deny. Otherwise matching table rules retain precedence, so path allow row/field clauses do not constrain a winning table rule.
func Under ¶
func Under(pattern PathPattern, rules ...Rule) Rule
Under adds an arbitrary structural path prefix beneath its containing scope.
func (Rule) Check ¶ added in v0.76.0
Check attaches a post-image condition to an allow rule: a row written under the rule must satisfy condition after the write (the new data of an Insert or Set, the updated row of an Update). A rule with Where but no Check uses Where as its check, so "rows where ownerID == $currentUser" also means "and they must still be mine afterwards". A rule with Check but no Where applies to every row on read and constrains only what a write may produce.
func (Rule) Fields ¶ added in v0.79.0
Fields attaches an allow-list of field patterns to an allow rule: reads return only matching fields (a query is projected and its records redacted) and writes may only set or touch matching fields. Patterns are dotted paths whose segments are literal names, `*`, `prefix*` or `*suffix`; a trailing `.*` covers a whole subtree; an allowed parent covers its children. A rule without Fields means every field.
func (Rule) Where ¶ added in v0.75.0
Where attaches a row condition to an allow rule: the rule applies only to records whose values satisfy condition. The condition is a dal.Condition over the record's fields (comparisons, In, And/Or groups) whose right-hand values may be parameters such as dal.NewParam("currentUser"), resolved from the operation context (see WithVariables and WithCurrentUser).
Conditions are valid on allow rules under path scopes and table scopes only. A conditional rule never authorises Truncate: naming it explicitly fails compilation, while the write and readwrite groups simply drop it.
func (Rule) WithFieldMask ¶ added in v0.80.0
WithFieldMask applies a portable scoped mask. Fields and masks are mutually exclusive; NewPolicy validates the complete declaration.
type TableName ¶ added in v0.90.0
type TableName struct {
Database string `json:"database,omitempty" yaml:"database,omitempty"`
Schema string `json:"schema,omitempty" yaml:"schema,omitempty"`
Name string `json:"name" yaml:"name"`
}
TableName says which stored table a source denotes: the database, the schema and the name of the table, each as the policy author wrote it, with no SQL quoting. A rule that names a table through TableScope, or through the table key of a policy document, writes one. The identity of the table a query source denotes is read from a resource with Resource.Table.
Name is required. A table rule names a schema, a database, or both; a table with neither is an ordinary collection, which Collection and a path scope name. A name is a plain name: a dot inside it is part of the name, so the schema "a" and the name "b.c" are not the schema "a.b" and the name "c".
type TugQLDocument ¶ added in v0.94.0
type TugQLDocument struct {
APIVersion string `json:"apiVersion" yaml:"apiVersion"`
Kind string `json:"kind" yaml:"kind"`
Metadata TugQLMetadata `json:"metadata" yaml:"metadata"`
Target TugQLTarget `json:"target" yaml:"target"`
Composition string `json:"composition" yaml:"composition"`
Default string `json:"default" yaml:"default"`
Scopes []TugQLScope `json:"scopes,omitempty" yaml:"scopes,omitempty"`
RuleSets map[string][]TugQLScope `json:"ruleSets,omitempty" yaml:"ruleSets,omitempty"`
Bindings *DocumentBindings `json:"bindings,omitempty" yaml:"bindings,omitempty"`
Execution *ExecutionGate `json:"execution,omitempty" yaml:"execution,omitempty"`
CollectionMask *Mask `json:"collectionMask,omitempty" yaml:"collectionMask,omitempty"`
}
TugQLDocument is a portable TugQL policy document.
func NormalizeTugQLPolicy ¶ added in v0.94.0
func NormalizeTugQLPolicy(document TugQLDocument) (TugQLDocument, error)
NormalizeTugQLPolicy returns a validated deep copy with canonical scoped masks. It preserves policy/rule identity and stage action-change order.
func ParseTugQLPolicy ¶ added in v0.94.0
func ParseTugQLPolicy(data []byte) (TugQLDocument, error)
ParseTugQLPolicy validates a portable editable document. JSON is accepted as the JSON subset of YAML. Parsing does not activate policy or authorize data.
type TugQLMetadata ¶ added in v0.95.2
type TugQLMetadata struct {
Name string `json:"name" yaml:"name"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Visibility string `json:"visibility,omitempty" yaml:"visibility,omitempty"`
}
TugQLMetadata holds the name, description, and visibility of a TugQL document.
type TugQLRule ¶ added in v0.95.2
type TugQLRule struct {
ID string `json:"id" yaml:"id"`
Effect string `json:"effect" yaml:"effect"`
Operations []string `json:"operations" yaml:"operations"`
Where *DocumentCondition `json:"where,omitempty" yaml:"where,omitempty"`
Check *DocumentCondition `json:"check,omitempty" yaml:"check,omitempty"`
Fields []string `json:"fields,omitempty" yaml:"fields,omitempty"`
FieldMask *Mask `json:"fieldMask,omitempty" yaml:"fieldMask,omitempty"`
}
TugQLRule is one rule in a TugQL scope, including an optional field mask.
type TugQLScope ¶ added in v0.95.2
type TugQLScope struct {
Path string `json:"path,omitempty" yaml:"path,omitempty"`
CollectionGroup string `json:"collectionGroup,omitempty" yaml:"collectionGroup,omitempty"`
OpaqueQuery bool `json:"opaqueQuery,omitempty" yaml:"opaqueQuery,omitempty"`
Rules []TugQLRule `json:"rules,omitempty" yaml:"rules,omitempty"`
Scopes []TugQLScope `json:"scopes,omitempty" yaml:"scopes,omitempty"`
CollectionMask *Mask `json:"collectionMask,omitempty" yaml:"collectionMask,omitempty"`
}
TugQLScope selects one resource in a TugQL document and holds its rules and nested scopes.
type TugQLTarget ¶ added in v0.95.2
type TugQLTarget struct {
Database string `json:"database" yaml:"database"`
}
TugQLTarget names the database a TugQL document applies to.
type WriteAlternative ¶ added in v0.76.0
type WriteAlternative struct {
Rule string
Where dal.Condition
Check dal.Condition
WhereText string
CheckText string
// Fields is the rule's allow-list of field patterns; nil means every field.
Fields []string
WhereDocument *DocumentCondition
CheckDocument *DocumentCondition
// contains filtered or unexported fields
}
WriteAlternative is one allow rule as it applies to a write. Where selects the rows (by pre-image) the rule applies to; nil means every row. Check is what the row must satisfy after the write; nil means no constraint. Both are resolved conditions; the Text fields keep the source form with parameter names for explanations.
type WriteResidual ¶ added in v0.76.0
type WriteResidual struct {
Alternatives []WriteAlternative
Terminal *WriteAlternative
}
WriteResidual is what the secured wrapper enforces on a write: the conditional alternatives in precedence order, then Terminal — the first unconditional rule when it is an allow (possibly with a Check) — or nil when the walk ends in a deny or in no rule at all. The first alternative whose Where holds on the pre-image decides the write; a new row (Insert, or Set of a missing row) is admitted by the first alternative whose Check it satisfies.
Source Files
¶
- assessment.go
- condition.go
- context.go
- context_assessment.go
- coordinator.go
- database.go
- doc.go
- document.go
- document_condition.go
- execution.go
- fields.go
- file_policy.go
- mask.go
- native_table_namespace.go
- nesting.go
- operation.go
- policy.go
- portable.go
- principal.go
- query_fields.go
- query_join_fields.go
- query_sources.go
- resource.go
- rule.go
- session.go
- table.go
- write.go