github.com/marwan-at-work/consul@v1.4.5/acl/acl.go (about)

     1  package acl
     2  
     3  import (
     4  	"github.com/armon/go-radix"
     5  	"github.com/hashicorp/consul/sentinel"
     6  )
     7  
     8  var (
     9  	// allowAll is a singleton policy which allows all
    10  	// non-management actions
    11  	allowAll Authorizer
    12  
    13  	// denyAll is a singleton policy which denies all actions
    14  	denyAll Authorizer
    15  
    16  	// manageAll is a singleton policy which allows all
    17  	// actions, including management
    18  	manageAll Authorizer
    19  )
    20  
    21  // DefaultPolicyEnforcementLevel will be used if the user leaves the level
    22  // blank when configuring an ACL.
    23  const DefaultPolicyEnforcementLevel = "hard-mandatory"
    24  
    25  func init() {
    26  	// Setup the singletons
    27  	allowAll = &StaticAuthorizer{
    28  		allowManage:  false,
    29  		defaultAllow: true,
    30  	}
    31  	denyAll = &StaticAuthorizer{
    32  		allowManage:  false,
    33  		defaultAllow: false,
    34  	}
    35  	manageAll = &StaticAuthorizer{
    36  		allowManage:  true,
    37  		defaultAllow: true,
    38  	}
    39  }
    40  
    41  // Authorizer is the interface for policy enforcement.
    42  type Authorizer interface {
    43  	// ACLRead checks for permission to list all the ACLs
    44  	ACLRead() bool
    45  
    46  	// ACLWrite checks for permission to manipulate ACLs
    47  	ACLWrite() bool
    48  
    49  	// AgentRead checks for permission to read from agent endpoints for a
    50  	// given node.
    51  	AgentRead(string) bool
    52  
    53  	// AgentWrite checks for permission to make changes via agent endpoints
    54  	// for a given node.
    55  	AgentWrite(string) bool
    56  
    57  	// EventRead determines if a specific event can be queried.
    58  	EventRead(string) bool
    59  
    60  	// EventWrite determines if a specific event may be fired.
    61  	EventWrite(string) bool
    62  
    63  	// IntentionDefaultAllow determines the default authorized behavior
    64  	// when no intentions match a Connect request.
    65  	IntentionDefaultAllow() bool
    66  
    67  	// IntentionRead determines if a specific intention can be read.
    68  	IntentionRead(string) bool
    69  
    70  	// IntentionWrite determines if a specific intention can be
    71  	// created, modified, or deleted.
    72  	IntentionWrite(string) bool
    73  
    74  	// KeyList checks for permission to list keys under a prefix
    75  	KeyList(string) bool
    76  
    77  	// KeyRead checks for permission to read a given key
    78  	KeyRead(string) bool
    79  
    80  	// KeyWrite checks for permission to write a given key
    81  	KeyWrite(string, sentinel.ScopeFn) bool
    82  
    83  	// KeyWritePrefix checks for permission to write to an
    84  	// entire key prefix. This means there must be no sub-policies
    85  	// that deny a write.
    86  	KeyWritePrefix(string) bool
    87  
    88  	// KeyringRead determines if the encryption keyring used in
    89  	// the gossip layer can be read.
    90  	KeyringRead() bool
    91  
    92  	// KeyringWrite determines if the keyring can be manipulated
    93  	KeyringWrite() bool
    94  
    95  	// NodeRead checks for permission to read (discover) a given node.
    96  	NodeRead(string) bool
    97  
    98  	// NodeWrite checks for permission to create or update (register) a
    99  	// given node.
   100  	NodeWrite(string, sentinel.ScopeFn) bool
   101  
   102  	// OperatorRead determines if the read-only Consul operator functions
   103  	// can be used.
   104  	OperatorRead() bool
   105  
   106  	// OperatorWrite determines if the state-changing Consul operator
   107  	// functions can be used.
   108  	OperatorWrite() bool
   109  
   110  	// PreparedQueryRead determines if a specific prepared query can be read
   111  	// to show its contents (this is not used for execution).
   112  	PreparedQueryRead(string) bool
   113  
   114  	// PreparedQueryWrite determines if a specific prepared query can be
   115  	// created, modified, or deleted.
   116  	PreparedQueryWrite(string) bool
   117  
   118  	// ServiceRead checks for permission to read a given service
   119  	ServiceRead(string) bool
   120  
   121  	// ServiceWrite checks for permission to create or update a given
   122  	// service
   123  	ServiceWrite(string, sentinel.ScopeFn) bool
   124  
   125  	// SessionRead checks for permission to read sessions for a given node.
   126  	SessionRead(string) bool
   127  
   128  	// SessionWrite checks for permission to create sessions for a given
   129  	// node.
   130  	SessionWrite(string) bool
   131  
   132  	// Snapshot checks for permission to take and restore snapshots.
   133  	Snapshot() bool
   134  }
   135  
   136  // StaticAuthorizer is used to implement a base ACL policy. It either
   137  // allows or denies all requests. This can be used as a parent
   138  // ACL to act in a blacklist or whitelist mode.
   139  type StaticAuthorizer struct {
   140  	allowManage  bool
   141  	defaultAllow bool
   142  }
   143  
   144  func (s *StaticAuthorizer) ACLRead() bool {
   145  	return s.allowManage
   146  }
   147  
   148  func (s *StaticAuthorizer) ACLWrite() bool {
   149  	return s.allowManage
   150  }
   151  
   152  func (s *StaticAuthorizer) AgentRead(string) bool {
   153  	return s.defaultAllow
   154  }
   155  
   156  func (s *StaticAuthorizer) AgentWrite(string) bool {
   157  	return s.defaultAllow
   158  }
   159  
   160  func (s *StaticAuthorizer) EventRead(string) bool {
   161  	return s.defaultAllow
   162  }
   163  
   164  func (s *StaticAuthorizer) EventWrite(string) bool {
   165  	return s.defaultAllow
   166  }
   167  
   168  func (s *StaticAuthorizer) IntentionDefaultAllow() bool {
   169  	return s.defaultAllow
   170  }
   171  
   172  func (s *StaticAuthorizer) IntentionRead(string) bool {
   173  	return s.defaultAllow
   174  }
   175  
   176  func (s *StaticAuthorizer) IntentionWrite(string) bool {
   177  	return s.defaultAllow
   178  }
   179  
   180  func (s *StaticAuthorizer) KeyRead(string) bool {
   181  	return s.defaultAllow
   182  }
   183  
   184  func (s *StaticAuthorizer) KeyList(string) bool {
   185  	return s.defaultAllow
   186  }
   187  
   188  func (s *StaticAuthorizer) KeyWrite(string, sentinel.ScopeFn) bool {
   189  	return s.defaultAllow
   190  }
   191  
   192  func (s *StaticAuthorizer) KeyWritePrefix(string) bool {
   193  	return s.defaultAllow
   194  }
   195  
   196  func (s *StaticAuthorizer) KeyringRead() bool {
   197  	return s.defaultAllow
   198  }
   199  
   200  func (s *StaticAuthorizer) KeyringWrite() bool {
   201  	return s.defaultAllow
   202  }
   203  
   204  func (s *StaticAuthorizer) NodeRead(string) bool {
   205  	return s.defaultAllow
   206  }
   207  
   208  func (s *StaticAuthorizer) NodeWrite(string, sentinel.ScopeFn) bool {
   209  	return s.defaultAllow
   210  }
   211  
   212  func (s *StaticAuthorizer) OperatorRead() bool {
   213  	return s.defaultAllow
   214  }
   215  
   216  func (s *StaticAuthorizer) OperatorWrite() bool {
   217  	return s.defaultAllow
   218  }
   219  
   220  func (s *StaticAuthorizer) PreparedQueryRead(string) bool {
   221  	return s.defaultAllow
   222  }
   223  
   224  func (s *StaticAuthorizer) PreparedQueryWrite(string) bool {
   225  	return s.defaultAllow
   226  }
   227  
   228  func (s *StaticAuthorizer) ServiceRead(string) bool {
   229  	return s.defaultAllow
   230  }
   231  
   232  func (s *StaticAuthorizer) ServiceWrite(string, sentinel.ScopeFn) bool {
   233  	return s.defaultAllow
   234  }
   235  
   236  func (s *StaticAuthorizer) SessionRead(string) bool {
   237  	return s.defaultAllow
   238  }
   239  
   240  func (s *StaticAuthorizer) SessionWrite(string) bool {
   241  	return s.defaultAllow
   242  }
   243  
   244  func (s *StaticAuthorizer) Snapshot() bool {
   245  	return s.allowManage
   246  }
   247  
   248  // AllowAll returns an Authorizer that allows all operations
   249  func AllowAll() Authorizer {
   250  	return allowAll
   251  }
   252  
   253  // DenyAll returns an Authorizer that denies all operations
   254  func DenyAll() Authorizer {
   255  	return denyAll
   256  }
   257  
   258  // ManageAll returns an Authorizer that can manage all resources
   259  func ManageAll() Authorizer {
   260  	return manageAll
   261  }
   262  
   263  // RootAuthorizer returns a possible Authorizer if the ID matches a root policy
   264  func RootAuthorizer(id string) Authorizer {
   265  	switch id {
   266  	case "allow":
   267  		return allowAll
   268  	case "deny":
   269  		return denyAll
   270  	case "manage":
   271  		return manageAll
   272  	default:
   273  		return nil
   274  	}
   275  }
   276  
   277  // RulePolicy binds a regular ACL policy along with an optional piece of
   278  // code to execute.
   279  type RulePolicy struct {
   280  	// aclPolicy is used for simple acl rules(allow/deny/manage)
   281  	aclPolicy string
   282  
   283  	// sentinelPolicy has the code part of a policy
   284  	sentinelPolicy Sentinel
   285  }
   286  
   287  // PolicyAuthorizer is used to wrap a set of ACL policies to provide
   288  // the Authorizer interface.
   289  //
   290  type PolicyAuthorizer struct {
   291  	// parent is used to resolve policy if we have
   292  	// no matching rule.
   293  	parent Authorizer
   294  
   295  	// sentinel is an interface for validating and executing sentinel code
   296  	// policies.
   297  	sentinel sentinel.Evaluator
   298  
   299  	// aclRule contains the acl management policy.
   300  	aclRule string
   301  
   302  	// agentRules contain the exact-match agent policies
   303  	agentRules *radix.Tree
   304  
   305  	// intentionRules contains the service intention exact-match policies
   306  	intentionRules *radix.Tree
   307  
   308  	// keyRules contains the key exact-match policies
   309  	keyRules *radix.Tree
   310  
   311  	// nodeRules contains the node exact-match policies
   312  	nodeRules *radix.Tree
   313  
   314  	// serviceRules contains the service exact-match policies
   315  	serviceRules *radix.Tree
   316  
   317  	// sessionRules contains the session exact-match policies
   318  	sessionRules *radix.Tree
   319  
   320  	// eventRules contains the user event exact-match policies
   321  	eventRules *radix.Tree
   322  
   323  	// preparedQueryRules contains the prepared query exact-match policies
   324  	preparedQueryRules *radix.Tree
   325  
   326  	// keyringRule contains the keyring policies. The keyring has
   327  	// a very simple yes/no without prefix matching, so here we
   328  	// don't need to use a radix tree.
   329  	keyringRule string
   330  
   331  	// operatorRule contains the operator policies.
   332  	operatorRule string
   333  }
   334  
   335  // policyAuthorizerRadixLeaf is used as the main
   336  // structure for storing in the radix.Tree's within the
   337  // PolicyAuthorizer
   338  type policyAuthorizerRadixLeaf struct {
   339  	exact  interface{}
   340  	prefix interface{}
   341  }
   342  
   343  // getPolicy first attempts to get an exact match for the segment from the "exact" tree and then falls
   344  // back to getting the policy for the longest prefix from the "prefix" tree
   345  func getPolicy(segment string, tree *radix.Tree) (policy interface{}, found bool) {
   346  	found = false
   347  
   348  	tree.WalkPath(segment, func(path string, leaf interface{}) bool {
   349  		policies := leaf.(*policyAuthorizerRadixLeaf)
   350  		if policies.exact != nil && path == segment {
   351  			found = true
   352  			policy = policies.exact
   353  			return true
   354  		}
   355  
   356  		if policies.prefix != nil {
   357  			found = true
   358  			policy = policies.prefix
   359  		}
   360  		return false
   361  	})
   362  	return
   363  }
   364  
   365  func insertPolicyIntoRadix(segment string, tree *radix.Tree, exactPolicy interface{}, prefixPolicy interface{}) {
   366  	leaf, found := tree.Get(segment)
   367  	if found {
   368  		policy := leaf.(*policyAuthorizerRadixLeaf)
   369  		if exactPolicy != nil {
   370  			policy.exact = exactPolicy
   371  		}
   372  		if prefixPolicy != nil {
   373  			policy.prefix = prefixPolicy
   374  		}
   375  	} else {
   376  		policy := &policyAuthorizerRadixLeaf{exact: exactPolicy, prefix: prefixPolicy}
   377  		tree.Insert(segment, policy)
   378  	}
   379  }
   380  
   381  func enforce(rule string, requiredPermission string) (allow, recurse bool) {
   382  	switch rule {
   383  	case PolicyWrite:
   384  		// grants read, list and write permissions
   385  		return true, false
   386  	case PolicyList:
   387  		// grants read and list permissions
   388  		if requiredPermission == PolicyList || requiredPermission == PolicyRead {
   389  			return true, false
   390  		} else {
   391  			return false, false
   392  		}
   393  	case PolicyRead:
   394  		// grants just read permissions
   395  		if requiredPermission == PolicyRead {
   396  			return true, false
   397  		} else {
   398  			return false, false
   399  		}
   400  	case PolicyDeny:
   401  		// explicit denial - do not recurse
   402  		return false, false
   403  	default:
   404  		// need to recurse as there was no specific policy set
   405  		return false, true
   406  	}
   407  }
   408  
   409  // NewPolicyAuthorizer is used to construct a policy based ACL from a set of policies
   410  // and a parent policy to resolve missing cases.
   411  func NewPolicyAuthorizer(parent Authorizer, policies []*Policy, sentinel sentinel.Evaluator) (*PolicyAuthorizer, error) {
   412  	p := &PolicyAuthorizer{
   413  		parent:             parent,
   414  		agentRules:         radix.New(),
   415  		intentionRules:     radix.New(),
   416  		keyRules:           radix.New(),
   417  		nodeRules:          radix.New(),
   418  		serviceRules:       radix.New(),
   419  		sessionRules:       radix.New(),
   420  		eventRules:         radix.New(),
   421  		preparedQueryRules: radix.New(),
   422  		sentinel:           sentinel,
   423  	}
   424  
   425  	policy := MergePolicies(policies)
   426  
   427  	// Load the agent policy (exact matches)
   428  	for _, ap := range policy.Agents {
   429  		insertPolicyIntoRadix(ap.Node, p.agentRules, ap.Policy, nil)
   430  	}
   431  
   432  	// Load the agent policy (prefix matches)
   433  	for _, ap := range policy.AgentPrefixes {
   434  		insertPolicyIntoRadix(ap.Node, p.agentRules, nil, ap.Policy)
   435  	}
   436  
   437  	// Load the key policy (exact matches)
   438  	for _, kp := range policy.Keys {
   439  		policyRule := RulePolicy{
   440  			aclPolicy:      kp.Policy,
   441  			sentinelPolicy: kp.Sentinel,
   442  		}
   443  		insertPolicyIntoRadix(kp.Prefix, p.keyRules, policyRule, nil)
   444  	}
   445  
   446  	// Load the key policy (prefix matches)
   447  	for _, kp := range policy.KeyPrefixes {
   448  		policyRule := RulePolicy{
   449  			aclPolicy:      kp.Policy,
   450  			sentinelPolicy: kp.Sentinel,
   451  		}
   452  		insertPolicyIntoRadix(kp.Prefix, p.keyRules, nil, policyRule)
   453  	}
   454  
   455  	// Load the node policy (exact matches)
   456  	for _, np := range policy.Nodes {
   457  		policyRule := RulePolicy{
   458  			aclPolicy:      np.Policy,
   459  			sentinelPolicy: np.Sentinel,
   460  		}
   461  		insertPolicyIntoRadix(np.Name, p.nodeRules, policyRule, nil)
   462  	}
   463  
   464  	// Load the node policy (prefix matches)
   465  	for _, np := range policy.NodePrefixes {
   466  		policyRule := RulePolicy{
   467  			aclPolicy:      np.Policy,
   468  			sentinelPolicy: np.Sentinel,
   469  		}
   470  		insertPolicyIntoRadix(np.Name, p.nodeRules, nil, policyRule)
   471  	}
   472  
   473  	// Load the service policy (exact matches)
   474  	for _, sp := range policy.Services {
   475  		policyRule := RulePolicy{
   476  			aclPolicy:      sp.Policy,
   477  			sentinelPolicy: sp.Sentinel,
   478  		}
   479  		insertPolicyIntoRadix(sp.Name, p.serviceRules, policyRule, nil)
   480  
   481  		intention := sp.Intentions
   482  		if intention == "" {
   483  			switch sp.Policy {
   484  			case PolicyRead, PolicyWrite:
   485  				intention = PolicyRead
   486  			default:
   487  				intention = PolicyDeny
   488  			}
   489  		}
   490  
   491  		policyRule = RulePolicy{
   492  			aclPolicy:      intention,
   493  			sentinelPolicy: sp.Sentinel,
   494  		}
   495  		insertPolicyIntoRadix(sp.Name, p.intentionRules, policyRule, nil)
   496  	}
   497  
   498  	// Load the service policy (prefix matches)
   499  	for _, sp := range policy.ServicePrefixes {
   500  		policyRule := RulePolicy{
   501  			aclPolicy:      sp.Policy,
   502  			sentinelPolicy: sp.Sentinel,
   503  		}
   504  		insertPolicyIntoRadix(sp.Name, p.serviceRules, nil, policyRule)
   505  
   506  		intention := sp.Intentions
   507  		if intention == "" {
   508  			switch sp.Policy {
   509  			case PolicyRead, PolicyWrite:
   510  				intention = PolicyRead
   511  			default:
   512  				intention = PolicyDeny
   513  			}
   514  		}
   515  
   516  		policyRule = RulePolicy{
   517  			aclPolicy:      intention,
   518  			sentinelPolicy: sp.Sentinel,
   519  		}
   520  		insertPolicyIntoRadix(sp.Name, p.intentionRules, nil, policyRule)
   521  	}
   522  
   523  	// Load the session policy (exact matches)
   524  	for _, sp := range policy.Sessions {
   525  		insertPolicyIntoRadix(sp.Node, p.sessionRules, sp.Policy, nil)
   526  	}
   527  
   528  	// Load the session policy (prefix matches)
   529  	for _, sp := range policy.SessionPrefixes {
   530  		insertPolicyIntoRadix(sp.Node, p.sessionRules, nil, sp.Policy)
   531  	}
   532  
   533  	// Load the event policy (exact matches)
   534  	for _, ep := range policy.Events {
   535  		insertPolicyIntoRadix(ep.Event, p.eventRules, ep.Policy, nil)
   536  	}
   537  
   538  	// Load the event policy (prefix matches)
   539  	for _, ep := range policy.EventPrefixes {
   540  		insertPolicyIntoRadix(ep.Event, p.eventRules, nil, ep.Policy)
   541  	}
   542  
   543  	// Load the prepared query policy (exact matches)
   544  	for _, qp := range policy.PreparedQueries {
   545  		insertPolicyIntoRadix(qp.Prefix, p.preparedQueryRules, qp.Policy, nil)
   546  	}
   547  
   548  	// Load the prepared query policy (prefix matches)
   549  	for _, qp := range policy.PreparedQueryPrefixes {
   550  		insertPolicyIntoRadix(qp.Prefix, p.preparedQueryRules, nil, qp.Policy)
   551  	}
   552  
   553  	// Load the acl policy
   554  	p.aclRule = policy.ACL
   555  
   556  	// Load the keyring policy
   557  	p.keyringRule = policy.Keyring
   558  
   559  	// Load the operator policy
   560  	p.operatorRule = policy.Operator
   561  
   562  	return p, nil
   563  }
   564  
   565  // ACLRead checks if listing of ACLs is allowed
   566  func (p *PolicyAuthorizer) ACLRead() bool {
   567  	if allow, recurse := enforce(p.aclRule, PolicyRead); !recurse {
   568  		return allow
   569  	}
   570  
   571  	return p.parent.ACLRead()
   572  }
   573  
   574  // ACLWrite checks if modification of ACLs is allowed
   575  func (p *PolicyAuthorizer) ACLWrite() bool {
   576  	if allow, recurse := enforce(p.aclRule, PolicyWrite); !recurse {
   577  		return allow
   578  	}
   579  
   580  	return p.parent.ACLWrite()
   581  }
   582  
   583  // AgentRead checks for permission to read from agent endpoints for a given
   584  // node.
   585  func (p *PolicyAuthorizer) AgentRead(node string) bool {
   586  	// Check for an exact rule or catch-all
   587  	if rule, ok := getPolicy(node, p.agentRules); ok {
   588  		if allow, recurse := enforce(rule.(string), PolicyRead); !recurse {
   589  			return allow
   590  		}
   591  	}
   592  
   593  	// No matching rule, use the parent.
   594  	return p.parent.AgentRead(node)
   595  }
   596  
   597  // AgentWrite checks for permission to make changes via agent endpoints for a
   598  // given node.
   599  func (p *PolicyAuthorizer) AgentWrite(node string) bool {
   600  	// Check for an exact rule or catch-all
   601  	if rule, ok := getPolicy(node, p.agentRules); ok {
   602  		if allow, recurse := enforce(rule.(string), PolicyWrite); !recurse {
   603  			return allow
   604  		}
   605  	}
   606  
   607  	// No matching rule, use the parent.
   608  	return p.parent.AgentWrite(node)
   609  }
   610  
   611  // Snapshot checks if taking and restoring snapshots is allowed.
   612  func (p *PolicyAuthorizer) Snapshot() bool {
   613  	if allow, recurse := enforce(p.aclRule, PolicyWrite); !recurse {
   614  		return allow
   615  	}
   616  	return p.parent.Snapshot()
   617  }
   618  
   619  // EventRead is used to determine if the policy allows for a
   620  // specific user event to be read.
   621  func (p *PolicyAuthorizer) EventRead(name string) bool {
   622  	// Longest-prefix match on event names
   623  	if rule, ok := getPolicy(name, p.eventRules); ok {
   624  		if allow, recurse := enforce(rule.(string), PolicyRead); !recurse {
   625  			return allow
   626  		}
   627  	}
   628  
   629  	// No matching rule, use the parent.
   630  	return p.parent.EventRead(name)
   631  }
   632  
   633  // EventWrite is used to determine if new events can be created
   634  // (fired) by the policy.
   635  func (p *PolicyAuthorizer) EventWrite(name string) bool {
   636  	// Longest-prefix match event names
   637  	if rule, ok := getPolicy(name, p.eventRules); ok {
   638  		if allow, recurse := enforce(rule.(string), PolicyWrite); !recurse {
   639  			return allow
   640  		}
   641  	}
   642  
   643  	// No match, use parent
   644  	return p.parent.EventWrite(name)
   645  }
   646  
   647  // IntentionDefaultAllow returns whether the default behavior when there are
   648  // no matching intentions is to allow or deny.
   649  func (p *PolicyAuthorizer) IntentionDefaultAllow() bool {
   650  	// We always go up, this can't be determined by a policy.
   651  	return p.parent.IntentionDefaultAllow()
   652  }
   653  
   654  // IntentionRead checks if writing (creating, updating, or deleting) of an
   655  // intention is allowed.
   656  func (p *PolicyAuthorizer) IntentionRead(prefix string) bool {
   657  	// Check for an exact rule or catch-all
   658  	if rule, ok := getPolicy(prefix, p.intentionRules); ok {
   659  		pr := rule.(RulePolicy)
   660  		if allow, recurse := enforce(pr.aclPolicy, PolicyRead); !recurse {
   661  			return allow
   662  		}
   663  	}
   664  
   665  	// No matching rule, use the parent.
   666  	return p.parent.IntentionRead(prefix)
   667  }
   668  
   669  // IntentionWrite checks if writing (creating, updating, or deleting) of an
   670  // intention is allowed.
   671  func (p *PolicyAuthorizer) IntentionWrite(prefix string) bool {
   672  	// Check for an exact rule or catch-all
   673  	if rule, ok := getPolicy(prefix, p.intentionRules); ok {
   674  		pr := rule.(RulePolicy)
   675  		if allow, recurse := enforce(pr.aclPolicy, PolicyWrite); !recurse {
   676  			// TODO (ACL-V2) - should we do sentinel enforcement here
   677  			return allow
   678  		}
   679  	}
   680  
   681  	// No matching rule, use the parent.
   682  	return p.parent.IntentionWrite(prefix)
   683  }
   684  
   685  // KeyRead returns if a key is allowed to be read
   686  func (p *PolicyAuthorizer) KeyRead(key string) bool {
   687  	// Look for a matching rule
   688  	if rule, ok := getPolicy(key, p.keyRules); ok {
   689  		pr := rule.(RulePolicy)
   690  		if allow, recurse := enforce(pr.aclPolicy, PolicyRead); !recurse {
   691  			return allow
   692  		}
   693  	}
   694  
   695  	// No matching rule, use the parent.
   696  	return p.parent.KeyRead(key)
   697  }
   698  
   699  // KeyList returns if a key is allowed to be listed
   700  func (p *PolicyAuthorizer) KeyList(key string) bool {
   701  	// Look for a matching rule
   702  	if rule, ok := getPolicy(key, p.keyRules); ok {
   703  		pr := rule.(RulePolicy)
   704  		if allow, recurse := enforce(pr.aclPolicy, PolicyList); !recurse {
   705  			return allow
   706  		}
   707  	}
   708  
   709  	// No matching rule, use the parent.
   710  	return p.parent.KeyList(key)
   711  }
   712  
   713  // KeyWrite returns if a key is allowed to be written
   714  func (p *PolicyAuthorizer) KeyWrite(key string, scope sentinel.ScopeFn) bool {
   715  	// Look for a matching rule
   716  	if rule, ok := getPolicy(key, p.keyRules); ok {
   717  		pr := rule.(RulePolicy)
   718  		if allow, recurse := enforce(pr.aclPolicy, PolicyWrite); !recurse {
   719  			if allow {
   720  				return p.executeCodePolicy(&pr.sentinelPolicy, scope)
   721  			}
   722  			return false
   723  		}
   724  	}
   725  
   726  	// No matching rule, use the parent.
   727  	return p.parent.KeyWrite(key, scope)
   728  }
   729  
   730  // KeyWritePrefix returns if a prefix is allowed to be written
   731  //
   732  // This is mainly used to detect whether a whole tree within
   733  // the KV can be removed. For that reason we must be able to
   734  // delete everything under the prefix. First we must have "write"
   735  // on the prefix itself
   736  func (p *PolicyAuthorizer) KeyWritePrefix(prefix string) bool {
   737  	parentAllows := p.parent.KeyWritePrefix(prefix)
   738  
   739  	// Look for a matching rule that denies
   740  	prefixAllowed := parentAllows
   741  	found := false
   742  
   743  	// Look for a prefix rule that would apply to the prefix we are checking
   744  	// WalkPath starts at the root and walks down to the given prefix.
   745  	// Therefore the last prefix rule we see is the one that matters
   746  	p.keyRules.WalkPath(prefix, func(path string, leaf interface{}) bool {
   747  		rule := leaf.(*policyAuthorizerRadixLeaf)
   748  
   749  		if rule.prefix != nil {
   750  			found = true
   751  			if rule.prefix.(RulePolicy).aclPolicy != PolicyWrite {
   752  				prefixAllowed = false
   753  			} else {
   754  				prefixAllowed = true
   755  			}
   756  		}
   757  		return false
   758  	})
   759  
   760  	// This will be false if we had a prefix that didn't allow write or if
   761  	// there was no prefix rule and the parent policy would deny access.
   762  	if !prefixAllowed {
   763  		return false
   764  	}
   765  
   766  	// Look if any of our children do not allow write access. This loop takes
   767  	// into account both prefix and exact match rules.
   768  	deny := false
   769  	p.keyRules.WalkPrefix(prefix, func(path string, leaf interface{}) bool {
   770  		rule := leaf.(*policyAuthorizerRadixLeaf)
   771  
   772  		if rule.prefix != nil && rule.prefix.(RulePolicy).aclPolicy != PolicyWrite {
   773  			deny = true
   774  			return true
   775  		}
   776  		if rule.exact != nil && rule.exact.(RulePolicy).aclPolicy != PolicyWrite {
   777  			deny = true
   778  			return true
   779  		}
   780  
   781  		return false
   782  	})
   783  
   784  	// Deny the write if any sub-rules may be violated
   785  	if deny {
   786  		return false
   787  	}
   788  
   789  	// If we had a matching prefix rule and it allowed writes, then we can allow the access
   790  	if found {
   791  		return true
   792  	}
   793  
   794  	// No matching rule, use the parent policy.
   795  	return parentAllows
   796  }
   797  
   798  // KeyringRead is used to determine if the keyring can be
   799  // read by the current ACL token.
   800  func (p *PolicyAuthorizer) KeyringRead() bool {
   801  	if allow, recurse := enforce(p.keyringRule, PolicyRead); !recurse {
   802  		return allow
   803  	}
   804  
   805  	return p.parent.KeyringRead()
   806  }
   807  
   808  // KeyringWrite determines if the keyring can be manipulated.
   809  func (p *PolicyAuthorizer) KeyringWrite() bool {
   810  	if allow, recurse := enforce(p.keyringRule, PolicyWrite); !recurse {
   811  		return allow
   812  	}
   813  
   814  	return p.parent.KeyringWrite()
   815  }
   816  
   817  // OperatorRead determines if the read-only operator functions are allowed.
   818  func (p *PolicyAuthorizer) OperatorRead() bool {
   819  	if allow, recurse := enforce(p.operatorRule, PolicyRead); !recurse {
   820  		return allow
   821  	}
   822  
   823  	return p.parent.OperatorRead()
   824  }
   825  
   826  // OperatorWrite determines if the state-changing operator functions are
   827  // allowed.
   828  func (p *PolicyAuthorizer) OperatorWrite() bool {
   829  	if allow, recurse := enforce(p.operatorRule, PolicyWrite); !recurse {
   830  		return allow
   831  	}
   832  
   833  	return p.parent.OperatorWrite()
   834  }
   835  
   836  // NodeRead checks if reading (discovery) of a node is allowed
   837  func (p *PolicyAuthorizer) NodeRead(name string) bool {
   838  	// Check for an exact rule or catch-all
   839  	if rule, ok := getPolicy(name, p.nodeRules); ok {
   840  		pr := rule.(RulePolicy)
   841  		if allow, recurse := enforce(pr.aclPolicy, PolicyRead); !recurse {
   842  			// TODO (ACL-V2) - Should we do sentinel enforcement here
   843  			return allow
   844  		}
   845  	}
   846  
   847  	// No matching rule, use the parent.
   848  	return p.parent.NodeRead(name)
   849  }
   850  
   851  // NodeWrite checks if writing (registering) a node is allowed
   852  func (p *PolicyAuthorizer) NodeWrite(name string, scope sentinel.ScopeFn) bool {
   853  	// Check for an exact rule or catch-all
   854  	if rule, ok := getPolicy(name, p.nodeRules); ok {
   855  		pr := rule.(RulePolicy)
   856  		if allow, recurse := enforce(pr.aclPolicy, PolicyWrite); !recurse {
   857  			return allow
   858  		}
   859  	}
   860  
   861  	// No matching rule, use the parent.
   862  	return p.parent.NodeWrite(name, scope)
   863  }
   864  
   865  // PreparedQueryRead checks if reading (listing) of a prepared query is
   866  // allowed - this isn't execution, just listing its contents.
   867  func (p *PolicyAuthorizer) PreparedQueryRead(prefix string) bool {
   868  	// Check for an exact rule or catch-all
   869  	if rule, ok := getPolicy(prefix, p.preparedQueryRules); ok {
   870  		if allow, recurse := enforce(rule.(string), PolicyRead); !recurse {
   871  			return allow
   872  		}
   873  	}
   874  
   875  	// No matching rule, use the parent.
   876  	return p.parent.PreparedQueryRead(prefix)
   877  }
   878  
   879  // PreparedQueryWrite checks if writing (creating, updating, or deleting) of a
   880  // prepared query is allowed.
   881  func (p *PolicyAuthorizer) PreparedQueryWrite(prefix string) bool {
   882  	// Check for an exact rule or catch-all
   883  	if rule, ok := getPolicy(prefix, p.preparedQueryRules); ok {
   884  		if allow, recurse := enforce(rule.(string), PolicyWrite); !recurse {
   885  			return allow
   886  		}
   887  	}
   888  
   889  	// No matching rule, use the parent.
   890  	return p.parent.PreparedQueryWrite(prefix)
   891  }
   892  
   893  // ServiceRead checks if reading (discovery) of a service is allowed
   894  func (p *PolicyAuthorizer) ServiceRead(name string) bool {
   895  	// Check for an exact rule or catch-all
   896  	if rule, ok := getPolicy(name, p.serviceRules); ok {
   897  		pr := rule.(RulePolicy)
   898  		if allow, recurse := enforce(pr.aclPolicy, PolicyRead); !recurse {
   899  			return allow
   900  		}
   901  	}
   902  
   903  	// No matching rule, use the parent.
   904  	return p.parent.ServiceRead(name)
   905  }
   906  
   907  // ServiceWrite checks if writing (registering) a service is allowed
   908  func (p *PolicyAuthorizer) ServiceWrite(name string, scope sentinel.ScopeFn) bool {
   909  	// Check for an exact rule or catch-all
   910  	if rule, ok := getPolicy(name, p.serviceRules); ok {
   911  		pr := rule.(RulePolicy)
   912  		if allow, recurse := enforce(pr.aclPolicy, PolicyWrite); !recurse {
   913  			return allow
   914  		}
   915  	}
   916  
   917  	// No matching rule, use the parent.
   918  	return p.parent.ServiceWrite(name, scope)
   919  }
   920  
   921  // SessionRead checks for permission to read sessions for a given node.
   922  func (p *PolicyAuthorizer) SessionRead(node string) bool {
   923  	// Check for an exact rule or catch-all
   924  	if rule, ok := getPolicy(node, p.sessionRules); ok {
   925  		if allow, recurse := enforce(rule.(string), PolicyRead); !recurse {
   926  			return allow
   927  		}
   928  	}
   929  
   930  	// No matching rule, use the parent.
   931  	return p.parent.SessionRead(node)
   932  }
   933  
   934  // SessionWrite checks for permission to create sessions for a given node.
   935  func (p *PolicyAuthorizer) SessionWrite(node string) bool {
   936  	// Check for an exact rule or catch-all
   937  	if rule, ok := getPolicy(node, p.sessionRules); ok {
   938  		if allow, recurse := enforce(rule.(string), PolicyWrite); !recurse {
   939  			return allow
   940  		}
   941  	}
   942  
   943  	// No matching rule, use the parent.
   944  	return p.parent.SessionWrite(node)
   945  }
   946  
   947  // executeCodePolicy will run the associated code policy if code policies are
   948  // enabled.
   949  func (p *PolicyAuthorizer) executeCodePolicy(policy *Sentinel, scope sentinel.ScopeFn) bool {
   950  	if p.sentinel == nil {
   951  		return true
   952  	}
   953  
   954  	if policy.Code == "" || scope == nil {
   955  		return true
   956  	}
   957  
   958  	enforcement := policy.EnforcementLevel
   959  	if enforcement == "" {
   960  		enforcement = DefaultPolicyEnforcementLevel
   961  	}
   962  
   963  	return p.sentinel.Execute(policy.Code, enforcement, scope())
   964  }