README

ORY Ladon - Policy-based Access Control

Join newsletter

Build Status Coverage Status Go Report Card GoDoc

Ladon is the serpent dragon protecting your resources.

Ladon is a library written in Go for access control policies, similar to Role Based Access Control or Access Control Lists. In contrast to ACL and RBAC you get fine-grained access control with the ability to answer questions in complex environments such as multi-tenant or distributed applications and large organizations. Ladon is inspired by AWS IAM Policies.

Ladon officially ships with an exemplary in-memory storage implementations. Community-supported adapters are available for CockroachDB.

Ladon is now considered stable.


ORY builds solutions for better internet security and accessibility. We have a couple more projects you might enjoy:

  • Hydra, a security-first open source OAuth2 and OpenID Connect server for new and existing infrastructures that uses Ladon for access control.
  • ORY Editor, an extensible, modern WYSI editor for the web written in React.
  • Fosite, an extensible security first OAuth 2.0 and OpenID Connect SDK for Go.
  • Dockertest: Write better integration tests with dockertest!

Table of Contents

Ladon utilizes ory-am/dockertest for tests. Please refer to ory-am/dockertest for more information of how to setup testing environment.

Installation

This library works with Go 1.11+.

export GO111MODULE=on
go get github.com/ory/ladon

Ladon uses semantic versioning and versions beginning with zero (0.1.2) might introduce backwards compatibility breaks with each minor version.

Concepts

Ladon is an access control library that answers the question:

Who is able to do what on something given some context

  • Who: An arbitrary unique subject name, for example "ken" or "printer-service.mydomain.com".
  • Able: The effect which can be either "allow" or "deny".
  • What: An arbitrary action name, for example "delete", "create" or "scoped:action:something".
  • Something: An arbitrary unique resource name, for example "something", "resources.articles.1234" or some uniform resource name like "urn:isbn:3827370191".
  • Context: The current context containing information about the environment such as the IP Address, request date, the resource owner name, the department ken is working in or any other information you want to pass along. (optional)

To decide what the answer is, Ladon uses policy documents which can be represented as JSON

{
  "description": "One policy to rule them all.",
  "subjects": ["users:<peter|ken>", "users:maria", "groups:admins"],
  "actions" : ["delete", "<create|update>"],
  "effect": "allow",
  "resources": [
    "resources:articles:<.*>",
    "resources:printer"
  ],
  "conditions": {
    "remoteIP": {
        "type": "CIDRCondition",
        "options": {
            "cidr": "192.168.0.1/16"
        }
    }
  }
}

and can answer access requests that look like:

{
  "subject": "users:peter",
  "action" : "delete",
  "resource": "resources:articles:ladon-introduction",
  "context": {
    "remoteIP": "192.168.0.5"
  }
}

However, Ladon does not come with a HTTP or server implementation. It does not restrict JSON either. We believe that it is your job to decide if you want to use Protobuf, RESTful, HTTP, AMQP, or some other protocol. It's up to you to write the server!

The following example should give you an idea what a RESTful flow could look like. Initially we create a policy by POSTing it to an artificial HTTP endpoint:

> curl \
      -X POST \
      -H "Content-Type: application/json" \
      -d@- \
      "https://my-ladon-implementation.localhost/policies" <<EOF
        {
          "description": "One policy to rule them all.",
          "subjects": ["users:<peter|ken>", "users:maria", "groups:admins"],
          "actions" : ["delete", "<create|update>"],
          "effect": "allow",
          "resources": [
            "resources:articles:<.*>",
            "resources:printer"
          ],
          "conditions": {
            "remoteIP": {
                "type": "CIDRCondition",
                "options": {
                    "cidr": "192.168.0.1/16"
                }
            }
          }
        }
  EOF

Then we test if "peter" (ip: "192.168.0.5") is allowed to "delete" the "ladon-introduction" article:

> curl \
      -X POST \
      -H "Content-Type: application/json" \
      -d@- \
      "https://my-ladon-implementation.localhost/warden" <<EOF
        {
          "subject": "users:peter",
          "action" : "delete",
          "resource": "resources:articles:ladon-introduction",
          "context": {
            "remoteIP": "192.168.0.5"
          }
        }
  EOF

{
    "allowed": true
}

Usage

We already discussed two essential parts of Ladon: policies and access control requests. Let's take a closer look at those two.

Policies

Policies are the basis for access control decisions. Think of them as a set of rules. In this library, policies are abstracted as the ladon.Policy interface, and Ladon comes with a standard implementation of this interface which is ladon.DefaultPolicy. Creating such a policy could look like:

import "github.com/ory/ladon"

var pol = &ladon.DefaultPolicy{
	// A required unique identifier. Used primarily for database retrieval.
	ID: "68819e5a-738b-41ec-b03c-b58a1b19d043",

	// A optional human readable description.
	Description: "something humanly readable",

	// A subject can be an user or a service. It is the "who" in "who is allowed to do what on something".
	// As you can see here, you can use regular expressions inside < >.
	Subjects: []string{"max", "peter", "<zac|ken>"},

	// Which resources this policy affects.
	// Again, you can put regular expressions in inside < >.
	Resources: []string{
            "myrn:some.domain.com:resource:123", "myrn:some.domain.com:resource:345",
            "myrn:something:foo:<.+>", "myrn:some.domain.com:resource:<(?!protected).*>",
            "myrn:some.domain.com:resource:<[[:digit:]]+>"
        },

	// Which actions this policy affects. Supports RegExp
	// Again, you can put regular expressions in inside < >.
	Actions: []string{"<create|delete>", "get"},

	// Should access be allowed or denied?
	// Note: If multiple policies match an access request, ladon.DenyAccess will always override ladon.AllowAccess
	// and thus deny access.
	Effect: ladon.AllowAccess,

	// Under which conditions this policy is "active".
	Conditions: ladon.Conditions{
		// In this example, the policy is only "active" when the requested subject is the owner of the resource as well.
		"resourceOwner": &ladon.EqualsSubjectCondition{},

		// Additionally, the policy will only match if the requests remote ip address matches address range 127.0.0.1/32
		"remoteIPAddress": &ladon.CIDRCondition{
			CIDR: "127.0.0.1/32",
		},
	},
}
Conditions

Conditions are functions returning true or false given a context. Because conditions implement logic, they must be programmed. Adding conditions to a policy consist of two parts, a key name and an implementation of ladon.Condition:

// StringEqualCondition is an exemplary condition.
type StringEqualCondition struct {
	Equals string `json:"equals"`
}

// Fulfills returns true if the given value is a string and is the
// same as in StringEqualCondition.Equals
func (c *StringEqualCondition) Fulfills(value interface{}, _ *ladon.Request) bool {
	s, ok := value.(string)

	return ok && s == c.Equals
}

// GetName returns the condition's name.
func (c *StringEqualCondition) GetName() string {
	return "StringEqualCondition"
}

var pol = &ladon.DefaultPolicy{
    // ...
    Conditions: ladon.Conditions{
        "some-arbitrary-key": &StringEqualCondition{
            Equals: "the-value-should-be-this"
        }
    },
}

The default implementation of Policy supports JSON un-/marshalling. In JSON, this policy would look like:

{
  "conditions": {
    "some-arbitrary-key": {
        "type": "StringEqualCondition",
        "options": {
            "equals": "the-value-should-be-this"
        }
    }
  }
}

As you can see, type is the value that StringEqualCondition.GetName() is returning and options is used to set the value of StringEqualCondition.Equals.

This condition is fulfilled by (we will cover the warden in the next section)

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
        "some-arbitrary-key": "the-value-should-be-this",
    },
}

but not by

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
        "some-arbitrary-key": "some other value",
    },
}

and neither by:

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
        "same value but other key": "the-value-should-be-this",
    },
}

Ladon ships with a couple of default conditions:

CIDR Condition

The CIDR condition matches CIDR IP Ranges. Using this condition would look like this in JSON:

{
    "conditions": {
        "remoteIPAddress": {
            "type": "CIDRCondition",
            "options": {
                "cidr": "192.168.0.1/16"
            }
        }
    }
}

and in Go:

var pol = &ladon.DefaultPolicy{
    Conditions: ladon.Conditions{
        "remoteIPAddress": &ladon.CIDRCondition{
            CIDR: "192.168.0.1/16",
        },
    },
}

In this case, we expect that the context of an access request contains a field "remoteIpAddress" matching the CIDR "192.168.0.1/16", for example "192.168.0.5".

String Equal Condition

Checks if the value passed in the access request's context is identical with the string that was given initially

var pol = &ladon.DefaultPolicy{
    Conditions: ladon.Conditions{
        "some-arbitrary-key": &ladon.StringEqualCondition{
            Equals: "the-value-should-be-this"
        }
    },
}

and would match in the following case:

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
         "some-arbitrary-key": "the-value-should-be-this",
    },
}
Boolean Condition

Checks if the boolean value passed in the access request's context is identical with the expected boolean value in the policy

var pol = &ladon.DefaultPolicy{
    Conditions: ladon.Conditions{
        "some-arbitrary-key": &ladon.BooleanCondition{
            BooleanValue: true,
        }
    },
}

and would match in the following case:

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
        "some-arbitrary-key": true,
    },
})

This condition type is particularly useful if you need to assert a policy dynamically on resources for multiple subjects. For example, consider if you wanted to enforce policy that only allows individuals that own a resource to view that resource. You'd have to be able to create a Ladon policy that permits access to every resource for every subject that enters your system.

With the Boolean Condition type, you can use conditional logic at runtime to create a match for a policy's condition.

String Match Condition

Checks if the value passed in the access request's context matches the regular expression that was given initially

var pol = &ladon.DefaultPolicy{
    Conditions: ladon.Conditions{
      "some-arbitrary-key": &ladon.StringMatchCondition{
          Matches: "regex-pattern-here.+"
      }
    }
}

and would match in the following case:

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
          "some-arbitrary-key": "regex-pattern-here111"
    }
  }
})
Subject Condition

Checks if the access request's subject is identical with the string that was given initially

var pol = &ladon.DefaultPolicy{
    Conditions: ladon.Conditions{
        "some-arbitrary-key": &ladon.EqualsSubjectCondition{}
    },
}

and would match

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Subject: "peter",
    Context: ladon.Context{
         "some-arbitrary-key": "peter",
    },
}

but not:

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Subject: "peter",
    Context: ladon.Context{
         "some-arbitrary-key": "max",
    },
}
String Pairs Equal Condition

Checks if the value passed in the access request's context contains two-element arrays and that both elements in each pair are equal.

var pol = &ladon.DefaultPolicy{
    Conditions: ladon.Conditions{
        "some-arbitrary-key": &ladon.StringPairsEqualCondition{}
    },
}

and would match

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
         "some-arbitrary-key": [
             ["some-arbitrary-pair-value", "some-arbitrary-pair-value"],
             ["some-other-arbitrary-pair-value", "some-other-arbitrary-pair-value"],
         ]
    },
}

but not:

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Context: ladon.Context{
         "some-arbitrary-key": [
             ["some-arbitrary-pair-value", "some-other-arbitrary-pair-value"],
         ]
    },
}
Resource Contains Condition

Checks if the string value passed in the access request's context is present in the resource string.

The Condition requires a value string and an optional delimiter (needs to match the resource string) to be passed.

A resource could for instance be: myrn:some.domain.com:resource:123 and myrn:some.otherdomain.com:resource:123 (the : is then considered a delimiter, and used by the condition to be able to separate the resource components from each other) to allow an action to the resources on myrn:some.otherdomain.com you could for instance create a resource condition with

{value: myrn:some.otherdomain.com, Delimiter: ":"}

alternatively:

{value: myrn:some.otherdomain.com}

The delimiter is optional but needed for the condition to be able to separate resource string components: i.e. to make sure the value foo:bar matches foo:bar but not foo:bara nor foo:bara:baz.

That is, a delimiter is necessary to separate:

{value: "myrn:fo", delimiter: ":"} from {value: "myrn:foo", delimiter: ":"} or {value: "myid:12"} from {value: "myid:123"}.

This condition is fulfilled by this (allow for all resources containing part:north):

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Resource: "rn:city:laholm:part:north"
    Context: ladon.Context{
      delimiter: ":",
      value: "part:north"
    },
}

or ( allow all resources with city:laholm)

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Resource: "rn:city:laholm:part:north"
    Context: ladon.Context{
      delimiter: ":",
      value: "city:laholm"
    },
}

but not (allow for all resources containing part:west, the resource does not contain part:west):

var err = warden.IsAllowed(&ladon.Request{
    // ...
    Resource: "rn:city:laholm:part:north"
    Context: ladon.Context{
      delimiter: ":",
      value: "part:west"
    },
}
Adding Custom Conditions

You can add custom conditions by appending it to ladon.ConditionFactories:

import "github.com/ory/ladon"

func main() {
    // ...

    ladon.ConditionFactories[new(CustomCondition).GetName()] = func() Condition {
        return new(CustomCondition)
    }

    // ...
}
Persistence

Obviously, creating such a policy is not enough. You want to persist it too. Ladon ships an interface ladon.Manager for this purpose. You have to implement that interface for persistence. An exemplary in-memory adapter can be found in ./manager/memory/manager_memory.go:

Let's take a look how to instantiate those:

In-Memory (officially supported)

import (
	"github.com/ory/ladon"
	manager "github.com/ory/ladon/manager/memory"
)


func main() {
	warden := &ladon.Ladon{
		Manager: manager.NewMemoryManager(),
	}
	err := warden.Manager.Create(pol)

    // ...
}

Access Control (Warden)

Now that we have defined our policies, we can use the warden to check if a request is valid. ladon.Ladon, which is the default implementation for the ladon.Warden interface defines ladon.Ladon.IsAllowed() which will return nil if the access request can be granted and an error otherwise.

import "github.com/ory/ladon"

func main() {
    // ...

    err := warden.IsAllowed(&ladon.Request{
        Subject: "peter",
        Action: "delete",
        Resource: "myrn:some.domain.com:resource:123",
        Context: ladon.Context{
            "ip": "127.0.0.1",
        },
    })
    if err != nil {
        log.Fatal("Access denied")
    }

    // ...
}

Audit Log (Warden)

In order to keep track of authorization grants and denials, it is possible to attach a ladon.AuditLogger. The provided ladon.AuditLoggerInfo outputs information about the policies involved when responding to authorization requests.

import "github.com/ory/ladon"
import manager "github.com/ory/ladon/manager/memory"

func main() {

    warden := ladon.Ladon{
        Manager: manager.NewMemoryManager(),
        AuditLogger: ladon.AuditLoggerInfo{}
    }

    // ...

It will output to stderr by default.

Metrics

Ability to track authorization grants,denials and errors, it is possible to implement own interface for processing metrics.

type prometheusMetrics struct{}

func (mtr *prometheusMetrics) RequestDeniedBy(r ladon.Request, p ladon.Policy) {}
func (mtr *prometheusMetrics) RequestAllowedBy(r ladon.Request, policies ladon.Policies) {}
func (mtr *prometheusMetrics) RequestNoMatch(r ladon.Request) {}
func (mtr *prometheusMetrics) RequestProcessingError(r ladon.Request, err error) {}

func main() {

    warden := ladon.Ladon{
        Manager: manager.NewMemoryManager(),
        Metric:  &prometheusMetrics{},
    }

    // ...

Limitations

Ladon's limitations are listed here.

Regular expressions

Matching regular expressions has a complexity of O(n) (except lookahead/lookbehind assertions) and databases such as MySQL or Postgres can not leverage indexes when parsing regular expressions. Thus, there is considerable overhead when using regular expressions.

We have implemented various strategies for reducing policy matching time:

  1. An LRU cache is used for caching frequently compiled regular expressions. This reduces cpu complexity significantly for memory manager implementations.
  2. The SQL schema is 3NF normalized.
  3. Policies, subjects and actions are stored uniquely, reducing the total number of rows.
  4. Only one query per look up is executed.
  5. If no regular expression is used, a simple equal match is done in SQL back-ends.

You will get the best performance with the in-memory manager. The SQL adapters perform about 1000:1 compared to the in-memory solution. Please note that these tests where in laboratory environments with Docker, without an SSD, and single-threaded. You might get better results on your system. We are thinking about introducing simple cache strategies such as LRU with a maximum age to further reduce runtime complexity.

We are also considering to offer different matching strategies (e.g. wildcard match) in the future, which will perform better with SQL databases. If you have ideas or suggestions, leave us an issue.

Examples

Check out ladon_test.go which includes a couple of policies and tests cases. You can run the code with go test -run=TestLadon -v .

Good to know

  • All checks are case sensitive because subject values could be case sensitive IDs.
  • If ladon.Ladon is not able to match a policy with the request, it will default to denying the request and return an error.

Ladon does not use reflection for matching conditions to their appropriate structs due to security considerations.

Useful commands

Create mocks

mockgen -package ladon_test -destination manager_mock_test.go github.com/ory/ladon Manager

Third Party Libraries

By implementing the warden.Manager it is possible to create your own adapters to persist data in a datastore of your choice. Below are a list of third party implementations.

Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const AllowAccess = "allow"

    AllowAccess should be used as effect for policies that allow access.

    View Source
    const DenyAccess = "deny"

      DenyAccess should be used as effect for policies that deny access.

      Variables

      View Source
      var (
      	// ErrRequestDenied is returned when an access request can not be satisfied by any policy.
      	ErrRequestDenied = &errorWithContext{
      		error:  errors.New("Request was denied by default"),
      		code:   http.StatusForbidden,
      		status: http.StatusText(http.StatusForbidden),
      		reason: "The request was denied because no matching policy was found.",
      	}
      
      	// ErrRequestForcefullyDenied is returned when an access request is explicitly denied by a policy.
      	ErrRequestForcefullyDenied = &errorWithContext{
      		error:  errors.New("Request was forcefully denied"),
      		code:   http.StatusForbidden,
      		status: http.StatusText(http.StatusForbidden),
      		reason: "The request was denied because a policy denied request.",
      	}
      
      	// ErrNotFound is returned when a resource can not be found.
      	ErrNotFound = &errorWithContext{
      		error:  errors.New("Resource could not be found"),
      		code:   http.StatusNotFound,
      		status: http.StatusText(http.StatusNotFound),
      	}
      )
      View Source
      var ConditionFactories = map[string]func() Condition{
      	new(StringEqualCondition).GetName(): func() Condition {
      		return new(StringEqualCondition)
      	},
      	new(CIDRCondition).GetName(): func() Condition {
      		return new(CIDRCondition)
      	},
      	new(EqualsSubjectCondition).GetName(): func() Condition {
      		return new(EqualsSubjectCondition)
      	},
      	new(StringPairsEqualCondition).GetName(): func() Condition {
      		return new(StringPairsEqualCondition)
      	},
      	new(StringMatchCondition).GetName(): func() Condition {
      		return new(StringMatchCondition)
      	},
      	new(ResourceContainsCondition).GetName(): func() Condition {
      		return new(ResourceContainsCondition)
      	},
      	new(BooleanCondition).GetName(): func() Condition {
      		return new(BooleanCondition)
      	},
      }

        ConditionFactories is where you can add custom conditions

        View Source
        var DefaultAuditLogger = &AuditLoggerNoOp{}
        View Source
        var DefaultMatcher = NewRegexpMatcher(512)
        View Source
        var DefaultMetric = &MetricNoOp{}

        Functions

        func NewErrResourceNotFound

        func NewErrResourceNotFound(err error) error

        Types

        type AuditLogger

        type AuditLogger interface {
        	LogRejectedAccessRequest(request *Request, pool Policies, deciders Policies)
        	LogGrantedAccessRequest(request *Request, pool Policies, deciders Policies)
        }

          AuditLogger tracks denied and granted authorizations.

          type AuditLoggerInfo

          type AuditLoggerInfo struct {
          	Logger *log.Logger
          }

            AuditLoggerInfo outputs information about granting or rejecting policies.

            func (*AuditLoggerInfo) LogGrantedAccessRequest

            func (a *AuditLoggerInfo) LogGrantedAccessRequest(r *Request, p Policies, d Policies)

            func (*AuditLoggerInfo) LogRejectedAccessRequest

            func (a *AuditLoggerInfo) LogRejectedAccessRequest(r *Request, p Policies, d Policies)

            type AuditLoggerNoOp

            type AuditLoggerNoOp struct{}

              AuditLoggerNoOp is the default AuditLogger, that tracks nothing.

              func (*AuditLoggerNoOp) LogGrantedAccessRequest

              func (*AuditLoggerNoOp) LogGrantedAccessRequest(r *Request, p Policies, d Policies)

              func (*AuditLoggerNoOp) LogRejectedAccessRequest

              func (*AuditLoggerNoOp) LogRejectedAccessRequest(r *Request, p Policies, d Policies)

              type BooleanCondition

              type BooleanCondition struct {
              	BooleanValue bool `json:"value"`
              }

                BooleanCondition is used to determine if a boolean context matches an expected boolean condition.

                BooleanCondition implements the ladon.Condition interface. See https://github.com/ory/ladon/blob/master/condition.go

                func (*BooleanCondition) Fulfills

                func (c *BooleanCondition) Fulfills(value interface{}, _ *Request) bool

                  Fulfills determines if the BooleanCondition is fulfilled. The BooleanCondition is fulfilled if the provided boolean value matches the conditions boolean value.

                  func (*BooleanCondition) GetName

                  func (c *BooleanCondition) GetName() string

                    GetName returns the name of the BooleanCondition

                    type CIDRCondition

                    type CIDRCondition struct {
                    	CIDR string `json:"cidr"`
                    }

                      CIDRCondition makes sure that the warden requests' IP address is in the given CIDR.

                      func (*CIDRCondition) Fulfills

                      func (c *CIDRCondition) Fulfills(value interface{}, _ *Request) bool

                        Fulfills returns true if the the request is fulfilled by the condition.

                        func (*CIDRCondition) GetName

                        func (c *CIDRCondition) GetName() string

                          GetName returns the condition's name.

                          type Condition

                          type Condition interface {
                          	// GetName returns the condition's name.
                          	GetName() string
                          
                          	// Fulfills returns true if the request is fulfilled by the condition.
                          	Fulfills(interface{}, *Request) bool
                          }

                            Condition either do or do not fulfill an access request.

                            type Conditions

                            type Conditions map[string]Condition

                              Conditions is a collection of conditions.

                              func (Conditions) AddCondition

                              func (cs Conditions) AddCondition(key string, c Condition)

                                AddCondition adds a condition to the collection.

                                func (Conditions) MarshalJSON

                                func (cs Conditions) MarshalJSON() ([]byte, error)

                                  MarshalJSON marshals a list of conditions to json.

                                  func (Conditions) UnmarshalJSON

                                  func (cs Conditions) UnmarshalJSON(data []byte) error

                                    UnmarshalJSON unmarshals a list of conditions from json.

                                    type Context

                                    type Context map[string]interface{}

                                      Context is used as request's context.

                                      type DefaultPolicy

                                      type DefaultPolicy struct {
                                      	ID          string     `json:"id" gorethink:"id"`
                                      	Description string     `json:"description" gorethink:"description"`
                                      	Subjects    []string   `json:"subjects" gorethink:"subjects"`
                                      	Effect      string     `json:"effect" gorethink:"effect"`
                                      	Resources   []string   `json:"resources" gorethink:"resources"`
                                      	Actions     []string   `json:"actions" gorethink:"actions"`
                                      	Conditions  Conditions `json:"conditions" gorethink:"conditions"`
                                      	Meta        []byte     `json:"meta" gorethink:"meta"`
                                      }

                                        DefaultPolicy is the default implementation of the policy interface.

                                        func (*DefaultPolicy) AllowAccess

                                        func (p *DefaultPolicy) AllowAccess() bool

                                          AllowAccess returns true if the policy effect is allow, otherwise false.

                                          func (*DefaultPolicy) GetActions

                                          func (p *DefaultPolicy) GetActions() []string

                                            GetActions returns the policies actions.

                                            func (*DefaultPolicy) GetConditions

                                            func (p *DefaultPolicy) GetConditions() Conditions

                                              GetConditions returns the policies conditions.

                                              func (*DefaultPolicy) GetDescription

                                              func (p *DefaultPolicy) GetDescription() string

                                                GetDescription returns the policies description.

                                                func (*DefaultPolicy) GetEffect

                                                func (p *DefaultPolicy) GetEffect() string

                                                  GetEffect returns the policies effect which might be 'allow' or 'deny'.

                                                  func (*DefaultPolicy) GetEndDelimiter

                                                  func (p *DefaultPolicy) GetEndDelimiter() byte

                                                    GetEndDelimiter returns the delimiter which identifies the end of a regular expression.

                                                    func (*DefaultPolicy) GetID

                                                    func (p *DefaultPolicy) GetID() string

                                                      GetID returns the policies id.

                                                      func (*DefaultPolicy) GetMeta

                                                      func (p *DefaultPolicy) GetMeta() []byte

                                                        GetMeta returns the policies arbitrary metadata set by the user.

                                                        func (*DefaultPolicy) GetResources

                                                        func (p *DefaultPolicy) GetResources() []string

                                                          GetResources returns the policies resources.

                                                          func (*DefaultPolicy) GetStartDelimiter

                                                          func (p *DefaultPolicy) GetStartDelimiter() byte

                                                            GetStartDelimiter returns the delimiter which identifies the beginning of a regular expression.

                                                            func (*DefaultPolicy) GetSubjects

                                                            func (p *DefaultPolicy) GetSubjects() []string

                                                              GetSubjects returns the policies subjects.

                                                              func (*DefaultPolicy) UnmarshalJSON

                                                              func (p *DefaultPolicy) UnmarshalJSON(data []byte) error

                                                                UnmarshalJSON overwrite own policy with values of the given in policy in JSON format

                                                                func (*DefaultPolicy) UnmarshalMeta

                                                                func (p *DefaultPolicy) UnmarshalMeta(v interface{}) error

                                                                  UnmarshalMeta parses the policies []byte encoded metadata and stores the result in the value pointed to by v.

                                                                  type EqualsSubjectCondition

                                                                  type EqualsSubjectCondition struct{}

                                                                    EqualsSubjectCondition is a condition which is fulfilled if the request's subject is equal to the given value string

                                                                    func (*EqualsSubjectCondition) Fulfills

                                                                    func (c *EqualsSubjectCondition) Fulfills(value interface{}, r *Request) bool

                                                                      Fulfills returns true if the request's subject is equal to the given value string

                                                                      func (*EqualsSubjectCondition) GetName

                                                                      func (c *EqualsSubjectCondition) GetName() string

                                                                        GetName returns the condition's name.

                                                                        type Ladon

                                                                        type Ladon struct {
                                                                        	Manager     Manager
                                                                        	Matcher     matcher
                                                                        	AuditLogger AuditLogger
                                                                        	Metric      Metric
                                                                        }

                                                                          Ladon is an implementation of Warden.

                                                                          func (*Ladon) DoPoliciesAllow

                                                                          func (l *Ladon) DoPoliciesAllow(r *Request, policies []Policy) (err error)

                                                                            DoPoliciesAllow returns nil if subject s has permission p on resource r with context c for a given policy list or an error otherwise. The IsAllowed interface should be preferred since it uses the manager directly. This is a lower level interface for when you don't want to use the ladon manager.

                                                                            func (*Ladon) IsAllowed

                                                                            func (l *Ladon) IsAllowed(r *Request) (err error)

                                                                              IsAllowed returns nil if subject s has permission p on resource r with context c or an error otherwise.

                                                                              type Manager

                                                                              type Manager interface {
                                                                              
                                                                              	// Create persists the policy.
                                                                              	Create(policy Policy) error
                                                                              
                                                                              	// Update updates an existing policy.
                                                                              	Update(policy Policy) error
                                                                              
                                                                              	// Get retrieves a policy.
                                                                              	Get(id string) (Policy, error)
                                                                              
                                                                              	// Delete removes a policy.
                                                                              	Delete(id string) error
                                                                              
                                                                              	// GetAll retrieves all policies.
                                                                              	GetAll(limit, offset int64) (Policies, error)
                                                                              
                                                                              	// FindRequestCandidates returns candidates that could match the request object. It either returns
                                                                              	// a set that exactly matches the request, or a superset of it. If an error occurs, it returns nil and
                                                                              	// the error.
                                                                              	FindRequestCandidates(r *Request) (Policies, error)
                                                                              
                                                                              	// FindPoliciesForSubject returns policies that could match the subject. It either returns
                                                                              	// a set of policies that applies to the subject, or a superset of it.
                                                                              	// If an error occurs, it returns nil and the error.
                                                                              	FindPoliciesForSubject(subject string) (Policies, error)
                                                                              
                                                                              	// FindPoliciesForResource returns policies that could match the resource. It either returns
                                                                              	// a set of policies that apply to the resource, or a superset of it.
                                                                              	// If an error occurs, it returns nil and the error.
                                                                              	FindPoliciesForResource(resource string) (Policies, error)
                                                                              }

                                                                                Manager is responsible for managing and persisting policies.

                                                                                type ManagerMigrator

                                                                                type ManagerMigrator interface {
                                                                                	Create(policy Policy) (err error)
                                                                                	Migrate() (err error)
                                                                                	GetManager() Manager
                                                                                }

                                                                                type Metric

                                                                                type Metric interface {
                                                                                	// RequestDeniedBy is called when we get explicit deny by policy
                                                                                	RequestDeniedBy(Request, Policy)
                                                                                	// RequestAllowedBy is called when a matching policy has been found.
                                                                                	RequestAllowedBy(Request, Policies)
                                                                                	// RequestNoMatch is called when no policy has matched our request
                                                                                	RequestNoMatch(Request)
                                                                                	// RequestProcessingError is called when unexpected error occured
                                                                                	RequestProcessingError(Request, Policy, error)
                                                                                }

                                                                                  Metric is used to expose metrics about authz

                                                                                  type MetricNoOp

                                                                                  type MetricNoOp struct{}

                                                                                    MetricNoOp is the default metrics implementation , that tracks nothing.

                                                                                    func (*MetricNoOp) RequestAllowedBy

                                                                                    func (*MetricNoOp) RequestAllowedBy(r Request, p Policies)

                                                                                    func (*MetricNoOp) RequestDeniedBy

                                                                                    func (*MetricNoOp) RequestDeniedBy(r Request, p Policy)

                                                                                    func (*MetricNoOp) RequestNoMatch

                                                                                    func (*MetricNoOp) RequestNoMatch(r Request)

                                                                                    func (*MetricNoOp) RequestProcessingError

                                                                                    func (*MetricNoOp) RequestProcessingError(r Request, p Policy, err error)

                                                                                    type Policies

                                                                                    type Policies []Policy

                                                                                      Policies is an array of policies.

                                                                                      type Policy

                                                                                      type Policy interface {
                                                                                      	// GetID returns the policies id.
                                                                                      	GetID() string
                                                                                      
                                                                                      	// GetDescription returns the policies description.
                                                                                      	GetDescription() string
                                                                                      
                                                                                      	// GetSubjects returns the policies subjects.
                                                                                      	GetSubjects() []string
                                                                                      
                                                                                      	// AllowAccess returns true if the policy effect is allow, otherwise false.
                                                                                      	AllowAccess() bool
                                                                                      
                                                                                      	// GetEffect returns the policies effect which might be 'allow' or 'deny'.
                                                                                      	GetEffect() string
                                                                                      
                                                                                      	// GetResources returns the policies resources.
                                                                                      	GetResources() []string
                                                                                      
                                                                                      	// GetActions returns the policies actions.
                                                                                      	GetActions() []string
                                                                                      
                                                                                      	// GetConditions returns the policies conditions.
                                                                                      	GetConditions() Conditions
                                                                                      
                                                                                      	// GetMeta returns the policies arbitrary metadata set by the user.
                                                                                      	GetMeta() []byte
                                                                                      
                                                                                      	// GetStartDelimiter returns the delimiter which identifies the beginning of a regular expression.
                                                                                      	GetStartDelimiter() byte
                                                                                      
                                                                                      	// GetEndDelimiter returns the delimiter which identifies the end of a regular expression.
                                                                                      	GetEndDelimiter() byte
                                                                                      }

                                                                                        Policy represent a policy model.

                                                                                        type RegexpMatcher

                                                                                        type RegexpMatcher struct {
                                                                                        	*lru.Cache
                                                                                        
                                                                                        	C map[string]*regexp2.Regexp
                                                                                        }

                                                                                        func NewRegexpMatcher

                                                                                        func NewRegexpMatcher(size int) *RegexpMatcher

                                                                                        func (*RegexpMatcher) Matches

                                                                                        func (m *RegexpMatcher) Matches(p Policy, haystack []string, needle string) (bool, error)

                                                                                          Matches a needle with an array of regular expressions and returns true if a match was found.

                                                                                          type Request

                                                                                          type Request struct {
                                                                                          	// Resource is the resource that access is requested to.
                                                                                          	Resource string `json:"resource"`
                                                                                          
                                                                                          	// Action is the action that is requested on the resource.
                                                                                          	Action string `json:"action"`
                                                                                          
                                                                                          	// Subejct is the subject that is requesting access.
                                                                                          	Subject string `json:"subject"`
                                                                                          
                                                                                          	// Context is the request's environmental context.
                                                                                          	Context Context `json:"context"`
                                                                                          }

                                                                                            Request is the warden's request object.

                                                                                            type ResourceContainsCondition

                                                                                            type ResourceContainsCondition struct{}

                                                                                              ResourceContainsCondition is fulfilled if the context matches a substring within the resource name

                                                                                              func (*ResourceContainsCondition) Fulfills

                                                                                              func (c *ResourceContainsCondition) Fulfills(value interface{}, r *Request) bool

                                                                                                Fulfills returns true if the request's resouce contains the given value string

                                                                                                func (*ResourceContainsCondition) GetName

                                                                                                func (c *ResourceContainsCondition) GetName() string

                                                                                                  GetName returns the condition's name.

                                                                                                  type StringEqualCondition

                                                                                                  type StringEqualCondition struct {
                                                                                                  	Equals string `json:"equals"`
                                                                                                  }

                                                                                                    StringEqualCondition is a condition which is fulfilled if the given string value is the same as specified in StringEqualCondition

                                                                                                    func (*StringEqualCondition) Fulfills

                                                                                                    func (c *StringEqualCondition) Fulfills(value interface{}, _ *Request) bool

                                                                                                      Fulfills returns true if the given value is a string and is the same as in StringEqualCondition.Equals

                                                                                                      func (*StringEqualCondition) GetName

                                                                                                      func (c *StringEqualCondition) GetName() string

                                                                                                        GetName returns the condition's name.

                                                                                                        type StringMatchCondition

                                                                                                        type StringMatchCondition struct {
                                                                                                        	Matches string `json:"matches"`
                                                                                                        }

                                                                                                          StringMatchCondition is a condition which is fulfilled if the given string value matches the regex pattern specified in StringMatchCondition

                                                                                                          func (*StringMatchCondition) Fulfills

                                                                                                          func (c *StringMatchCondition) Fulfills(value interface{}, _ *Request) bool

                                                                                                            Fulfills returns true if the given value is a string and matches the regex pattern in StringMatchCondition.Matches

                                                                                                            func (*StringMatchCondition) GetName

                                                                                                            func (c *StringMatchCondition) GetName() string

                                                                                                              GetName returns the condition's name.

                                                                                                              type StringPairsEqualCondition

                                                                                                              type StringPairsEqualCondition struct{}

                                                                                                                StringPairsEqualCondition is a condition which is fulfilled if the given array of pairs contains two-element string arrays where both elements in the string array are equal

                                                                                                                func (*StringPairsEqualCondition) Fulfills

                                                                                                                func (c *StringPairsEqualCondition) Fulfills(value interface{}, _ *Request) bool

                                                                                                                  Fulfills returns true if the given value is an array of string arrays and each string array has exactly two values which are equal

                                                                                                                  func (*StringPairsEqualCondition) GetName

                                                                                                                  func (c *StringPairsEqualCondition) GetName() string

                                                                                                                    GetName returns the condition's name.

                                                                                                                    type Warden

                                                                                                                    type Warden interface {
                                                                                                                    	// IsAllowed returns nil if subject s can perform action a on resource r with context c or an error otherwise.
                                                                                                                    	//  if err := guard.IsAllowed(&Request{Resource: "article/1234", Action: "update", Subject: "peter"}); err != nil {
                                                                                                                    	//    return errors.New("Not allowed")
                                                                                                                    	//  }
                                                                                                                    	IsAllowed(r *Request) error
                                                                                                                    }

                                                                                                                      Warden is responsible for deciding if subject s can perform action a on resource r with context c.

                                                                                                                      Directories

                                                                                                                      Path Synopsis
                                                                                                                      manager