github.com/clly/consul@v1.4.5/acl/acl_test.go (about)

     1  package acl
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func legacyPolicy(policy *Policy) *Policy {
    11  	return &Policy{
    12  		Agents:                policy.Agents,
    13  		AgentPrefixes:         policy.Agents,
    14  		Nodes:                 policy.Nodes,
    15  		NodePrefixes:          policy.Nodes,
    16  		Keys:                  policy.Keys,
    17  		KeyPrefixes:           policy.Keys,
    18  		Services:              policy.Services,
    19  		ServicePrefixes:       policy.Services,
    20  		Sessions:              policy.Sessions,
    21  		SessionPrefixes:       policy.Sessions,
    22  		Events:                policy.Events,
    23  		EventPrefixes:         policy.Events,
    24  		PreparedQueries:       policy.PreparedQueries,
    25  		PreparedQueryPrefixes: policy.PreparedQueries,
    26  		Keyring:               policy.Keyring,
    27  		Operator:              policy.Operator,
    28  	}
    29  }
    30  
    31  //
    32  // The following 1 line functions are created to all conform to what
    33  // can be stored in the aclCheck type to make defining ACL tests
    34  // nicer in the embedded struct within TestACL
    35  //
    36  
    37  func checkAllowACLRead(t *testing.T, authz Authorizer, prefix string) {
    38  	require.True(t, authz.ACLRead())
    39  }
    40  
    41  func checkAllowACLWrite(t *testing.T, authz Authorizer, prefix string) {
    42  	require.True(t, authz.ACLWrite())
    43  }
    44  
    45  func checkAllowAgentRead(t *testing.T, authz Authorizer, prefix string) {
    46  	require.True(t, authz.AgentRead(prefix))
    47  }
    48  
    49  func checkAllowAgentWrite(t *testing.T, authz Authorizer, prefix string) {
    50  	require.True(t, authz.AgentWrite(prefix))
    51  }
    52  
    53  func checkAllowEventRead(t *testing.T, authz Authorizer, prefix string) {
    54  	require.True(t, authz.EventRead(prefix))
    55  }
    56  
    57  func checkAllowEventWrite(t *testing.T, authz Authorizer, prefix string) {
    58  	require.True(t, authz.EventWrite(prefix))
    59  }
    60  
    61  func checkAllowIntentionDefaultAllow(t *testing.T, authz Authorizer, prefix string) {
    62  	require.True(t, authz.IntentionDefaultAllow())
    63  }
    64  
    65  func checkAllowIntentionRead(t *testing.T, authz Authorizer, prefix string) {
    66  	require.True(t, authz.IntentionRead(prefix))
    67  }
    68  
    69  func checkAllowIntentionWrite(t *testing.T, authz Authorizer, prefix string) {
    70  	require.True(t, authz.IntentionWrite(prefix))
    71  }
    72  
    73  func checkAllowKeyRead(t *testing.T, authz Authorizer, prefix string) {
    74  	require.True(t, authz.KeyRead(prefix))
    75  }
    76  
    77  func checkAllowKeyList(t *testing.T, authz Authorizer, prefix string) {
    78  	require.True(t, authz.KeyList(prefix))
    79  }
    80  
    81  func checkAllowKeyringRead(t *testing.T, authz Authorizer, prefix string) {
    82  	require.True(t, authz.KeyringRead())
    83  }
    84  
    85  func checkAllowKeyringWrite(t *testing.T, authz Authorizer, prefix string) {
    86  	require.True(t, authz.KeyringWrite())
    87  }
    88  
    89  func checkAllowKeyWrite(t *testing.T, authz Authorizer, prefix string) {
    90  	require.True(t, authz.KeyWrite(prefix, nil))
    91  }
    92  
    93  func checkAllowKeyWritePrefix(t *testing.T, authz Authorizer, prefix string) {
    94  	require.True(t, authz.KeyWritePrefix(prefix))
    95  }
    96  
    97  func checkAllowNodeRead(t *testing.T, authz Authorizer, prefix string) {
    98  	require.True(t, authz.NodeRead(prefix))
    99  }
   100  
   101  func checkAllowNodeWrite(t *testing.T, authz Authorizer, prefix string) {
   102  	require.True(t, authz.NodeWrite(prefix, nil))
   103  }
   104  
   105  func checkAllowOperatorRead(t *testing.T, authz Authorizer, prefix string) {
   106  	require.True(t, authz.OperatorRead())
   107  }
   108  
   109  func checkAllowOperatorWrite(t *testing.T, authz Authorizer, prefix string) {
   110  	require.True(t, authz.OperatorWrite())
   111  }
   112  
   113  func checkAllowPreparedQueryRead(t *testing.T, authz Authorizer, prefix string) {
   114  	require.True(t, authz.PreparedQueryRead(prefix))
   115  }
   116  
   117  func checkAllowPreparedQueryWrite(t *testing.T, authz Authorizer, prefix string) {
   118  	require.True(t, authz.PreparedQueryWrite(prefix))
   119  }
   120  
   121  func checkAllowServiceRead(t *testing.T, authz Authorizer, prefix string) {
   122  	require.True(t, authz.ServiceRead(prefix))
   123  }
   124  
   125  func checkAllowServiceWrite(t *testing.T, authz Authorizer, prefix string) {
   126  	require.True(t, authz.ServiceWrite(prefix, nil))
   127  }
   128  
   129  func checkAllowSessionRead(t *testing.T, authz Authorizer, prefix string) {
   130  	require.True(t, authz.SessionRead(prefix))
   131  }
   132  
   133  func checkAllowSessionWrite(t *testing.T, authz Authorizer, prefix string) {
   134  	require.True(t, authz.SessionWrite(prefix))
   135  }
   136  
   137  func checkAllowSnapshot(t *testing.T, authz Authorizer, prefix string) {
   138  	require.True(t, authz.Snapshot())
   139  }
   140  
   141  func checkDenyACLRead(t *testing.T, authz Authorizer, prefix string) {
   142  	require.False(t, authz.ACLRead())
   143  }
   144  
   145  func checkDenyACLWrite(t *testing.T, authz Authorizer, prefix string) {
   146  	require.False(t, authz.ACLWrite())
   147  }
   148  
   149  func checkDenyAgentRead(t *testing.T, authz Authorizer, prefix string) {
   150  	require.False(t, authz.AgentRead(prefix))
   151  }
   152  
   153  func checkDenyAgentWrite(t *testing.T, authz Authorizer, prefix string) {
   154  	require.False(t, authz.AgentWrite(prefix))
   155  }
   156  
   157  func checkDenyEventRead(t *testing.T, authz Authorizer, prefix string) {
   158  	require.False(t, authz.EventRead(prefix))
   159  }
   160  
   161  func checkDenyEventWrite(t *testing.T, authz Authorizer, prefix string) {
   162  	require.False(t, authz.EventWrite(prefix))
   163  }
   164  
   165  func checkDenyIntentionDefaultAllow(t *testing.T, authz Authorizer, prefix string) {
   166  	require.False(t, authz.IntentionDefaultAllow())
   167  }
   168  
   169  func checkDenyIntentionRead(t *testing.T, authz Authorizer, prefix string) {
   170  	require.False(t, authz.IntentionRead(prefix))
   171  }
   172  
   173  func checkDenyIntentionWrite(t *testing.T, authz Authorizer, prefix string) {
   174  	require.False(t, authz.IntentionWrite(prefix))
   175  }
   176  
   177  func checkDenyKeyRead(t *testing.T, authz Authorizer, prefix string) {
   178  	require.False(t, authz.KeyRead(prefix))
   179  }
   180  
   181  func checkDenyKeyList(t *testing.T, authz Authorizer, prefix string) {
   182  	require.False(t, authz.KeyList(prefix))
   183  }
   184  
   185  func checkDenyKeyringRead(t *testing.T, authz Authorizer, prefix string) {
   186  	require.False(t, authz.KeyringRead())
   187  }
   188  
   189  func checkDenyKeyringWrite(t *testing.T, authz Authorizer, prefix string) {
   190  	require.False(t, authz.KeyringWrite())
   191  }
   192  
   193  func checkDenyKeyWrite(t *testing.T, authz Authorizer, prefix string) {
   194  	require.False(t, authz.KeyWrite(prefix, nil))
   195  }
   196  
   197  func checkDenyKeyWritePrefix(t *testing.T, authz Authorizer, prefix string) {
   198  	require.False(t, authz.KeyWritePrefix(prefix))
   199  }
   200  
   201  func checkDenyNodeRead(t *testing.T, authz Authorizer, prefix string) {
   202  	require.False(t, authz.NodeRead(prefix))
   203  }
   204  
   205  func checkDenyNodeWrite(t *testing.T, authz Authorizer, prefix string) {
   206  	require.False(t, authz.NodeWrite(prefix, nil))
   207  }
   208  
   209  func checkDenyOperatorRead(t *testing.T, authz Authorizer, prefix string) {
   210  	require.False(t, authz.OperatorRead())
   211  }
   212  
   213  func checkDenyOperatorWrite(t *testing.T, authz Authorizer, prefix string) {
   214  	require.False(t, authz.OperatorWrite())
   215  }
   216  
   217  func checkDenyPreparedQueryRead(t *testing.T, authz Authorizer, prefix string) {
   218  	require.False(t, authz.PreparedQueryRead(prefix))
   219  }
   220  
   221  func checkDenyPreparedQueryWrite(t *testing.T, authz Authorizer, prefix string) {
   222  	require.False(t, authz.PreparedQueryWrite(prefix))
   223  }
   224  
   225  func checkDenyServiceRead(t *testing.T, authz Authorizer, prefix string) {
   226  	require.False(t, authz.ServiceRead(prefix))
   227  }
   228  
   229  func checkDenyServiceWrite(t *testing.T, authz Authorizer, prefix string) {
   230  	require.False(t, authz.ServiceWrite(prefix, nil))
   231  }
   232  
   233  func checkDenySessionRead(t *testing.T, authz Authorizer, prefix string) {
   234  	require.False(t, authz.SessionRead(prefix))
   235  }
   236  
   237  func checkDenySessionWrite(t *testing.T, authz Authorizer, prefix string) {
   238  	require.False(t, authz.SessionWrite(prefix))
   239  }
   240  
   241  func checkDenySnapshot(t *testing.T, authz Authorizer, prefix string) {
   242  	require.False(t, authz.Snapshot())
   243  }
   244  
   245  func TestACL(t *testing.T) {
   246  	type aclCheck struct {
   247  		name   string
   248  		prefix string
   249  		check  func(t *testing.T, authz Authorizer, prefix string)
   250  	}
   251  
   252  	type aclTest struct {
   253  		name          string
   254  		defaultPolicy Authorizer
   255  		policyStack   []*Policy
   256  		checks        []aclCheck
   257  	}
   258  
   259  	tests := []aclTest{
   260  		{
   261  			name:          "DenyAll",
   262  			defaultPolicy: DenyAll(),
   263  			checks: []aclCheck{
   264  				{name: "DenyACLRead", check: checkDenyACLRead},
   265  				{name: "DenyACLWrite", check: checkDenyACLWrite},
   266  				{name: "DenyAgentRead", check: checkDenyAgentRead},
   267  				{name: "DenyAgentWrite", check: checkDenyAgentWrite},
   268  				{name: "DenyEventRead", check: checkDenyEventRead},
   269  				{name: "DenyEventWrite", check: checkDenyEventWrite},
   270  				{name: "DenyIntentionDefaultAllow", check: checkDenyIntentionDefaultAllow},
   271  				{name: "DenyIntentionRead", check: checkDenyIntentionRead},
   272  				{name: "DenyIntentionWrite", check: checkDenyIntentionWrite},
   273  				{name: "DenyKeyRead", check: checkDenyKeyRead},
   274  				{name: "DenyKeyringRead", check: checkDenyKeyringRead},
   275  				{name: "DenyKeyringWrite", check: checkDenyKeyringWrite},
   276  				{name: "DenyKeyWrite", check: checkDenyKeyWrite},
   277  				{name: "DenyNodeRead", check: checkDenyNodeRead},
   278  				{name: "DenyNodeWrite", check: checkDenyNodeWrite},
   279  				{name: "DenyOperatorRead", check: checkDenyOperatorRead},
   280  				{name: "DenyOperatorWrite", check: checkDenyOperatorWrite},
   281  				{name: "DenyPreparedQueryRead", check: checkDenyPreparedQueryRead},
   282  				{name: "DenyPreparedQueryWrite", check: checkDenyPreparedQueryWrite},
   283  				{name: "DenyServiceRead", check: checkDenyServiceRead},
   284  				{name: "DenyServiceWrite", check: checkDenyServiceWrite},
   285  				{name: "DenySessionRead", check: checkDenySessionRead},
   286  				{name: "DenySessionWrite", check: checkDenySessionWrite},
   287  				{name: "DenySnapshot", check: checkDenySnapshot},
   288  			},
   289  		},
   290  		{
   291  			name:          "AllowAll",
   292  			defaultPolicy: AllowAll(),
   293  			checks: []aclCheck{
   294  				{name: "DenyACLRead", check: checkDenyACLRead},
   295  				{name: "DenyACLWrite", check: checkDenyACLWrite},
   296  				{name: "AllowAgentRead", check: checkAllowAgentRead},
   297  				{name: "AllowAgentWrite", check: checkAllowAgentWrite},
   298  				{name: "AllowEventRead", check: checkAllowEventRead},
   299  				{name: "AllowEventWrite", check: checkAllowEventWrite},
   300  				{name: "AllowIntentionDefaultAllow", check: checkAllowIntentionDefaultAllow},
   301  				{name: "AllowIntentionRead", check: checkAllowIntentionRead},
   302  				{name: "AllowIntentionWrite", check: checkAllowIntentionWrite},
   303  				{name: "AllowKeyRead", check: checkAllowKeyRead},
   304  				{name: "AllowKeyringRead", check: checkAllowKeyringRead},
   305  				{name: "AllowKeyringWrite", check: checkAllowKeyringWrite},
   306  				{name: "AllowKeyWrite", check: checkAllowKeyWrite},
   307  				{name: "AllowNodeRead", check: checkAllowNodeRead},
   308  				{name: "AllowNodeWrite", check: checkAllowNodeWrite},
   309  				{name: "AllowOperatorRead", check: checkAllowOperatorRead},
   310  				{name: "AllowOperatorWrite", check: checkAllowOperatorWrite},
   311  				{name: "AllowPreparedQueryRead", check: checkAllowPreparedQueryRead},
   312  				{name: "AllowPreparedQueryWrite", check: checkAllowPreparedQueryWrite},
   313  				{name: "AllowServiceRead", check: checkAllowServiceRead},
   314  				{name: "AllowServiceWrite", check: checkAllowServiceWrite},
   315  				{name: "AllowSessionRead", check: checkAllowSessionRead},
   316  				{name: "AllowSessionWrite", check: checkAllowSessionWrite},
   317  				{name: "DenySnapshot", check: checkDenySnapshot},
   318  			},
   319  		},
   320  		{
   321  			name:          "ManageAll",
   322  			defaultPolicy: ManageAll(),
   323  			checks: []aclCheck{
   324  				{name: "AllowACLRead", check: checkAllowACLRead},
   325  				{name: "AllowACLWrite", check: checkAllowACLWrite},
   326  				{name: "AllowAgentRead", check: checkAllowAgentRead},
   327  				{name: "AllowAgentWrite", check: checkAllowAgentWrite},
   328  				{name: "AllowEventRead", check: checkAllowEventRead},
   329  				{name: "AllowEventWrite", check: checkAllowEventWrite},
   330  				{name: "AllowIntentionDefaultAllow", check: checkAllowIntentionDefaultAllow},
   331  				{name: "AllowIntentionRead", check: checkAllowIntentionRead},
   332  				{name: "AllowIntentionWrite", check: checkAllowIntentionWrite},
   333  				{name: "AllowKeyRead", check: checkAllowKeyRead},
   334  				{name: "AllowKeyringRead", check: checkAllowKeyringRead},
   335  				{name: "AllowKeyringWrite", check: checkAllowKeyringWrite},
   336  				{name: "AllowKeyWrite", check: checkAllowKeyWrite},
   337  				{name: "AllowNodeRead", check: checkAllowNodeRead},
   338  				{name: "AllowNodeWrite", check: checkAllowNodeWrite},
   339  				{name: "AllowOperatorRead", check: checkAllowOperatorRead},
   340  				{name: "AllowOperatorWrite", check: checkAllowOperatorWrite},
   341  				{name: "AllowPreparedQueryRead", check: checkAllowPreparedQueryRead},
   342  				{name: "AllowPreparedQueryWrite", check: checkAllowPreparedQueryWrite},
   343  				{name: "AllowServiceRead", check: checkAllowServiceRead},
   344  				{name: "AllowServiceWrite", check: checkAllowServiceWrite},
   345  				{name: "AllowSessionRead", check: checkAllowSessionRead},
   346  				{name: "AllowSessionWrite", check: checkAllowSessionWrite},
   347  				{name: "AllowSnapshot", check: checkAllowSnapshot},
   348  			},
   349  		},
   350  		{
   351  			name:          "AgentBasicDefaultDeny",
   352  			defaultPolicy: DenyAll(),
   353  			policyStack: []*Policy{
   354  				legacyPolicy(&Policy{
   355  					Agents: []*AgentPolicy{
   356  						&AgentPolicy{
   357  							Node:   "root",
   358  							Policy: PolicyRead,
   359  						},
   360  						&AgentPolicy{
   361  							Node:   "root-nope",
   362  							Policy: PolicyDeny,
   363  						},
   364  						&AgentPolicy{
   365  							Node:   "root-rw",
   366  							Policy: PolicyWrite,
   367  						},
   368  					},
   369  				}),
   370  			},
   371  			checks: []aclCheck{
   372  				{name: "DefaultReadDenied", prefix: "ro", check: checkDenyAgentRead},
   373  				{name: "DefaultWriteDenied", prefix: "ro", check: checkDenyAgentWrite},
   374  				{name: "ROReadAllowed", prefix: "root", check: checkAllowAgentRead},
   375  				{name: "ROWriteDenied", prefix: "root", check: checkDenyAgentWrite},
   376  				{name: "ROSuffixReadAllowed", prefix: "root-ro", check: checkAllowAgentRead},
   377  				{name: "ROSuffixWriteDenied", prefix: "root-ro", check: checkDenyAgentWrite},
   378  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowAgentRead},
   379  				{name: "RWWriteDenied", prefix: "root-rw", check: checkAllowAgentWrite},
   380  				{name: "RWSuffixReadAllowed", prefix: "root-rw-sub", check: checkAllowAgentRead},
   381  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-sub", check: checkAllowAgentWrite},
   382  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenyAgentRead},
   383  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenyAgentWrite},
   384  				{name: "DenySuffixReadDenied", prefix: "root-nope-sub", check: checkDenyAgentRead},
   385  				{name: "DenySuffixWriteDenied", prefix: "root-nope-sub", check: checkDenyAgentWrite},
   386  			},
   387  		},
   388  		{
   389  			name:          "AgentBasicDefaultAllow",
   390  			defaultPolicy: AllowAll(),
   391  			policyStack: []*Policy{
   392  				legacyPolicy(&Policy{
   393  					Agents: []*AgentPolicy{
   394  						&AgentPolicy{
   395  							Node:   "root",
   396  							Policy: PolicyRead,
   397  						},
   398  						&AgentPolicy{
   399  							Node:   "root-nope",
   400  							Policy: PolicyDeny,
   401  						},
   402  						&AgentPolicy{
   403  							Node:   "root-rw",
   404  							Policy: PolicyWrite,
   405  						},
   406  					},
   407  				}),
   408  			},
   409  			checks: []aclCheck{
   410  				{name: "DefaultReadDenied", prefix: "ro", check: checkAllowAgentRead},
   411  				{name: "DefaultWriteDenied", prefix: "ro", check: checkAllowAgentWrite},
   412  				{name: "ROReadAllowed", prefix: "root", check: checkAllowAgentRead},
   413  				{name: "ROWriteDenied", prefix: "root", check: checkDenyAgentWrite},
   414  				{name: "ROSuffixReadAllowed", prefix: "root-ro", check: checkAllowAgentRead},
   415  				{name: "ROSuffixWriteDenied", prefix: "root-ro", check: checkDenyAgentWrite},
   416  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowAgentRead},
   417  				{name: "RWWriteDenied", prefix: "root-rw", check: checkAllowAgentWrite},
   418  				{name: "RWSuffixReadAllowed", prefix: "root-rw-sub", check: checkAllowAgentRead},
   419  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-sub", check: checkAllowAgentWrite},
   420  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenyAgentRead},
   421  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenyAgentWrite},
   422  				{name: "DenySuffixReadDenied", prefix: "root-nope-sub", check: checkDenyAgentRead},
   423  				{name: "DenySuffixWriteDenied", prefix: "root-nope-sub", check: checkDenyAgentWrite},
   424  			},
   425  		},
   426  		{
   427  			name:          "PreparedQueryDefaultAllow",
   428  			defaultPolicy: AllowAll(),
   429  			policyStack: []*Policy{
   430  				legacyPolicy(&Policy{
   431  					PreparedQueries: []*PreparedQueryPolicy{
   432  						&PreparedQueryPolicy{
   433  							Prefix: "other",
   434  							Policy: PolicyDeny,
   435  						},
   436  					},
   437  				}),
   438  			},
   439  			checks: []aclCheck{
   440  				// in version 1.2.1 and below this would have failed
   441  				{name: "ReadAllowed", prefix: "foo", check: checkAllowPreparedQueryRead},
   442  				// in version 1.2.1 and below this would have failed
   443  				{name: "WriteAllowed", prefix: "foo", check: checkAllowPreparedQueryWrite},
   444  				{name: "ReadDenied", prefix: "other", check: checkDenyPreparedQueryRead},
   445  				{name: "WriteDenied", prefix: "other", check: checkDenyPreparedQueryWrite},
   446  			},
   447  		},
   448  		{
   449  			name:          "AgentNestedDefaultDeny",
   450  			defaultPolicy: DenyAll(),
   451  			policyStack: []*Policy{
   452  				legacyPolicy(&Policy{
   453  					Agents: []*AgentPolicy{
   454  						&AgentPolicy{
   455  							Node:   "root-nope",
   456  							Policy: PolicyDeny,
   457  						},
   458  						&AgentPolicy{
   459  							Node:   "root-ro",
   460  							Policy: PolicyRead,
   461  						},
   462  						&AgentPolicy{
   463  							Node:   "root-rw",
   464  							Policy: PolicyWrite,
   465  						},
   466  						&AgentPolicy{
   467  							Node:   "override",
   468  							Policy: PolicyDeny,
   469  						},
   470  					},
   471  				}),
   472  				legacyPolicy(&Policy{
   473  					Agents: []*AgentPolicy{
   474  						&AgentPolicy{
   475  							Node:   "child-nope",
   476  							Policy: PolicyDeny,
   477  						},
   478  						&AgentPolicy{
   479  							Node:   "child-ro",
   480  							Policy: PolicyRead,
   481  						},
   482  						&AgentPolicy{
   483  							Node:   "child-rw",
   484  							Policy: PolicyWrite,
   485  						},
   486  						&AgentPolicy{
   487  							Node:   "override",
   488  							Policy: PolicyWrite,
   489  						},
   490  					},
   491  				}),
   492  			},
   493  			checks: []aclCheck{
   494  				{name: "DefaultReadDenied", prefix: "nope", check: checkDenyAgentRead},
   495  				{name: "DefaultWriteDenied", prefix: "nope", check: checkDenyAgentWrite},
   496  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenyAgentRead},
   497  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenyAgentWrite},
   498  				{name: "ROReadAllowed", prefix: "root-ro", check: checkAllowAgentRead},
   499  				{name: "ROWriteDenied", prefix: "root-ro", check: checkDenyAgentWrite},
   500  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowAgentRead},
   501  				{name: "RWWriteAllowed", prefix: "root-rw", check: checkAllowAgentWrite},
   502  				{name: "DenySuffixReadDenied", prefix: "root-nope-prefix", check: checkDenyAgentRead},
   503  				{name: "DenySuffixWriteDenied", prefix: "root-nope-prefix", check: checkDenyAgentWrite},
   504  				{name: "ROSuffixReadAllowed", prefix: "root-ro-prefix", check: checkAllowAgentRead},
   505  				{name: "ROSuffixWriteDenied", prefix: "root-ro-prefix", check: checkDenyAgentWrite},
   506  				{name: "RWSuffixReadAllowed", prefix: "root-rw-prefix", check: checkAllowAgentRead},
   507  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-prefix", check: checkAllowAgentWrite},
   508  				{name: "ChildDenyReadDenied", prefix: "child-nope", check: checkDenyAgentRead},
   509  				{name: "ChildDenyWriteDenied", prefix: "child-nope", check: checkDenyAgentWrite},
   510  				{name: "ChildROReadAllowed", prefix: "child-ro", check: checkAllowAgentRead},
   511  				{name: "ChildROWriteDenied", prefix: "child-ro", check: checkDenyAgentWrite},
   512  				{name: "ChildRWReadAllowed", prefix: "child-rw", check: checkAllowAgentRead},
   513  				{name: "ChildRWWriteAllowed", prefix: "child-rw", check: checkAllowAgentWrite},
   514  				{name: "ChildDenySuffixReadDenied", prefix: "child-nope-prefix", check: checkDenyAgentRead},
   515  				{name: "ChildDenySuffixWriteDenied", prefix: "child-nope-prefix", check: checkDenyAgentWrite},
   516  				{name: "ChildROSuffixReadAllowed", prefix: "child-ro-prefix", check: checkAllowAgentRead},
   517  				{name: "ChildROSuffixWriteDenied", prefix: "child-ro-prefix", check: checkDenyAgentWrite},
   518  				{name: "ChildRWSuffixReadAllowed", prefix: "child-rw-prefix", check: checkAllowAgentRead},
   519  				{name: "ChildRWSuffixWriteAllowed", prefix: "child-rw-prefix", check: checkAllowAgentWrite},
   520  				{name: "ChildOverrideReadAllowed", prefix: "override", check: checkAllowAgentRead},
   521  				{name: "ChildOverrideWriteAllowed", prefix: "override", check: checkAllowAgentWrite},
   522  			},
   523  		},
   524  		{
   525  			name:          "AgentNestedDefaultAllow",
   526  			defaultPolicy: AllowAll(),
   527  			policyStack: []*Policy{
   528  				legacyPolicy(&Policy{
   529  					Agents: []*AgentPolicy{
   530  						&AgentPolicy{
   531  							Node:   "root-nope",
   532  							Policy: PolicyDeny,
   533  						},
   534  						&AgentPolicy{
   535  							Node:   "root-ro",
   536  							Policy: PolicyRead,
   537  						},
   538  						&AgentPolicy{
   539  							Node:   "root-rw",
   540  							Policy: PolicyWrite,
   541  						},
   542  						&AgentPolicy{
   543  							Node:   "override",
   544  							Policy: PolicyDeny,
   545  						},
   546  					},
   547  				}),
   548  				legacyPolicy(&Policy{
   549  					Agents: []*AgentPolicy{
   550  						&AgentPolicy{
   551  							Node:   "child-nope",
   552  							Policy: PolicyDeny,
   553  						},
   554  						&AgentPolicy{
   555  							Node:   "child-ro",
   556  							Policy: PolicyRead,
   557  						},
   558  						&AgentPolicy{
   559  							Node:   "child-rw",
   560  							Policy: PolicyWrite,
   561  						},
   562  						&AgentPolicy{
   563  							Node:   "override",
   564  							Policy: PolicyWrite,
   565  						},
   566  					},
   567  				}),
   568  			},
   569  			checks: []aclCheck{
   570  				{name: "DefaultReadAllowed", prefix: "nope", check: checkAllowAgentRead},
   571  				{name: "DefaultWriteAllowed", prefix: "nope", check: checkAllowAgentWrite},
   572  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenyAgentRead},
   573  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenyAgentWrite},
   574  				{name: "ROReadAllowed", prefix: "root-ro", check: checkAllowAgentRead},
   575  				{name: "ROWriteDenied", prefix: "root-ro", check: checkDenyAgentWrite},
   576  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowAgentRead},
   577  				{name: "RWWriteAllowed", prefix: "root-rw", check: checkAllowAgentWrite},
   578  				{name: "DenySuffixReadDenied", prefix: "root-nope-prefix", check: checkDenyAgentRead},
   579  				{name: "DenySuffixWriteDenied", prefix: "root-nope-prefix", check: checkDenyAgentWrite},
   580  				{name: "ROSuffixReadAllowed", prefix: "root-ro-prefix", check: checkAllowAgentRead},
   581  				{name: "ROSuffixWriteDenied", prefix: "root-ro-prefix", check: checkDenyAgentWrite},
   582  				{name: "RWSuffixReadAllowed", prefix: "root-rw-prefix", check: checkAllowAgentRead},
   583  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-prefix", check: checkAllowAgentWrite},
   584  				{name: "ChildDenyReadDenied", prefix: "child-nope", check: checkDenyAgentRead},
   585  				{name: "ChildDenyWriteDenied", prefix: "child-nope", check: checkDenyAgentWrite},
   586  				{name: "ChildROReadAllowed", prefix: "child-ro", check: checkAllowAgentRead},
   587  				{name: "ChildROWriteDenied", prefix: "child-ro", check: checkDenyAgentWrite},
   588  				{name: "ChildRWReadAllowed", prefix: "child-rw", check: checkAllowAgentRead},
   589  				{name: "ChildRWWriteAllowed", prefix: "child-rw", check: checkAllowAgentWrite},
   590  				{name: "ChildDenySuffixReadDenied", prefix: "child-nope-prefix", check: checkDenyAgentRead},
   591  				{name: "ChildDenySuffixWriteDenied", prefix: "child-nope-prefix", check: checkDenyAgentWrite},
   592  				{name: "ChildROSuffixReadAllowed", prefix: "child-ro-prefix", check: checkAllowAgentRead},
   593  				{name: "ChildROSuffixWriteDenied", prefix: "child-ro-prefix", check: checkDenyAgentWrite},
   594  				{name: "ChildRWSuffixReadAllowed", prefix: "child-rw-prefix", check: checkAllowAgentRead},
   595  				{name: "ChildRWSuffixWriteAllowed", prefix: "child-rw-prefix", check: checkAllowAgentWrite},
   596  				{name: "ChildOverrideReadAllowed", prefix: "override", check: checkAllowAgentRead},
   597  				{name: "ChildOverrideWriteAllowed", prefix: "override", check: checkAllowAgentWrite},
   598  			},
   599  		},
   600  		{
   601  			name:          "KeyringDefaultAllowPolicyDeny",
   602  			defaultPolicy: AllowAll(),
   603  			policyStack: []*Policy{
   604  				&Policy{
   605  					Keyring: PolicyDeny,
   606  				},
   607  			},
   608  			checks: []aclCheck{
   609  				{name: "ReadDenied", check: checkDenyKeyringRead},
   610  				// in version 1.2.1 and below this would have failed
   611  				{name: "WriteDenied", check: checkDenyKeyringWrite},
   612  			},
   613  		},
   614  		{
   615  			name:          "KeyringDefaultAllowPolicyRead",
   616  			defaultPolicy: AllowAll(),
   617  			policyStack: []*Policy{
   618  				&Policy{
   619  					Keyring: PolicyRead,
   620  				},
   621  			},
   622  			checks: []aclCheck{
   623  				{name: "ReadAllowed", check: checkAllowKeyringRead},
   624  				// in version 1.2.1 and below this would have failed
   625  				{name: "WriteDenied", check: checkDenyKeyringWrite},
   626  			},
   627  		},
   628  		{
   629  			name:          "KeyringDefaultAllowPolicyWrite",
   630  			defaultPolicy: AllowAll(),
   631  			policyStack: []*Policy{
   632  				&Policy{
   633  					Keyring: PolicyWrite,
   634  				},
   635  			},
   636  			checks: []aclCheck{
   637  				{name: "ReadAllowed", check: checkAllowKeyringRead},
   638  				{name: "WriteAllowed", check: checkAllowKeyringWrite},
   639  			},
   640  		},
   641  		{
   642  			name:          "KeyringDefaultAllowPolicyNone",
   643  			defaultPolicy: AllowAll(),
   644  			policyStack: []*Policy{
   645  				&Policy{},
   646  			},
   647  			checks: []aclCheck{
   648  				{name: "ReadAllowed", check: checkAllowKeyringRead},
   649  				{name: "WriteAllowed", check: checkAllowKeyringWrite},
   650  			},
   651  		},
   652  		{
   653  			name:          "KeyringDefaultDenyPolicyDeny",
   654  			defaultPolicy: DenyAll(),
   655  			policyStack: []*Policy{
   656  				&Policy{
   657  					Keyring: PolicyDeny,
   658  				},
   659  			},
   660  			checks: []aclCheck{
   661  				{name: "ReadDenied", check: checkDenyKeyringRead},
   662  				{name: "WriteDenied", check: checkDenyKeyringWrite},
   663  			},
   664  		},
   665  		{
   666  			name:          "KeyringDefaultDenyPolicyRead",
   667  			defaultPolicy: DenyAll(),
   668  			policyStack: []*Policy{
   669  				&Policy{
   670  					Keyring: PolicyRead,
   671  				},
   672  			},
   673  			checks: []aclCheck{
   674  				{name: "ReadAllowed", check: checkAllowKeyringRead},
   675  				{name: "WriteDenied", check: checkDenyKeyringWrite},
   676  			},
   677  		},
   678  		{
   679  			name:          "KeyringDefaultDenyPolicyWrite",
   680  			defaultPolicy: DenyAll(),
   681  			policyStack: []*Policy{
   682  				&Policy{
   683  					Keyring: PolicyWrite,
   684  				},
   685  			},
   686  			checks: []aclCheck{
   687  				{name: "ReadAllowed", check: checkAllowKeyringRead},
   688  				{name: "WriteAllowed", check: checkAllowKeyringWrite},
   689  			},
   690  		},
   691  		{
   692  			name:          "KeyringDefaultDenyPolicyNone",
   693  			defaultPolicy: DenyAll(),
   694  			policyStack: []*Policy{
   695  				&Policy{},
   696  			},
   697  			checks: []aclCheck{
   698  				{name: "ReadDenied", check: checkDenyKeyringRead},
   699  				{name: "WriteDenied", check: checkDenyKeyringWrite},
   700  			},
   701  		},
   702  		{
   703  			name:          "OperatorDefaultAllowPolicyDeny",
   704  			defaultPolicy: AllowAll(),
   705  			policyStack: []*Policy{
   706  				&Policy{
   707  					Operator: PolicyDeny,
   708  				},
   709  			},
   710  			checks: []aclCheck{
   711  				{name: "ReadDenied", check: checkDenyOperatorRead},
   712  				// in version 1.2.1 and below this would have failed
   713  				{name: "WriteDenied", check: checkDenyOperatorWrite},
   714  			},
   715  		},
   716  		{
   717  			name:          "OperatorDefaultAllowPolicyRead",
   718  			defaultPolicy: AllowAll(),
   719  			policyStack: []*Policy{
   720  				&Policy{
   721  					Operator: PolicyRead,
   722  				},
   723  			},
   724  			checks: []aclCheck{
   725  				{name: "ReadAllowed", check: checkAllowOperatorRead},
   726  				// in version 1.2.1 and below this would have failed
   727  				{name: "WriteDenied", check: checkDenyOperatorWrite},
   728  			},
   729  		},
   730  		{
   731  			name:          "OperatorDefaultAllowPolicyWrite",
   732  			defaultPolicy: AllowAll(),
   733  			policyStack: []*Policy{
   734  				&Policy{
   735  					Operator: PolicyWrite,
   736  				},
   737  			},
   738  			checks: []aclCheck{
   739  				{name: "ReadAllowed", check: checkAllowOperatorRead},
   740  				{name: "WriteAllowed", check: checkAllowOperatorWrite},
   741  			},
   742  		},
   743  		{
   744  			name:          "OperatorDefaultAllowPolicyNone",
   745  			defaultPolicy: AllowAll(),
   746  			policyStack: []*Policy{
   747  				&Policy{},
   748  			},
   749  			checks: []aclCheck{
   750  				{name: "ReadAllowed", check: checkAllowOperatorRead},
   751  				{name: "WriteAllowed", check: checkAllowOperatorWrite},
   752  			},
   753  		},
   754  		{
   755  			name:          "OperatorDefaultDenyPolicyDeny",
   756  			defaultPolicy: DenyAll(),
   757  			policyStack: []*Policy{
   758  				&Policy{
   759  					Operator: PolicyDeny,
   760  				},
   761  			},
   762  			checks: []aclCheck{
   763  				{name: "ReadDenied", check: checkDenyOperatorRead},
   764  				{name: "WriteDenied", check: checkDenyOperatorWrite},
   765  			},
   766  		},
   767  		{
   768  			name:          "OperatorDefaultDenyPolicyRead",
   769  			defaultPolicy: DenyAll(),
   770  			policyStack: []*Policy{
   771  				&Policy{
   772  					Operator: PolicyRead,
   773  				},
   774  			},
   775  			checks: []aclCheck{
   776  				{name: "ReadAllowed", check: checkAllowOperatorRead},
   777  				{name: "WriteDenied", check: checkDenyOperatorWrite},
   778  			},
   779  		},
   780  		{
   781  			name:          "OperatorDefaultDenyPolicyWrite",
   782  			defaultPolicy: DenyAll(),
   783  			policyStack: []*Policy{
   784  				&Policy{
   785  					Operator: PolicyWrite,
   786  				},
   787  			},
   788  			checks: []aclCheck{
   789  				{name: "ReadAllowed", check: checkAllowOperatorRead},
   790  				{name: "WriteAllowed", check: checkAllowOperatorWrite},
   791  			},
   792  		},
   793  		{
   794  			name:          "OperatorDefaultDenyPolicyNone",
   795  			defaultPolicy: DenyAll(),
   796  			policyStack: []*Policy{
   797  				&Policy{},
   798  			},
   799  			checks: []aclCheck{
   800  				{name: "ReadDenied", check: checkDenyOperatorRead},
   801  				{name: "WriteDenied", check: checkDenyOperatorWrite},
   802  			},
   803  		},
   804  		{
   805  			name:          "NodeDefaultDeny",
   806  			defaultPolicy: DenyAll(),
   807  			policyStack: []*Policy{
   808  				legacyPolicy(&Policy{
   809  					Nodes: []*NodePolicy{
   810  						&NodePolicy{
   811  							Name:   "root-nope",
   812  							Policy: PolicyDeny,
   813  						},
   814  						&NodePolicy{
   815  							Name:   "root-ro",
   816  							Policy: PolicyRead,
   817  						},
   818  						&NodePolicy{
   819  							Name:   "root-rw",
   820  							Policy: PolicyWrite,
   821  						},
   822  						&NodePolicy{
   823  							Name:   "override",
   824  							Policy: PolicyDeny,
   825  						},
   826  					},
   827  				}),
   828  				legacyPolicy(&Policy{
   829  					Nodes: []*NodePolicy{
   830  						&NodePolicy{
   831  							Name:   "child-nope",
   832  							Policy: PolicyDeny,
   833  						},
   834  						&NodePolicy{
   835  							Name:   "child-ro",
   836  							Policy: PolicyRead,
   837  						},
   838  						&NodePolicy{
   839  							Name:   "child-rw",
   840  							Policy: PolicyWrite,
   841  						},
   842  						&NodePolicy{
   843  							Name:   "override",
   844  							Policy: PolicyWrite,
   845  						},
   846  					},
   847  				}),
   848  			},
   849  			checks: []aclCheck{
   850  				{name: "DefaultReadDenied", prefix: "nope", check: checkDenyNodeRead},
   851  				{name: "DefaultWriteDenied", prefix: "nope", check: checkDenyNodeWrite},
   852  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenyNodeRead},
   853  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenyNodeWrite},
   854  				{name: "ROReadAllowed", prefix: "root-ro", check: checkAllowNodeRead},
   855  				{name: "ROWriteDenied", prefix: "root-ro", check: checkDenyNodeWrite},
   856  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowNodeRead},
   857  				{name: "RWWriteAllowed", prefix: "root-rw", check: checkAllowNodeWrite},
   858  				{name: "DenySuffixReadDenied", prefix: "root-nope-prefix", check: checkDenyNodeRead},
   859  				{name: "DenySuffixWriteDenied", prefix: "root-nope-prefix", check: checkDenyNodeWrite},
   860  				{name: "ROSuffixReadAllowed", prefix: "root-ro-prefix", check: checkAllowNodeRead},
   861  				{name: "ROSuffixWriteDenied", prefix: "root-ro-prefix", check: checkDenyNodeWrite},
   862  				{name: "RWSuffixReadAllowed", prefix: "root-rw-prefix", check: checkAllowNodeRead},
   863  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-prefix", check: checkAllowNodeWrite},
   864  				{name: "ChildDenyReadDenied", prefix: "child-nope", check: checkDenyNodeRead},
   865  				{name: "ChildDenyWriteDenied", prefix: "child-nope", check: checkDenyNodeWrite},
   866  				{name: "ChildROReadAllowed", prefix: "child-ro", check: checkAllowNodeRead},
   867  				{name: "ChildROWriteDenied", prefix: "child-ro", check: checkDenyNodeWrite},
   868  				{name: "ChildRWReadAllowed", prefix: "child-rw", check: checkAllowNodeRead},
   869  				{name: "ChildRWWriteAllowed", prefix: "child-rw", check: checkAllowNodeWrite},
   870  				{name: "ChildDenySuffixReadDenied", prefix: "child-nope-prefix", check: checkDenyNodeRead},
   871  				{name: "ChildDenySuffixWriteDenied", prefix: "child-nope-prefix", check: checkDenyNodeWrite},
   872  				{name: "ChildROSuffixReadAllowed", prefix: "child-ro-prefix", check: checkAllowNodeRead},
   873  				{name: "ChildROSuffixWriteDenied", prefix: "child-ro-prefix", check: checkDenyNodeWrite},
   874  				{name: "ChildRWSuffixReadAllowed", prefix: "child-rw-prefix", check: checkAllowNodeRead},
   875  				{name: "ChildRWSuffixWriteAllowed", prefix: "child-rw-prefix", check: checkAllowNodeWrite},
   876  				{name: "ChildOverrideReadAllowed", prefix: "override", check: checkAllowNodeRead},
   877  				{name: "ChildOverrideWriteAllowed", prefix: "override", check: checkAllowNodeWrite},
   878  			},
   879  		},
   880  		{
   881  			name:          "NodeDefaultAllow",
   882  			defaultPolicy: AllowAll(),
   883  			policyStack: []*Policy{
   884  				legacyPolicy(&Policy{
   885  					Nodes: []*NodePolicy{
   886  						&NodePolicy{
   887  							Name:   "root-nope",
   888  							Policy: PolicyDeny,
   889  						},
   890  						&NodePolicy{
   891  							Name:   "root-ro",
   892  							Policy: PolicyRead,
   893  						},
   894  						&NodePolicy{
   895  							Name:   "root-rw",
   896  							Policy: PolicyWrite,
   897  						},
   898  						&NodePolicy{
   899  							Name:   "override",
   900  							Policy: PolicyDeny,
   901  						},
   902  					},
   903  				}),
   904  				legacyPolicy(&Policy{
   905  					Nodes: []*NodePolicy{
   906  						&NodePolicy{
   907  							Name:   "child-nope",
   908  							Policy: PolicyDeny,
   909  						},
   910  						&NodePolicy{
   911  							Name:   "child-ro",
   912  							Policy: PolicyRead,
   913  						},
   914  						&NodePolicy{
   915  							Name:   "child-rw",
   916  							Policy: PolicyWrite,
   917  						},
   918  						&NodePolicy{
   919  							Name:   "override",
   920  							Policy: PolicyWrite,
   921  						},
   922  					},
   923  				}),
   924  			},
   925  			checks: []aclCheck{
   926  				{name: "DefaultReadAllowed", prefix: "nope", check: checkAllowNodeRead},
   927  				{name: "DefaultWriteAllowed", prefix: "nope", check: checkAllowNodeWrite},
   928  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenyNodeRead},
   929  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenyNodeWrite},
   930  				{name: "ROReadAllowed", prefix: "root-ro", check: checkAllowNodeRead},
   931  				{name: "ROWriteDenied", prefix: "root-ro", check: checkDenyNodeWrite},
   932  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowNodeRead},
   933  				{name: "RWWriteAllowed", prefix: "root-rw", check: checkAllowNodeWrite},
   934  				{name: "DenySuffixReadDenied", prefix: "root-nope-prefix", check: checkDenyNodeRead},
   935  				{name: "DenySuffixWriteDenied", prefix: "root-nope-prefix", check: checkDenyNodeWrite},
   936  				{name: "ROSuffixReadAllowed", prefix: "root-ro-prefix", check: checkAllowNodeRead},
   937  				{name: "ROSuffixWriteDenied", prefix: "root-ro-prefix", check: checkDenyNodeWrite},
   938  				{name: "RWSuffixReadAllowed", prefix: "root-rw-prefix", check: checkAllowNodeRead},
   939  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-prefix", check: checkAllowNodeWrite},
   940  				{name: "ChildDenyReadDenied", prefix: "child-nope", check: checkDenyNodeRead},
   941  				{name: "ChildDenyWriteDenied", prefix: "child-nope", check: checkDenyNodeWrite},
   942  				{name: "ChildROReadAllowed", prefix: "child-ro", check: checkAllowNodeRead},
   943  				{name: "ChildROWriteDenied", prefix: "child-ro", check: checkDenyNodeWrite},
   944  				{name: "ChildRWReadAllowed", prefix: "child-rw", check: checkAllowNodeRead},
   945  				{name: "ChildRWWriteAllowed", prefix: "child-rw", check: checkAllowNodeWrite},
   946  				{name: "ChildDenySuffixReadDenied", prefix: "child-nope-prefix", check: checkDenyNodeRead},
   947  				{name: "ChildDenySuffixWriteDenied", prefix: "child-nope-prefix", check: checkDenyNodeWrite},
   948  				{name: "ChildROSuffixReadAllowed", prefix: "child-ro-prefix", check: checkAllowNodeRead},
   949  				{name: "ChildROSuffixWriteDenied", prefix: "child-ro-prefix", check: checkDenyNodeWrite},
   950  				{name: "ChildRWSuffixReadAllowed", prefix: "child-rw-prefix", check: checkAllowNodeRead},
   951  				{name: "ChildRWSuffixWriteAllowed", prefix: "child-rw-prefix", check: checkAllowNodeWrite},
   952  				{name: "ChildOverrideReadAllowed", prefix: "override", check: checkAllowNodeRead},
   953  				{name: "ChildOverrideWriteAllowed", prefix: "override", check: checkAllowNodeWrite},
   954  			},
   955  		},
   956  		{
   957  			name:          "SessionDefaultDeny",
   958  			defaultPolicy: DenyAll(),
   959  			policyStack: []*Policy{
   960  				legacyPolicy(&Policy{
   961  					Sessions: []*SessionPolicy{
   962  						&SessionPolicy{
   963  							Node:   "root-nope",
   964  							Policy: PolicyDeny,
   965  						},
   966  						&SessionPolicy{
   967  							Node:   "root-ro",
   968  							Policy: PolicyRead,
   969  						},
   970  						&SessionPolicy{
   971  							Node:   "root-rw",
   972  							Policy: PolicyWrite,
   973  						},
   974  						&SessionPolicy{
   975  							Node:   "override",
   976  							Policy: PolicyDeny,
   977  						},
   978  					},
   979  				}),
   980  				legacyPolicy(&Policy{
   981  					Sessions: []*SessionPolicy{
   982  						&SessionPolicy{
   983  							Node:   "child-nope",
   984  							Policy: PolicyDeny,
   985  						},
   986  						&SessionPolicy{
   987  							Node:   "child-ro",
   988  							Policy: PolicyRead,
   989  						},
   990  						&SessionPolicy{
   991  							Node:   "child-rw",
   992  							Policy: PolicyWrite,
   993  						},
   994  						&SessionPolicy{
   995  							Node:   "override",
   996  							Policy: PolicyWrite,
   997  						},
   998  					},
   999  				}),
  1000  			},
  1001  			checks: []aclCheck{
  1002  				{name: "DefaultReadDenied", prefix: "nope", check: checkDenySessionRead},
  1003  				{name: "DefaultWriteDenied", prefix: "nope", check: checkDenySessionWrite},
  1004  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenySessionRead},
  1005  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenySessionWrite},
  1006  				{name: "ROReadAllowed", prefix: "root-ro", check: checkAllowSessionRead},
  1007  				{name: "ROWriteDenied", prefix: "root-ro", check: checkDenySessionWrite},
  1008  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowSessionRead},
  1009  				{name: "RWWriteAllowed", prefix: "root-rw", check: checkAllowSessionWrite},
  1010  				{name: "DenySuffixReadDenied", prefix: "root-nope-prefix", check: checkDenySessionRead},
  1011  				{name: "DenySuffixWriteDenied", prefix: "root-nope-prefix", check: checkDenySessionWrite},
  1012  				{name: "ROSuffixReadAllowed", prefix: "root-ro-prefix", check: checkAllowSessionRead},
  1013  				{name: "ROSuffixWriteDenied", prefix: "root-ro-prefix", check: checkDenySessionWrite},
  1014  				{name: "RWSuffixReadAllowed", prefix: "root-rw-prefix", check: checkAllowSessionRead},
  1015  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-prefix", check: checkAllowSessionWrite},
  1016  				{name: "ChildDenyReadDenied", prefix: "child-nope", check: checkDenySessionRead},
  1017  				{name: "ChildDenyWriteDenied", prefix: "child-nope", check: checkDenySessionWrite},
  1018  				{name: "ChildROReadAllowed", prefix: "child-ro", check: checkAllowSessionRead},
  1019  				{name: "ChildROWriteDenied", prefix: "child-ro", check: checkDenySessionWrite},
  1020  				{name: "ChildRWReadAllowed", prefix: "child-rw", check: checkAllowSessionRead},
  1021  				{name: "ChildRWWriteAllowed", prefix: "child-rw", check: checkAllowSessionWrite},
  1022  				{name: "ChildDenySuffixReadDenied", prefix: "child-nope-prefix", check: checkDenySessionRead},
  1023  				{name: "ChildDenySuffixWriteDenied", prefix: "child-nope-prefix", check: checkDenySessionWrite},
  1024  				{name: "ChildROSuffixReadAllowed", prefix: "child-ro-prefix", check: checkAllowSessionRead},
  1025  				{name: "ChildROSuffixWriteDenied", prefix: "child-ro-prefix", check: checkDenySessionWrite},
  1026  				{name: "ChildRWSuffixReadAllowed", prefix: "child-rw-prefix", check: checkAllowSessionRead},
  1027  				{name: "ChildRWSuffixWriteAllowed", prefix: "child-rw-prefix", check: checkAllowSessionWrite},
  1028  				{name: "ChildOverrideReadAllowed", prefix: "override", check: checkAllowSessionRead},
  1029  				{name: "ChildOverrideWriteAllowed", prefix: "override", check: checkAllowSessionWrite},
  1030  			},
  1031  		},
  1032  		{
  1033  			name:          "SessionDefaultAllow",
  1034  			defaultPolicy: AllowAll(),
  1035  			policyStack: []*Policy{
  1036  				legacyPolicy(&Policy{
  1037  					Sessions: []*SessionPolicy{
  1038  						&SessionPolicy{
  1039  							Node:   "root-nope",
  1040  							Policy: PolicyDeny,
  1041  						},
  1042  						&SessionPolicy{
  1043  							Node:   "root-ro",
  1044  							Policy: PolicyRead,
  1045  						},
  1046  						&SessionPolicy{
  1047  							Node:   "root-rw",
  1048  							Policy: PolicyWrite,
  1049  						},
  1050  						&SessionPolicy{
  1051  							Node:   "override",
  1052  							Policy: PolicyDeny,
  1053  						},
  1054  					},
  1055  				}),
  1056  				legacyPolicy(&Policy{
  1057  					Sessions: []*SessionPolicy{
  1058  						&SessionPolicy{
  1059  							Node:   "child-nope",
  1060  							Policy: PolicyDeny,
  1061  						},
  1062  						&SessionPolicy{
  1063  							Node:   "child-ro",
  1064  							Policy: PolicyRead,
  1065  						},
  1066  						&SessionPolicy{
  1067  							Node:   "child-rw",
  1068  							Policy: PolicyWrite,
  1069  						},
  1070  						&SessionPolicy{
  1071  							Node:   "override",
  1072  							Policy: PolicyWrite,
  1073  						},
  1074  					},
  1075  				}),
  1076  			},
  1077  			checks: []aclCheck{
  1078  				{name: "DefaultReadAllowed", prefix: "nope", check: checkAllowSessionRead},
  1079  				{name: "DefaultWriteAllowed", prefix: "nope", check: checkAllowSessionWrite},
  1080  				{name: "DenyReadDenied", prefix: "root-nope", check: checkDenySessionRead},
  1081  				{name: "DenyWriteDenied", prefix: "root-nope", check: checkDenySessionWrite},
  1082  				{name: "ROReadAllowed", prefix: "root-ro", check: checkAllowSessionRead},
  1083  				{name: "ROWriteDenied", prefix: "root-ro", check: checkDenySessionWrite},
  1084  				{name: "RWReadAllowed", prefix: "root-rw", check: checkAllowSessionRead},
  1085  				{name: "RWWriteAllowed", prefix: "root-rw", check: checkAllowSessionWrite},
  1086  				{name: "DenySuffixReadDenied", prefix: "root-nope-prefix", check: checkDenySessionRead},
  1087  				{name: "DenySuffixWriteDenied", prefix: "root-nope-prefix", check: checkDenySessionWrite},
  1088  				{name: "ROSuffixReadAllowed", prefix: "root-ro-prefix", check: checkAllowSessionRead},
  1089  				{name: "ROSuffixWriteDenied", prefix: "root-ro-prefix", check: checkDenySessionWrite},
  1090  				{name: "RWSuffixReadAllowed", prefix: "root-rw-prefix", check: checkAllowSessionRead},
  1091  				{name: "RWSuffixWriteAllowed", prefix: "root-rw-prefix", check: checkAllowSessionWrite},
  1092  				{name: "ChildDenyReadDenied", prefix: "child-nope", check: checkDenySessionRead},
  1093  				{name: "ChildDenyWriteDenied", prefix: "child-nope", check: checkDenySessionWrite},
  1094  				{name: "ChildROReadAllowed", prefix: "child-ro", check: checkAllowSessionRead},
  1095  				{name: "ChildROWriteDenied", prefix: "child-ro", check: checkDenySessionWrite},
  1096  				{name: "ChildRWReadAllowed", prefix: "child-rw", check: checkAllowSessionRead},
  1097  				{name: "ChildRWWriteAllowed", prefix: "child-rw", check: checkAllowSessionWrite},
  1098  				{name: "ChildDenySuffixReadDenied", prefix: "child-nope-prefix", check: checkDenySessionRead},
  1099  				{name: "ChildDenySuffixWriteDenied", prefix: "child-nope-prefix", check: checkDenySessionWrite},
  1100  				{name: "ChildROSuffixReadAllowed", prefix: "child-ro-prefix", check: checkAllowSessionRead},
  1101  				{name: "ChildROSuffixWriteDenied", prefix: "child-ro-prefix", check: checkDenySessionWrite},
  1102  				{name: "ChildRWSuffixReadAllowed", prefix: "child-rw-prefix", check: checkAllowSessionRead},
  1103  				{name: "ChildRWSuffixWriteAllowed", prefix: "child-rw-prefix", check: checkAllowSessionWrite},
  1104  				{name: "ChildOverrideReadAllowed", prefix: "override", check: checkAllowSessionRead},
  1105  				{name: "ChildOverrideWriteAllowed", prefix: "override", check: checkAllowSessionWrite},
  1106  			},
  1107  		},
  1108  		{
  1109  			name:          "Parent",
  1110  			defaultPolicy: DenyAll(),
  1111  			policyStack: []*Policy{
  1112  				legacyPolicy(&Policy{
  1113  					Keys: []*KeyPolicy{
  1114  						&KeyPolicy{
  1115  							Prefix: "foo/",
  1116  							Policy: PolicyWrite,
  1117  						},
  1118  						&KeyPolicy{
  1119  							Prefix: "bar/",
  1120  							Policy: PolicyRead,
  1121  						},
  1122  					},
  1123  					PreparedQueries: []*PreparedQueryPolicy{
  1124  						&PreparedQueryPolicy{
  1125  							Prefix: "other",
  1126  							Policy: PolicyWrite,
  1127  						},
  1128  						&PreparedQueryPolicy{
  1129  							Prefix: "foo",
  1130  							Policy: PolicyRead,
  1131  						},
  1132  					},
  1133  					Services: []*ServicePolicy{
  1134  						&ServicePolicy{
  1135  							Name:   "other",
  1136  							Policy: PolicyWrite,
  1137  						},
  1138  						&ServicePolicy{
  1139  							Name:   "foo",
  1140  							Policy: PolicyRead,
  1141  						},
  1142  					},
  1143  				}),
  1144  				legacyPolicy(&Policy{
  1145  					Keys: []*KeyPolicy{
  1146  						&KeyPolicy{
  1147  							Prefix: "foo/priv/",
  1148  							Policy: PolicyRead,
  1149  						},
  1150  						&KeyPolicy{
  1151  							Prefix: "bar/",
  1152  							Policy: PolicyDeny,
  1153  						},
  1154  						&KeyPolicy{
  1155  							Prefix: "zip/",
  1156  							Policy: PolicyRead,
  1157  						},
  1158  					},
  1159  					PreparedQueries: []*PreparedQueryPolicy{
  1160  						&PreparedQueryPolicy{
  1161  							Prefix: "bar",
  1162  							Policy: PolicyDeny,
  1163  						},
  1164  					},
  1165  					Services: []*ServicePolicy{
  1166  						&ServicePolicy{
  1167  							Name:   "bar",
  1168  							Policy: PolicyDeny,
  1169  						},
  1170  					},
  1171  				}),
  1172  			},
  1173  			checks: []aclCheck{
  1174  				{name: "KeyReadDenied", prefix: "other", check: checkDenyKeyRead},
  1175  				{name: "KeyWriteDenied", prefix: "other", check: checkDenyKeyWrite},
  1176  				{name: "KeyWritePrefixDenied", prefix: "other", check: checkDenyKeyWritePrefix},
  1177  				{name: "KeyReadAllowed", prefix: "foo/test", check: checkAllowKeyRead},
  1178  				{name: "KeyWriteAllowed", prefix: "foo/test", check: checkAllowKeyWrite},
  1179  				{name: "KeyWritePrefixAllowed", prefix: "foo/test", check: checkAllowKeyWritePrefix},
  1180  				{name: "KeyReadAllowed", prefix: "foo/priv/test", check: checkAllowKeyRead},
  1181  				{name: "KeyWriteDenied", prefix: "foo/priv/test", check: checkDenyKeyWrite},
  1182  				{name: "KeyWritePrefixDenied", prefix: "foo/priv/test", check: checkDenyKeyWritePrefix},
  1183  				{name: "KeyReadDenied", prefix: "bar/any", check: checkDenyKeyRead},
  1184  				{name: "KeyWriteDenied", prefix: "bar/any", check: checkDenyKeyWrite},
  1185  				{name: "KeyWritePrefixDenied", prefix: "bar/any", check: checkDenyKeyWritePrefix},
  1186  				{name: "KeyReadAllowed", prefix: "zip/test", check: checkAllowKeyRead},
  1187  				{name: "KeyWriteDenied", prefix: "zip/test", check: checkDenyKeyWrite},
  1188  				{name: "KeyWritePrefixDenied", prefix: "zip/test", check: checkDenyKeyWritePrefix},
  1189  				{name: "ServiceReadDenied", prefix: "fail", check: checkDenyServiceRead},
  1190  				{name: "ServiceWriteDenied", prefix: "fail", check: checkDenyServiceWrite},
  1191  				{name: "ServiceReadAllowed", prefix: "other", check: checkAllowServiceRead},
  1192  				{name: "ServiceWriteAllowed", prefix: "other", check: checkAllowServiceWrite},
  1193  				{name: "ServiceReadAllowed", prefix: "foo", check: checkAllowServiceRead},
  1194  				{name: "ServiceWriteDenied", prefix: "foo", check: checkDenyServiceWrite},
  1195  				{name: "ServiceReadDenied", prefix: "bar", check: checkDenyServiceRead},
  1196  				{name: "ServiceWriteDenied", prefix: "bar", check: checkDenyServiceWrite},
  1197  				{name: "PreparedQueryReadAllowed", prefix: "foo", check: checkAllowPreparedQueryRead},
  1198  				{name: "PreparedQueryWriteDenied", prefix: "foo", check: checkDenyPreparedQueryWrite},
  1199  				{name: "PreparedQueryReadAllowed", prefix: "foobar", check: checkAllowPreparedQueryRead},
  1200  				{name: "PreparedQueryWriteDenied", prefix: "foobar", check: checkDenyPreparedQueryWrite},
  1201  				{name: "PreparedQueryReadDenied", prefix: "bar", check: checkDenyPreparedQueryRead},
  1202  				{name: "PreparedQueryWriteDenied", prefix: "bar", check: checkDenyPreparedQueryWrite},
  1203  				{name: "PreparedQueryReadDenied", prefix: "barbaz", check: checkDenyPreparedQueryRead},
  1204  				{name: "PreparedQueryWriteDenied", prefix: "barbaz", check: checkDenyPreparedQueryWrite},
  1205  				{name: "PreparedQueryReadDenied", prefix: "baz", check: checkDenyPreparedQueryRead},
  1206  				{name: "PreparedQueryWriteDenied", prefix: "baz", check: checkDenyPreparedQueryWrite},
  1207  				{name: "PreparedQueryReadDenied", prefix: "nope", check: checkDenyPreparedQueryRead},
  1208  				{name: "PreparedQueryWriteDenied", prefix: "nope", check: checkDenyPreparedQueryWrite},
  1209  				{name: "ACLReadDenied", check: checkDenyACLRead},
  1210  				{name: "ACLWriteDenied", check: checkDenyACLWrite},
  1211  				{name: "SnapshotDenied", check: checkDenySnapshot},
  1212  				{name: "IntentionDefaultAllowDenied", check: checkDenyIntentionDefaultAllow},
  1213  			},
  1214  		},
  1215  		{
  1216  			name:          "ComplexDefaultAllow",
  1217  			defaultPolicy: AllowAll(),
  1218  			policyStack: []*Policy{
  1219  				legacyPolicy(&Policy{
  1220  					Events: []*EventPolicy{
  1221  						&EventPolicy{
  1222  							Event:  "",
  1223  							Policy: PolicyRead,
  1224  						},
  1225  						&EventPolicy{
  1226  							Event:  "foo",
  1227  							Policy: PolicyWrite,
  1228  						},
  1229  						&EventPolicy{
  1230  							Event:  "bar",
  1231  							Policy: PolicyDeny,
  1232  						},
  1233  					},
  1234  					Keys: []*KeyPolicy{
  1235  						&KeyPolicy{
  1236  							Prefix: "foo/",
  1237  							Policy: PolicyWrite,
  1238  						},
  1239  						&KeyPolicy{
  1240  							Prefix: "foo/priv/",
  1241  							Policy: PolicyDeny,
  1242  						},
  1243  						&KeyPolicy{
  1244  							Prefix: "bar/",
  1245  							Policy: PolicyDeny,
  1246  						},
  1247  						&KeyPolicy{
  1248  							Prefix: "zip/",
  1249  							Policy: PolicyRead,
  1250  						},
  1251  						&KeyPolicy{
  1252  							Prefix: "zap/",
  1253  							Policy: PolicyList,
  1254  						},
  1255  					},
  1256  					PreparedQueries: []*PreparedQueryPolicy{
  1257  						&PreparedQueryPolicy{
  1258  							Prefix: "",
  1259  							Policy: PolicyRead,
  1260  						},
  1261  						&PreparedQueryPolicy{
  1262  							Prefix: "foo",
  1263  							Policy: PolicyWrite,
  1264  						},
  1265  						&PreparedQueryPolicy{
  1266  							Prefix: "bar",
  1267  							Policy: PolicyDeny,
  1268  						},
  1269  						&PreparedQueryPolicy{
  1270  							Prefix: "zoo",
  1271  							Policy: PolicyWrite,
  1272  						},
  1273  					},
  1274  					Services: []*ServicePolicy{
  1275  						&ServicePolicy{
  1276  							Name:   "",
  1277  							Policy: PolicyWrite,
  1278  						},
  1279  						&ServicePolicy{
  1280  							Name:   "foo",
  1281  							Policy: PolicyRead,
  1282  						},
  1283  						&ServicePolicy{
  1284  							Name:   "bar",
  1285  							Policy: PolicyDeny,
  1286  						},
  1287  						&ServicePolicy{
  1288  							Name:       "barfoo",
  1289  							Policy:     PolicyWrite,
  1290  							Intentions: PolicyWrite,
  1291  						},
  1292  						&ServicePolicy{
  1293  							Name:       "intbaz",
  1294  							Policy:     PolicyWrite,
  1295  							Intentions: PolicyDeny,
  1296  						},
  1297  					},
  1298  				}),
  1299  			},
  1300  			checks: []aclCheck{
  1301  				{name: "KeyReadAllowed", prefix: "other", check: checkAllowKeyRead},
  1302  				{name: "KeyWriteAllowed", prefix: "other", check: checkAllowKeyWrite},
  1303  				{name: "KeyWritePrefixAllowed", prefix: "other", check: checkAllowKeyWritePrefix},
  1304  				{name: "KeyListAllowed", prefix: "other", check: checkAllowKeyList},
  1305  				{name: "KeyReadAllowed", prefix: "foo/test", check: checkAllowKeyRead},
  1306  				{name: "KeyWriteAllowed", prefix: "foo/test", check: checkAllowKeyWrite},
  1307  				{name: "KeyWritePrefixAllowed", prefix: "foo/test", check: checkAllowKeyWritePrefix},
  1308  				{name: "KeyListAllowed", prefix: "foo/test", check: checkAllowKeyList},
  1309  				{name: "KeyReadDenied", prefix: "foo/priv/test", check: checkDenyKeyRead},
  1310  				{name: "KeyWriteDenied", prefix: "foo/priv/test", check: checkDenyKeyWrite},
  1311  				{name: "KeyWritePrefixDenied", prefix: "foo/priv/test", check: checkDenyKeyWritePrefix},
  1312  				{name: "KeyListDenied", prefix: "foo/priv/test", check: checkDenyKeyList},
  1313  				{name: "KeyReadDenied", prefix: "bar/any", check: checkDenyKeyRead},
  1314  				{name: "KeyWriteDenied", prefix: "bar/any", check: checkDenyKeyWrite},
  1315  				{name: "KeyWritePrefixDenied", prefix: "bar/any", check: checkDenyKeyWritePrefix},
  1316  				{name: "KeyListDenied", prefix: "bar/any", check: checkDenyKeyList},
  1317  				{name: "KeyReadAllowed", prefix: "zip/test", check: checkAllowKeyRead},
  1318  				{name: "KeyWriteDenied", prefix: "zip/test", check: checkDenyKeyWrite},
  1319  				{name: "KeyWritePrefixDenied", prefix: "zip/test", check: checkDenyKeyWritePrefix},
  1320  				{name: "KeyListDenied", prefix: "zip/test", check: checkDenyKeyList},
  1321  				{name: "KeyReadAllowed", prefix: "foo/", check: checkAllowKeyRead},
  1322  				{name: "KeyWriteAllowed", prefix: "foo/", check: checkAllowKeyWrite},
  1323  				{name: "KeyWritePrefixDenied", prefix: "foo/", check: checkDenyKeyWritePrefix},
  1324  				{name: "KeyListAllowed", prefix: "foo/", check: checkAllowKeyList},
  1325  				{name: "KeyReadAllowed", prefix: "", check: checkAllowKeyRead},
  1326  				{name: "KeyWriteAllowed", prefix: "", check: checkAllowKeyWrite},
  1327  				{name: "KeyWritePrefixDenied", prefix: "", check: checkDenyKeyWritePrefix},
  1328  				{name: "KeyListAllowed", prefix: "", check: checkAllowKeyList},
  1329  				{name: "KeyReadAllowed", prefix: "zap/test", check: checkAllowKeyRead},
  1330  				{name: "KeyWriteDenied", prefix: "zap/test", check: checkDenyKeyWrite},
  1331  				{name: "KeyWritePrefixDenied", prefix: "zap/test", check: checkDenyKeyWritePrefix},
  1332  				{name: "KeyListAllowed", prefix: "zap/test", check: checkAllowKeyList},
  1333  				{name: "IntentionReadAllowed", prefix: "other", check: checkAllowIntentionRead},
  1334  				{name: "IntentionWriteDenied", prefix: "other", check: checkDenyIntentionWrite},
  1335  				{name: "IntentionReadAllowed", prefix: "foo", check: checkAllowIntentionRead},
  1336  				{name: "IntentionWriteDenied", prefix: "foo", check: checkDenyIntentionWrite},
  1337  				{name: "IntentionReadDenied", prefix: "bar", check: checkDenyIntentionRead},
  1338  				{name: "IntentionWriteDenied", prefix: "bar", check: checkDenyIntentionWrite},
  1339  				{name: "IntentionReadAllowed", prefix: "foobar", check: checkAllowIntentionRead},
  1340  				{name: "IntentionWriteDenied", prefix: "foobar", check: checkDenyIntentionWrite},
  1341  				{name: "IntentionReadDenied", prefix: "barfo", check: checkDenyIntentionRead},
  1342  				{name: "IntentionWriteDenied", prefix: "barfo", check: checkDenyIntentionWrite},
  1343  				{name: "IntentionReadAllowed", prefix: "barfoo", check: checkAllowIntentionRead},
  1344  				{name: "IntentionWriteAllowed", prefix: "barfoo", check: checkAllowIntentionWrite},
  1345  				{name: "IntentionReadAllowed", prefix: "barfoo2", check: checkAllowIntentionRead},
  1346  				{name: "IntentionWriteAllowed", prefix: "barfoo2", check: checkAllowIntentionWrite},
  1347  				{name: "IntentionReadDenied", prefix: "intbaz", check: checkDenyIntentionRead},
  1348  				{name: "IntentionWriteDenied", prefix: "intbaz", check: checkDenyIntentionWrite},
  1349  				{name: "IntentionDefaultAllowAllowed", check: checkAllowIntentionDefaultAllow},
  1350  				{name: "ServiceReadAllowed", prefix: "other", check: checkAllowServiceRead},
  1351  				{name: "ServiceWriteAllowed", prefix: "other", check: checkAllowServiceWrite},
  1352  				{name: "ServiceReadAllowed", prefix: "foo", check: checkAllowServiceRead},
  1353  				{name: "ServiceWriteDenied", prefix: "foo", check: checkDenyServiceWrite},
  1354  				{name: "ServiceReadDenied", prefix: "bar", check: checkDenyServiceRead},
  1355  				{name: "ServiceWriteDenied", prefix: "bar", check: checkDenyServiceWrite},
  1356  				{name: "ServiceReadAllowed", prefix: "foobar", check: checkAllowServiceRead},
  1357  				{name: "ServiceWriteDenied", prefix: "foobar", check: checkDenyServiceWrite},
  1358  				{name: "ServiceReadDenied", prefix: "barfo", check: checkDenyServiceRead},
  1359  				{name: "ServiceWriteDenied", prefix: "barfo", check: checkDenyServiceWrite},
  1360  				{name: "ServiceReadAllowed", prefix: "barfoo", check: checkAllowServiceRead},
  1361  				{name: "ServiceWriteAllowed", prefix: "barfoo", check: checkAllowServiceWrite},
  1362  				{name: "ServiceReadAllowed", prefix: "barfoo2", check: checkAllowServiceRead},
  1363  				{name: "ServiceWriteAllowed", prefix: "barfoo2", check: checkAllowServiceWrite},
  1364  				{name: "EventReadAllowed", prefix: "foo", check: checkAllowEventRead},
  1365  				{name: "EventWriteAllowed", prefix: "foo", check: checkAllowEventWrite},
  1366  				{name: "EventReadAllowed", prefix: "foobar", check: checkAllowEventRead},
  1367  				{name: "EventWriteAllowed", prefix: "foobar", check: checkAllowEventWrite},
  1368  				{name: "EventReadDenied", prefix: "bar", check: checkDenyEventRead},
  1369  				{name: "EventWriteDenied", prefix: "bar", check: checkDenyEventWrite},
  1370  				{name: "EventReadDenied", prefix: "barbaz", check: checkDenyEventRead},
  1371  				{name: "EventWriteDenied", prefix: "barbaz", check: checkDenyEventWrite},
  1372  				{name: "EventReadAllowed", prefix: "baz", check: checkAllowEventRead},
  1373  				{name: "EventWriteDenied", prefix: "baz", check: checkDenyEventWrite},
  1374  				{name: "PreparedQueryReadAllowed", prefix: "foo", check: checkAllowPreparedQueryRead},
  1375  				{name: "PreparedQueryWriteAllowed", prefix: "foo", check: checkAllowPreparedQueryWrite},
  1376  				{name: "PreparedQueryReadAllowed", prefix: "foobar", check: checkAllowPreparedQueryRead},
  1377  				{name: "PreparedQueryWriteAllowed", prefix: "foobar", check: checkAllowPreparedQueryWrite},
  1378  				{name: "PreparedQueryReadDenied", prefix: "bar", check: checkDenyPreparedQueryRead},
  1379  				{name: "PreparedQueryWriteDenied", prefix: "bar", check: checkDenyPreparedQueryWrite},
  1380  				{name: "PreparedQueryReadDenied", prefix: "barbaz", check: checkDenyPreparedQueryRead},
  1381  				{name: "PreparedQueryWriteDenied", prefix: "barbaz", check: checkDenyPreparedQueryWrite},
  1382  				{name: "PreparedQueryReadAllowed", prefix: "baz", check: checkAllowPreparedQueryRead},
  1383  				{name: "PreparedQueryWriteDenied", prefix: "baz", check: checkDenyPreparedQueryWrite},
  1384  				{name: "PreparedQueryReadAllowed", prefix: "nope", check: checkAllowPreparedQueryRead},
  1385  				{name: "PreparedQueryWriteDenied", prefix: "nope", check: checkDenyPreparedQueryWrite},
  1386  				{name: "PreparedQueryReadAllowed", prefix: "zoo", check: checkAllowPreparedQueryRead},
  1387  				{name: "PreparedQueryWriteAllowed", prefix: "zoo", check: checkAllowPreparedQueryWrite},
  1388  				{name: "PreparedQueryReadAllowed", prefix: "zookeeper", check: checkAllowPreparedQueryRead},
  1389  				{name: "PreparedQueryWriteAllowed", prefix: "zookeeper", check: checkAllowPreparedQueryWrite},
  1390  			},
  1391  		},
  1392  		{
  1393  			name:          "ExactMatchPrecedence",
  1394  			defaultPolicy: DenyAll(),
  1395  			policyStack: []*Policy{
  1396  				&Policy{
  1397  					Agents: []*AgentPolicy{
  1398  						&AgentPolicy{
  1399  							Node:   "foo",
  1400  							Policy: PolicyWrite,
  1401  						},
  1402  						&AgentPolicy{
  1403  							Node:   "football",
  1404  							Policy: PolicyDeny,
  1405  						},
  1406  					},
  1407  					AgentPrefixes: []*AgentPolicy{
  1408  						&AgentPolicy{
  1409  							Node:   "foot",
  1410  							Policy: PolicyRead,
  1411  						},
  1412  						&AgentPolicy{
  1413  							Node:   "fo",
  1414  							Policy: PolicyRead,
  1415  						},
  1416  					},
  1417  					Keys: []*KeyPolicy{
  1418  						&KeyPolicy{
  1419  							Prefix: "foo",
  1420  							Policy: PolicyWrite,
  1421  						},
  1422  						&KeyPolicy{
  1423  							Prefix: "football",
  1424  							Policy: PolicyDeny,
  1425  						},
  1426  					},
  1427  					KeyPrefixes: []*KeyPolicy{
  1428  						&KeyPolicy{
  1429  							Prefix: "foot",
  1430  							Policy: PolicyRead,
  1431  						},
  1432  						&KeyPolicy{
  1433  							Prefix: "fo",
  1434  							Policy: PolicyRead,
  1435  						},
  1436  					},
  1437  					Nodes: []*NodePolicy{
  1438  						&NodePolicy{
  1439  							Name:   "foo",
  1440  							Policy: PolicyWrite,
  1441  						},
  1442  						&NodePolicy{
  1443  							Name:   "football",
  1444  							Policy: PolicyDeny,
  1445  						},
  1446  					},
  1447  					NodePrefixes: []*NodePolicy{
  1448  						&NodePolicy{
  1449  							Name:   "foot",
  1450  							Policy: PolicyRead,
  1451  						},
  1452  						&NodePolicy{
  1453  							Name:   "fo",
  1454  							Policy: PolicyRead,
  1455  						},
  1456  					},
  1457  					Services: []*ServicePolicy{
  1458  						&ServicePolicy{
  1459  							Name:       "foo",
  1460  							Policy:     PolicyWrite,
  1461  							Intentions: PolicyWrite,
  1462  						},
  1463  						&ServicePolicy{
  1464  							Name:   "football",
  1465  							Policy: PolicyDeny,
  1466  						},
  1467  					},
  1468  					ServicePrefixes: []*ServicePolicy{
  1469  						&ServicePolicy{
  1470  							Name:       "foot",
  1471  							Policy:     PolicyRead,
  1472  							Intentions: PolicyRead,
  1473  						},
  1474  						&ServicePolicy{
  1475  							Name:       "fo",
  1476  							Policy:     PolicyRead,
  1477  							Intentions: PolicyRead,
  1478  						},
  1479  					},
  1480  					Sessions: []*SessionPolicy{
  1481  						&SessionPolicy{
  1482  							Node:   "foo",
  1483  							Policy: PolicyWrite,
  1484  						},
  1485  						&SessionPolicy{
  1486  							Node:   "football",
  1487  							Policy: PolicyDeny,
  1488  						},
  1489  					},
  1490  					SessionPrefixes: []*SessionPolicy{
  1491  						&SessionPolicy{
  1492  							Node:   "foot",
  1493  							Policy: PolicyRead,
  1494  						},
  1495  						&SessionPolicy{
  1496  							Node:   "fo",
  1497  							Policy: PolicyRead,
  1498  						},
  1499  					},
  1500  					Events: []*EventPolicy{
  1501  						&EventPolicy{
  1502  							Event:  "foo",
  1503  							Policy: PolicyWrite,
  1504  						},
  1505  						&EventPolicy{
  1506  							Event:  "football",
  1507  							Policy: PolicyDeny,
  1508  						},
  1509  					},
  1510  					EventPrefixes: []*EventPolicy{
  1511  						&EventPolicy{
  1512  							Event:  "foot",
  1513  							Policy: PolicyRead,
  1514  						},
  1515  						&EventPolicy{
  1516  							Event:  "fo",
  1517  							Policy: PolicyRead,
  1518  						},
  1519  					},
  1520  					PreparedQueries: []*PreparedQueryPolicy{
  1521  						&PreparedQueryPolicy{
  1522  							Prefix: "foo",
  1523  							Policy: PolicyWrite,
  1524  						},
  1525  						&PreparedQueryPolicy{
  1526  							Prefix: "football",
  1527  							Policy: PolicyDeny,
  1528  						},
  1529  					},
  1530  					PreparedQueryPrefixes: []*PreparedQueryPolicy{
  1531  						&PreparedQueryPolicy{
  1532  							Prefix: "foot",
  1533  							Policy: PolicyRead,
  1534  						},
  1535  						&PreparedQueryPolicy{
  1536  							Prefix: "fo",
  1537  							Policy: PolicyRead,
  1538  						},
  1539  					},
  1540  				},
  1541  			},
  1542  			checks: []aclCheck{
  1543  				{name: "AgentReadPrefixAllowed", prefix: "fo", check: checkAllowAgentRead},
  1544  				{name: "AgentWritePrefixDenied", prefix: "fo", check: checkDenyAgentWrite},
  1545  				{name: "AgentReadPrefixAllowed", prefix: "for", check: checkAllowAgentRead},
  1546  				{name: "AgentWritePrefixDenied", prefix: "for", check: checkDenyAgentWrite},
  1547  				{name: "AgentReadAllowed", prefix: "foo", check: checkAllowAgentRead},
  1548  				{name: "AgentWriteAllowed", prefix: "foo", check: checkAllowAgentWrite},
  1549  				{name: "AgentReadPrefixAllowed", prefix: "foot", check: checkAllowAgentRead},
  1550  				{name: "AgentWritePrefixDenied", prefix: "foot", check: checkDenyAgentWrite},
  1551  				{name: "AgentReadPrefixAllowed", prefix: "foot2", check: checkAllowAgentRead},
  1552  				{name: "AgentWritePrefixDenied", prefix: "foot2", check: checkDenyAgentWrite},
  1553  				{name: "AgentReadPrefixAllowed", prefix: "food", check: checkAllowAgentRead},
  1554  				{name: "AgentWritePrefixDenied", prefix: "food", check: checkDenyAgentWrite},
  1555  				{name: "AgentReadDenied", prefix: "football", check: checkDenyAgentRead},
  1556  				{name: "AgentWriteDenied", prefix: "football", check: checkDenyAgentWrite},
  1557  
  1558  				{name: "KeyReadPrefixAllowed", prefix: "fo", check: checkAllowKeyRead},
  1559  				{name: "KeyWritePrefixDenied", prefix: "fo", check: checkDenyKeyWrite},
  1560  				{name: "KeyReadPrefixAllowed", prefix: "for", check: checkAllowKeyRead},
  1561  				{name: "KeyWritePrefixDenied", prefix: "for", check: checkDenyKeyWrite},
  1562  				{name: "KeyReadAllowed", prefix: "foo", check: checkAllowKeyRead},
  1563  				{name: "KeyWriteAllowed", prefix: "foo", check: checkAllowKeyWrite},
  1564  				{name: "KeyReadPrefixAllowed", prefix: "foot", check: checkAllowKeyRead},
  1565  				{name: "KeyWritePrefixDenied", prefix: "foot", check: checkDenyKeyWrite},
  1566  				{name: "KeyReadPrefixAllowed", prefix: "foot2", check: checkAllowKeyRead},
  1567  				{name: "KeyWritePrefixDenied", prefix: "foot2", check: checkDenyKeyWrite},
  1568  				{name: "KeyReadPrefixAllowed", prefix: "food", check: checkAllowKeyRead},
  1569  				{name: "KeyWritePrefixDenied", prefix: "food", check: checkDenyKeyWrite},
  1570  				{name: "KeyReadDenied", prefix: "football", check: checkDenyKeyRead},
  1571  				{name: "KeyWriteDenied", prefix: "football", check: checkDenyKeyWrite},
  1572  
  1573  				{name: "NodeReadPrefixAllowed", prefix: "fo", check: checkAllowNodeRead},
  1574  				{name: "NodeWritePrefixDenied", prefix: "fo", check: checkDenyNodeWrite},
  1575  				{name: "NodeReadPrefixAllowed", prefix: "for", check: checkAllowNodeRead},
  1576  				{name: "NodeWritePrefixDenied", prefix: "for", check: checkDenyNodeWrite},
  1577  				{name: "NodeReadAllowed", prefix: "foo", check: checkAllowNodeRead},
  1578  				{name: "NodeWriteAllowed", prefix: "foo", check: checkAllowNodeWrite},
  1579  				{name: "NodeReadPrefixAllowed", prefix: "foot", check: checkAllowNodeRead},
  1580  				{name: "NodeWritePrefixDenied", prefix: "foot", check: checkDenyNodeWrite},
  1581  				{name: "NodeReadPrefixAllowed", prefix: "foot2", check: checkAllowNodeRead},
  1582  				{name: "NodeWritePrefixDenied", prefix: "foot2", check: checkDenyNodeWrite},
  1583  				{name: "NodeReadPrefixAllowed", prefix: "food", check: checkAllowNodeRead},
  1584  				{name: "NodeWritePrefixDenied", prefix: "food", check: checkDenyNodeWrite},
  1585  				{name: "NodeReadDenied", prefix: "football", check: checkDenyNodeRead},
  1586  				{name: "NodeWriteDenied", prefix: "football", check: checkDenyNodeWrite},
  1587  
  1588  				{name: "ServiceReadPrefixAllowed", prefix: "fo", check: checkAllowServiceRead},
  1589  				{name: "ServiceWritePrefixDenied", prefix: "fo", check: checkDenyServiceWrite},
  1590  				{name: "ServiceReadPrefixAllowed", prefix: "for", check: checkAllowServiceRead},
  1591  				{name: "ServiceWritePrefixDenied", prefix: "for", check: checkDenyServiceWrite},
  1592  				{name: "ServiceReadAllowed", prefix: "foo", check: checkAllowServiceRead},
  1593  				{name: "ServiceWriteAllowed", prefix: "foo", check: checkAllowServiceWrite},
  1594  				{name: "ServiceReadPrefixAllowed", prefix: "foot", check: checkAllowServiceRead},
  1595  				{name: "ServiceWritePrefixDenied", prefix: "foot", check: checkDenyServiceWrite},
  1596  				{name: "ServiceReadPrefixAllowed", prefix: "foot2", check: checkAllowServiceRead},
  1597  				{name: "ServiceWritePrefixDenied", prefix: "foot2", check: checkDenyServiceWrite},
  1598  				{name: "ServiceReadPrefixAllowed", prefix: "food", check: checkAllowServiceRead},
  1599  				{name: "ServiceWritePrefixDenied", prefix: "food", check: checkDenyServiceWrite},
  1600  				{name: "ServiceReadDenied", prefix: "football", check: checkDenyServiceRead},
  1601  				{name: "ServiceWriteDenied", prefix: "football", check: checkDenyServiceWrite},
  1602  
  1603  				{name: "NodeReadPrefixAllowed", prefix: "fo", check: checkAllowNodeRead},
  1604  				{name: "NodeWritePrefixDenied", prefix: "fo", check: checkDenyNodeWrite},
  1605  				{name: "NodeReadPrefixAllowed", prefix: "for", check: checkAllowNodeRead},
  1606  				{name: "NodeWritePrefixDenied", prefix: "for", check: checkDenyNodeWrite},
  1607  				{name: "NodeReadAllowed", prefix: "foo", check: checkAllowNodeRead},
  1608  				{name: "NodeWriteAllowed", prefix: "foo", check: checkAllowNodeWrite},
  1609  				{name: "NodeReadPrefixAllowed", prefix: "foot", check: checkAllowNodeRead},
  1610  				{name: "NodeWritePrefixDenied", prefix: "foot", check: checkDenyNodeWrite},
  1611  				{name: "NodeReadPrefixAllowed", prefix: "foot2", check: checkAllowNodeRead},
  1612  				{name: "NodeWritePrefixDenied", prefix: "foot2", check: checkDenyNodeWrite},
  1613  				{name: "NodeReadPrefixAllowed", prefix: "food", check: checkAllowNodeRead},
  1614  				{name: "NodeWritePrefixDenied", prefix: "food", check: checkDenyNodeWrite},
  1615  				{name: "NodeReadDenied", prefix: "football", check: checkDenyNodeRead},
  1616  				{name: "NodeWriteDenied", prefix: "football", check: checkDenyNodeWrite},
  1617  
  1618  				{name: "IntentionReadPrefixAllowed", prefix: "fo", check: checkAllowIntentionRead},
  1619  				{name: "IntentionWritePrefixDenied", prefix: "fo", check: checkDenyIntentionWrite},
  1620  				{name: "IntentionReadPrefixAllowed", prefix: "for", check: checkAllowIntentionRead},
  1621  				{name: "IntentionWritePrefixDenied", prefix: "for", check: checkDenyIntentionWrite},
  1622  				{name: "IntentionReadAllowed", prefix: "foo", check: checkAllowIntentionRead},
  1623  				{name: "IntentionWriteAllowed", prefix: "foo", check: checkAllowIntentionWrite},
  1624  				{name: "IntentionReadPrefixAllowed", prefix: "foot", check: checkAllowIntentionRead},
  1625  				{name: "IntentionWritePrefixDenied", prefix: "foot", check: checkDenyIntentionWrite},
  1626  				{name: "IntentionReadPrefixAllowed", prefix: "foot2", check: checkAllowIntentionRead},
  1627  				{name: "IntentionWritePrefixDenied", prefix: "foot2", check: checkDenyIntentionWrite},
  1628  				{name: "IntentionReadPrefixAllowed", prefix: "food", check: checkAllowIntentionRead},
  1629  				{name: "IntentionWritePrefixDenied", prefix: "food", check: checkDenyIntentionWrite},
  1630  				{name: "IntentionReadDenied", prefix: "football", check: checkDenyIntentionRead},
  1631  				{name: "IntentionWriteDenied", prefix: "football", check: checkDenyIntentionWrite},
  1632  
  1633  				{name: "SessionReadPrefixAllowed", prefix: "fo", check: checkAllowSessionRead},
  1634  				{name: "SessionWritePrefixDenied", prefix: "fo", check: checkDenySessionWrite},
  1635  				{name: "SessionReadPrefixAllowed", prefix: "for", check: checkAllowSessionRead},
  1636  				{name: "SessionWritePrefixDenied", prefix: "for", check: checkDenySessionWrite},
  1637  				{name: "SessionReadAllowed", prefix: "foo", check: checkAllowSessionRead},
  1638  				{name: "SessionWriteAllowed", prefix: "foo", check: checkAllowSessionWrite},
  1639  				{name: "SessionReadPrefixAllowed", prefix: "foot", check: checkAllowSessionRead},
  1640  				{name: "SessionWritePrefixDenied", prefix: "foot", check: checkDenySessionWrite},
  1641  				{name: "SessionReadPrefixAllowed", prefix: "foot2", check: checkAllowSessionRead},
  1642  				{name: "SessionWritePrefixDenied", prefix: "foot2", check: checkDenySessionWrite},
  1643  				{name: "SessionReadPrefixAllowed", prefix: "food", check: checkAllowSessionRead},
  1644  				{name: "SessionWritePrefixDenied", prefix: "food", check: checkDenySessionWrite},
  1645  				{name: "SessionReadDenied", prefix: "football", check: checkDenySessionRead},
  1646  				{name: "SessionWriteDenied", prefix: "football", check: checkDenySessionWrite},
  1647  
  1648  				{name: "EventReadPrefixAllowed", prefix: "fo", check: checkAllowEventRead},
  1649  				{name: "EventWritePrefixDenied", prefix: "fo", check: checkDenyEventWrite},
  1650  				{name: "EventReadPrefixAllowed", prefix: "for", check: checkAllowEventRead},
  1651  				{name: "EventWritePrefixDenied", prefix: "for", check: checkDenyEventWrite},
  1652  				{name: "EventReadAllowed", prefix: "foo", check: checkAllowEventRead},
  1653  				{name: "EventWriteAllowed", prefix: "foo", check: checkAllowEventWrite},
  1654  				{name: "EventReadPrefixAllowed", prefix: "foot", check: checkAllowEventRead},
  1655  				{name: "EventWritePrefixDenied", prefix: "foot", check: checkDenyEventWrite},
  1656  				{name: "EventReadPrefixAllowed", prefix: "foot2", check: checkAllowEventRead},
  1657  				{name: "EventWritePrefixDenied", prefix: "foot2", check: checkDenyEventWrite},
  1658  				{name: "EventReadPrefixAllowed", prefix: "food", check: checkAllowEventRead},
  1659  				{name: "EventWritePrefixDenied", prefix: "food", check: checkDenyEventWrite},
  1660  				{name: "EventReadDenied", prefix: "football", check: checkDenyEventRead},
  1661  				{name: "EventWriteDenied", prefix: "football", check: checkDenyEventWrite},
  1662  
  1663  				{name: "PreparedQueryReadPrefixAllowed", prefix: "fo", check: checkAllowPreparedQueryRead},
  1664  				{name: "PreparedQueryWritePrefixDenied", prefix: "fo", check: checkDenyPreparedQueryWrite},
  1665  				{name: "PreparedQueryReadPrefixAllowed", prefix: "for", check: checkAllowPreparedQueryRead},
  1666  				{name: "PreparedQueryWritePrefixDenied", prefix: "for", check: checkDenyPreparedQueryWrite},
  1667  				{name: "PreparedQueryReadAllowed", prefix: "foo", check: checkAllowPreparedQueryRead},
  1668  				{name: "PreparedQueryWriteAllowed", prefix: "foo", check: checkAllowPreparedQueryWrite},
  1669  				{name: "PreparedQueryReadPrefixAllowed", prefix: "foot", check: checkAllowPreparedQueryRead},
  1670  				{name: "PreparedQueryWritePrefixDenied", prefix: "foot", check: checkDenyPreparedQueryWrite},
  1671  				{name: "PreparedQueryReadPrefixAllowed", prefix: "foot2", check: checkAllowPreparedQueryRead},
  1672  				{name: "PreparedQueryWritePrefixDenied", prefix: "foot2", check: checkDenyPreparedQueryWrite},
  1673  				{name: "PreparedQueryReadPrefixAllowed", prefix: "food", check: checkAllowPreparedQueryRead},
  1674  				{name: "PreparedQueryWritePrefixDenied", prefix: "food", check: checkDenyPreparedQueryWrite},
  1675  				{name: "PreparedQueryReadDenied", prefix: "football", check: checkDenyPreparedQueryRead},
  1676  				{name: "PreparedQueryWriteDenied", prefix: "football", check: checkDenyPreparedQueryWrite},
  1677  			},
  1678  		},
  1679  		{
  1680  			name:          "ACLRead",
  1681  			defaultPolicy: DenyAll(),
  1682  			policyStack: []*Policy{
  1683  				&Policy{
  1684  					ACL: PolicyRead,
  1685  				},
  1686  			},
  1687  			checks: []aclCheck{
  1688  				{name: "ReadAllowed", check: checkAllowACLRead},
  1689  				// in version 1.2.1 and below this would have failed
  1690  				{name: "WriteDenied", check: checkDenyACLWrite},
  1691  			},
  1692  		},
  1693  		{
  1694  			name:          "ACLRead",
  1695  			defaultPolicy: DenyAll(),
  1696  			policyStack: []*Policy{
  1697  				&Policy{
  1698  					ACL: PolicyWrite,
  1699  				},
  1700  			},
  1701  			checks: []aclCheck{
  1702  				{name: "ReadAllowed", check: checkAllowACLRead},
  1703  				// in version 1.2.1 and below this would have failed
  1704  				{name: "WriteAllowed", check: checkAllowACLWrite},
  1705  			},
  1706  		},
  1707  		{
  1708  			name:          "KeyWritePrefixDefaultDeny",
  1709  			defaultPolicy: DenyAll(),
  1710  			policyStack: []*Policy{
  1711  				&Policy{
  1712  					KeyPrefixes: []*KeyPolicy{
  1713  						&KeyPolicy{
  1714  							Prefix: "fo",
  1715  							Policy: PolicyRead,
  1716  						},
  1717  						&KeyPolicy{
  1718  							Prefix: "foo/",
  1719  							Policy: PolicyWrite,
  1720  						},
  1721  						&KeyPolicy{
  1722  							Prefix: "bar/",
  1723  							Policy: PolicyWrite,
  1724  						},
  1725  						&KeyPolicy{
  1726  							Prefix: "baz/",
  1727  							Policy: PolicyWrite,
  1728  						},
  1729  						&KeyPolicy{
  1730  							Prefix: "test/",
  1731  							Policy: PolicyWrite,
  1732  						},
  1733  					},
  1734  					Keys: []*KeyPolicy{
  1735  						&KeyPolicy{
  1736  							Prefix: "foo/bar",
  1737  							Policy: PolicyWrite,
  1738  						},
  1739  						&KeyPolicy{
  1740  							Prefix: "bar/baz",
  1741  							Policy: PolicyRead,
  1742  						},
  1743  					},
  1744  				},
  1745  			},
  1746  			checks: []aclCheck{
  1747  				// Ensure we deny access if the best match key_prefix rule does not grant
  1748  				// write access (disregards both the default policy and any other rules with
  1749  				// segments that may fall within the given kv prefix)
  1750  				{name: "DeniedTopLevelPrefix", prefix: "foo", check: checkDenyKeyWritePrefix},
  1751  				// Allow recursive KV writes when we have a prefix rule that allows it and no
  1752  				// other rules with segments that fall within the requested kv prefix to be written.
  1753  				{name: "AllowedTopLevelPrefix", prefix: "baz/", check: checkAllowKeyWritePrefix},
  1754  				// Ensure we allow recursive KV writes when we have a prefix rule that would allow it
  1755  				// and all other rules with segments prefixed by the kv prefix to be written also allow
  1756  				// write access.
  1757  				{name: "AllowedPrefixWithNestedWrite", prefix: "foo/", check: checkAllowKeyWritePrefix},
  1758  				// Ensure that we deny recursive KV writes when they would be allowed for a prefix but
  1759  				// denied by either an exact match rule or prefix match rule for a segment prefixed by
  1760  				// the kv prefix being checked against.
  1761  				{name: "DenyPrefixWithNestedRead", prefix: "bar/", check: checkDenyKeyWritePrefix},
  1762  				// Ensure that the default deny policy is used when there is no key_prefix rule
  1763  				// for the given kv segment regardless of any rules that would grant write access
  1764  				// to segments prefixed by the kv prefix being checked against.
  1765  				{name: "DenyNoPrefixMatch", prefix: "te", check: checkDenyKeyWritePrefix},
  1766  			},
  1767  		},
  1768  		{
  1769  			name:          "KeyWritePrefixDefaultAllow",
  1770  			defaultPolicy: AllowAll(),
  1771  			policyStack: []*Policy{
  1772  				&Policy{
  1773  					Keys: []*KeyPolicy{
  1774  						&KeyPolicy{
  1775  							Prefix: "foo/bar",
  1776  							Policy: PolicyRead,
  1777  						},
  1778  					},
  1779  				},
  1780  			},
  1781  			checks: []aclCheck{
  1782  				// Ensure that we deny a key prefix write when a rule for a key within our prefix
  1783  				// doesn't allow writing and the default policy is to allow
  1784  				{name: "KeyWritePrefixDenied", prefix: "foo", check: checkDenyKeyWritePrefix},
  1785  				// Ensure that the default allow policy is used when there is no prefix rule
  1786  				// and there are no other rules regarding keys within that prefix to be written.
  1787  				{name: "KeyWritePrefixAllowed", prefix: "bar", check: checkAllowKeyWritePrefix},
  1788  			},
  1789  		},
  1790  	}
  1791  
  1792  	for _, tcase := range tests {
  1793  		t.Run(tcase.name, func(t *testing.T) {
  1794  			acl := tcase.defaultPolicy
  1795  			for _, policy := range tcase.policyStack {
  1796  				newACL, err := NewPolicyAuthorizer(acl, []*Policy{policy}, nil)
  1797  				require.NoError(t, err)
  1798  				acl = newACL
  1799  			}
  1800  
  1801  			for _, check := range tcase.checks {
  1802  				checkName := check.name
  1803  				if check.prefix != "" {
  1804  					checkName = fmt.Sprintf("%s.Prefix(%s)", checkName, check.prefix)
  1805  				}
  1806  				t.Run(checkName, func(t *testing.T) {
  1807  					check.check(t, acl, check.prefix)
  1808  				})
  1809  			}
  1810  		})
  1811  	}
  1812  }
  1813  
  1814  func TestRootAuthorizer(t *testing.T) {
  1815  	require.Equal(t, AllowAll(), RootAuthorizer("allow"))
  1816  	require.Equal(t, DenyAll(), RootAuthorizer("deny"))
  1817  	require.Equal(t, ManageAll(), RootAuthorizer("manage"))
  1818  	require.Nil(t, RootAuthorizer("foo"))
  1819  }
  1820  
  1821  func TestACLEnforce(t *testing.T) {
  1822  	type enforceTest struct {
  1823  		name     string
  1824  		rule     string
  1825  		required string
  1826  		allow    bool
  1827  		recurse  bool
  1828  	}
  1829  
  1830  	tests := []enforceTest{
  1831  		{
  1832  			name:     "RuleNoneRequireRead",
  1833  			rule:     "",
  1834  			required: PolicyRead,
  1835  			allow:    false,
  1836  			recurse:  true,
  1837  		},
  1838  		{
  1839  			name:     "RuleNoneRequireWrite",
  1840  			rule:     "",
  1841  			required: PolicyWrite,
  1842  			allow:    false,
  1843  			recurse:  true,
  1844  		},
  1845  		{
  1846  			name:     "RuleNoneRequireList",
  1847  			rule:     "",
  1848  			required: PolicyList,
  1849  			allow:    false,
  1850  			recurse:  true,
  1851  		},
  1852  		{
  1853  			name:     "RuleReadRequireRead",
  1854  			rule:     PolicyRead,
  1855  			required: PolicyRead,
  1856  			allow:    true,
  1857  			recurse:  false,
  1858  		},
  1859  		{
  1860  			name:     "RuleReadRequireWrite",
  1861  			rule:     PolicyRead,
  1862  			required: PolicyWrite,
  1863  			allow:    false,
  1864  			recurse:  false,
  1865  		},
  1866  		{
  1867  			name:     "RuleReadRequireList",
  1868  			rule:     PolicyRead,
  1869  			required: PolicyList,
  1870  			allow:    false,
  1871  			recurse:  false,
  1872  		},
  1873  		{
  1874  			name:     "RuleListRequireRead",
  1875  			rule:     PolicyList,
  1876  			required: PolicyRead,
  1877  			allow:    true,
  1878  			recurse:  false,
  1879  		},
  1880  		{
  1881  			name:     "RuleListRequireWrite",
  1882  			rule:     PolicyList,
  1883  			required: PolicyWrite,
  1884  			allow:    false,
  1885  			recurse:  false,
  1886  		},
  1887  		{
  1888  			name:     "RuleListRequireList",
  1889  			rule:     PolicyList,
  1890  			required: PolicyList,
  1891  			allow:    true,
  1892  			recurse:  false,
  1893  		},
  1894  		{
  1895  			name:     "RuleWritetRequireRead",
  1896  			rule:     PolicyWrite,
  1897  			required: PolicyRead,
  1898  			allow:    true,
  1899  			recurse:  false,
  1900  		},
  1901  		{
  1902  			name:     "RuleWritetRequireWrite",
  1903  			rule:     PolicyWrite,
  1904  			required: PolicyWrite,
  1905  			allow:    true,
  1906  			recurse:  false,
  1907  		},
  1908  		{
  1909  			name:     "RuleWritetRequireList",
  1910  			rule:     PolicyWrite,
  1911  			required: PolicyList,
  1912  			allow:    true,
  1913  			recurse:  false,
  1914  		},
  1915  		{
  1916  			name:     "RuleDenyRequireRead",
  1917  			rule:     PolicyDeny,
  1918  			required: PolicyRead,
  1919  			allow:    false,
  1920  			recurse:  false,
  1921  		},
  1922  		{
  1923  			name:     "RuleDenyRequireWrite",
  1924  			rule:     PolicyDeny,
  1925  			required: PolicyWrite,
  1926  			allow:    false,
  1927  			recurse:  false,
  1928  		},
  1929  		{
  1930  			name:     "RuleDenyRequireList",
  1931  			rule:     PolicyDeny,
  1932  			required: PolicyList,
  1933  			allow:    false,
  1934  			recurse:  false,
  1935  		},
  1936  	}
  1937  
  1938  	for _, tcase := range tests {
  1939  		t.Run(tcase.name, func(t *testing.T) {
  1940  			allow, recurse := enforce(tcase.rule, tcase.required)
  1941  			require.Equal(t, tcase.allow, allow)
  1942  			require.Equal(t, tcase.recurse, recurse)
  1943  		})
  1944  	}
  1945  }