accesspdp

package module
v2.0.0-...-e047130 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2022 License: MIT Imports: 5 Imported by: 0

README

ABAC Access Policy Decision Point

A reference implementation of an Attribute Based Access Control (ABAC) Access Policy Decision Point (PDP)

What's an Access PDP, and how does it fit into an ABAC system?

ABAC System

  • A Access PDP (Policy Decision Point) is a library or service that makes Access decisions. It is usually "wrapped" or used by an Access Policy Enforcement Point (PEP), which enforces whatever decision this Access PDP makes.
  • This library is not an Access PEP - it is a domain-agnostic Access PDP, which domain-specific Access PEPs may consume.

Details

In this implementation, the Access PDP:

Expects to be provided with:
  • The Data Attributes to make a decision against
  • Attribute Definitions for every Data Attribute the decision is being made against
  • A list of Entities the decision is being made against, and entitlements (Entity Attributes) for each Entity

as decision input.

To the Access PDP, an "entity" is just a string identifier of any kind with entity attributes attached to it - this PDP doesn't care about entity subtypes (PE, NPE) or what kind of entity identifiers are being used, and "entities" have no meaning to the PDP except as a way to group decision results - they are simply there so the PEP invoking this library can correlate PDP requests with PDP results.

Returns:

For each entity identifer provided: 1. A single, top-level boolean Access property indicating the overall access decision for that entity against the complete set of provided Data Attributes, according to the rules of the Data Attribute Definitions those map to (any-of, all-of, hierarchy). 2. A set of DataRuleResults for each Data Attribute comparison that was done, which contributed to the top-level Access property of true or false.

Important design decisions/constraints for this library
  • Design decision -> Entity identifiers and "entity types" only have meaning to the caller of the PDP, not the PDP itself.
  • Design decision -> This PDP may not make outbound requests or consult outside sources for decision inputs - it must be provided everything necessary to make a decision (Entity Attributes, Data Attributes, Attribute Definitions for the Data Attributes) by its caller, usually an Access PEP
  • Design decision -> The logic of this PDP must be fixed, boolean and domain-agnostic - deciding how to interpret and apply the decisions this Access PDP generates is the job of an Access PEP, which is typically domain-specific, and which would typically wrap this Access PDP.
  • Design decision -> This PDP must be embeddable into PEPs as in-process code (library/local gRPC) or out-of-process code (separate container/remote gRPC)

Interface

This library exposes gRPC endpoints, and so can be consumed by any code that understands the gRPC protocol. This library could be wrapped in a container and hosted out-of-process from an Access PEP, or it could be hosted in-process.

Documentation

Index

Constants

View Source
const ALL_OF string = "allOf"
View Source
const ANY_OF string = "anyOf"
View Source
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

func (*AccessPDP) AllOfRule

func (pdp *AccessPDP) AllOfRule(dataAttrsBySingleCanonicalName []attrs.AttributeInstance, entityAttributes map[string][]attrs.AttributeInstance, groupBy *attrs.AttributeInstance) map[string]DataRuleResult

AllOf the Data Attribute CanonicalName+Value pairs should be present in AllOf the Entity's Attribute sets Accepts - a set of data attribute instances with the same canonical name - a map of entity attribute instances keyed by entity ID Returns a map of DataRuleResults keyed by EntityID

func (*AccessPDP) AnyOfRule

func (pdp *AccessPDP) AnyOfRule(dataAttrsBySingleCanonicalName []attrs.AttributeInstance, entityAttributes map[string][]attrs.AttributeInstance, groupBy *attrs.AttributeInstance) map[string]DataRuleResult

AnyOf the Data Attribute CanonicalName+Value pairs can be present in AnyOf the Entity's Attribute sets Accepts - a set of data attribute instances with the same canonical name - a map of entity attribute instances keyed by entity ID Returns a map of DataRuleResults keyed by EntityID

func (*AccessPDP) DetermineAccess

func (pdp *AccessPDP) DetermineAccess(dataAttributes []attrs.AttributeInstance, entityAttributeSets map[string][]attrs.AttributeInstance, attributeDefinitions []attrs.AttributeDefinition, parentCtx ctx.Context) (map[string]*Decision, error)

func (*AccessPDP) GroupByFilterEntityAttributeInstances

func (pdp *AccessPDP) GroupByFilterEntityAttributeInstances(entityAttributes map[string][]attrs.AttributeInstance, groupBy *attrs.AttributeInstance) map[string][]attrs.AttributeInstance

the purpose of a GroupBy attribute is to indicate which entities should be included in a rule evaluation, and which entities should not be included. This function will check every entity's AttributeInstances, and filter out the entities that lack an instance of the GroupBy AttributeInstance, returning a new, reduced set of entities that all have the GroupBy AttributeInstance.

func (*AccessPDP) HierarchyRule

func (pdp *AccessPDP) HierarchyRule(dataAttrsBySingleCanonicalName []attrs.AttributeInstance, entityAttributes map[string][]attrs.AttributeInstance, groupBy *attrs.AttributeInstance, order []string) map[string]DataRuleResult

Hierarchy rule compares the HIGHEST (that is, numerically lowest index) data value for a given attribute canonical name with the LOWEST (that is, numerically highest index) entity value for a given attribute canonical name.

If multiple data values for a hierarchy attribute are present for the same canonical name, the highest will be chosen and the others ignored.

If multiple entity values for a hierarchy attribute are present for the same canonical name, the lowest will be chosen, and the others ignored.

type DataRuleResult

type DataRuleResult struct {
	//Indicates whether, for this specific data attribute definition/rule, 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 attribute-definition-level) decision for a specific entity - the result of comparing entity attributes to a single data attribute definition/rule (with potentially many values)

type Decision

type Decision struct {
	//The important bit - does this entity Have Access or not, for this set of Data 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 Attribute.
	//e.g. if we compare an entity's attributes against a data policy with 5 data attributes,
	//then there will be 5 rule results, each indicating whether this entity "passed" validation
	//for that data attribute or not.
	//
	//If an entity was skipped for a particular rule evaluation because of a GroupBy clause
	//on the AttributeDefinition for a data attribute, however, then there may be FEWER DataRuleResults
	//then there are DataRules
	//e.g. there are 5 data attributes, and two entities, the definition for one of those data attributes
	//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 attributes to every data attribute.

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 attribute, which data values (aka specific data AttributeInstance) the entity "failed" on. A single data attribute may be present in the data policy with one or more values. A value failure does not necessarily mean a rule failure, 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 to translate this into an overall failure or not.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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