Documentation ¶
Overview ¶
Example ¶
AnyOf tests
package main import ( ctx "context" "fmt" "log/slog" attrs "github.com/virtru/access-pdp/attributes" accesspdp "github.com/virtru/access-pdp/pdp" ) func main() { entityID := "4f6636ca-c60c-40d1-9f3f-015086303f74" attrAuthorities := []string{"https://example.org"} AttrDefinitions := []attrs.AttributeDefinition{ { Authority: attrAuthorities[0], Name: "MyAttr", Rule: "anyOf", Order: []string{"Value1", "Value2"}, }, } DataAttrs := []attrs.AttributeInstance{ { Authority: attrAuthorities[0], Name: AttrDefinitions[0].Name, Value: AttrDefinitions[0].Order[1], }, { Authority: attrAuthorities[0], Name: AttrDefinitions[0].Name, Value: AttrDefinitions[0].Order[0], }, { Authority: attrAuthorities[0], Name: AttrDefinitions[0].Name, Value: "NegativeTypoValue", }, } EntityAttrs := map[string][]attrs.AttributeInstance{ entityID: { { Authority: "https://example.org", Name: "MyAttr", Value: "Value2", }, { Authority: "https://meep.org", Name: "meep", Value: "beepbeep", }, }, } slog.Default().Handler().Enabled(ctx.Background(), slog.LevelInfo) accessPDP := accesspdp.NewAccessPDPWithSlog(slog.Default()) context := ctx.Background() decisions, err := accessPDP.DetermineAccess(DataAttrs, EntityAttrs, AttrDefinitions, &context) if err != nil { slog.Error("Could not generate a decision!") } fmt.Printf("Decision result: %+v", decisions) }
Output:
Index ¶
Examples ¶
Constants ¶
const ALL_OF string = "allOf"
const ANY_OF string = "anyOf"
const HIERARCHY string = "hierarchy"
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccessPDP ¶
type AccessPDP struct {
// contains filtered or unexported fields
}
func NewAccessPDP ¶
func NewAccessPDP(logger *zap.SugaredLogger) *AccessPDP
NewAccessPDP uses https://github.com/uber-go/zap for structured logging
func NewAccessPDPWithSlog ¶ added in v1.6.0
func (*AccessPDP) DetermineAccess ¶
func (pdp *AccessPDP) DetermineAccess(dataAttributes []attrs.AttributeInstance, entityAttributeSets map[string][]attrs.AttributeInstance, attributeDefinitions []attrs.AttributeDefinition, context *ctx.Context) (map[string]*Decision, error)
DetermineAccess will take data AttributeInstances, data AttributeDefinitions, and entity AttributeInstance sets, and compare every data AttributeInstance against every entity's AttributeInstance set, generating a rolled-up decision result for each entity, as well as a detailed breakdown of every data AttributeInstance comparison.
type DataRuleResult ¶
type DataRuleResult struct { //Indicates whether, for this specific data AttributeDefinition, an entity satisfied //the rule conditions (allof/anyof/hierarchy) Passed bool `json:"passed" example:"false"` //Contains the AttributeDefinition of the data attribute rule this result represents RuleDefinition *attrs.AttributeDefinition `json:"rule_definition"` //May contain 0 or more ValueFailure types, depending on the RuleDefinition and which (if any) //data AttributeInstances/values the entity failed against // //For an AllOf rule, there should be no value failures if Passed=TRUE //For an AnyOf rule, there should be fewer entity value failures than //there are data attribute values in total if Passed=TRUE //For a Hierarchy rule, there should be either no value failures if Passed=TRUE, //or exactly one value failure if Passed=FALSE ValueFailures []ValueFailure `json:"value_failures"` }
DataRuleResult represents the rule-level (or AttributeDefinition-level) decision for a specific entity - the result of comparing entity AttributeInstances to a single data AttributeDefinition/rule (with potentially many values)
There may be multiple "instances" (that is, AttributeInstances) of a single AttributeDefinition on both data and entities, each with a different value.
type Decision ¶
type Decision struct { //The important bit - does this entity Have Access or not, for this set of data attribute values //This will be TRUE if, for *every* DataRuleResult in Results, EntityRuleResult.Passed == TRUE //Otherwise, it will be false Access bool `json:"access" example:"false"` //Results will contain at most 1 DataRuleResult for each data AttributeInstance. //e.g. if we compare an entity's AttributeInstances against 5 data AttributeInstances, //then there will be 5 rule results, each indicating whether this entity "passed" validation //for that data AttributeInstance or not. // //If an entity was skipped for a particular rule evaluation because of a GroupBy clause //on the AttributeDefinition for a given data AttributeInstance, however, then there may be // FEWER DataRuleResults then there are DataRules // //e.g. there are 5 data AttributeInstances, and two entities each with a set of AttributeInstances, //the definition for one of those data AttributeInstances has a GroupBy clause that excludes the second entity //-> the first entity will have 5 DataRuleResults with Passed = true //-> the second entity will have 4 DataRuleResults Passed = true //-> both will have Access == true. Results []DataRuleResult `json:"entity_rule_result"` }
A Decision represents the overall access decision for a specific entity, - that is, the aggregate result of comparing entity AttributeInstances to every data AttributeInstance.
type ValueFailure ¶
type ValueFailure struct { //The data attribute w/value that "caused" the denial DataAttribute *attrs.AttributeInstance `json:"data_attribute"` //Optional denial message Message string `json:"message" example:"Criteria NOT satisfied for entity: {entity_id} - lacked attribute value: {attribute}"` }
ValueFailure indicates, for a given entity and data AttributeInstance, which data values (aka specific data AttributeInstance) the entity "failed" on.
There may be multiple "instances" (that is, AttributeInstances) of a single AttributeDefinition on both data and entities, each with a different value.
A ValueFailure does not necessarily mean the requirements for an AttributeDefinition were not or will not be met, it is purely informational - there will be one value failure, per entity, per rule, per value the entity lacks - it is up to the rule itself (anyof/allof/hierarchy) to translate this into an overall failure or not.