accesspdp

package module
v0.2.10 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2022 License: BSD-3-Clause-Clear Imports: 5 Imported by: 0

README

ABAC Access Policy Decision Point

Quality Gate Go Reference

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)
Project structure
  • access-pdp.go: Actual PDP logic
  • attributes: A sub-package of access-pdp that models and defines Attribute structs (Definitions and Instances) for canonically representing and comparing ABAC attributes in URI form.

Interface

This library exposes gRPC endpoints (TODO), 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

Overview

Example

AnyOf tests

zapLog, _ := zap.NewDevelopment()

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],
	},
}
EntityAttrs := map[string][]attrs.AttributeInstance{
	entityID: {
		{
			Authority: "https://example.org",
			Name:      "MyAttr",
			Value:     "Value2",
		},
		{
			Authority: "https://meep.org",
			Name:      "meep",
			Value:     "beepbeep",
		},
	},
}
accessPDP := accesspdp.NewAccessPDP(zapLog.Sugar())

decisions, err := accessPDP.DetermineAccess(DataAttrs, EntityAttrs, AttrDefinitions, ctx.Background())
if err != nil {
	zapLog.Error("Could not generate a decision!")
}

fmt.Printf("Decision result: %+v", decisions)

Index

Examples

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

func NewAccessPDP

func NewAccessPDP(logger *zap.SugaredLogger) *accessPDP

NewAccessPDP uses https://github.com/uber-go/zap for structured logging

Types

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.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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