Merge pull request #11136 from hashicorp/dnephin/acl-resolver-fix-default-authz

acl: fix default Authorizer for down_policy extend-cache/async-cache
This commit is contained in:
Daniel Nephin 2021-09-29 13:45:12 -04:00 committed by GitHub
commit 33a5448604
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 23 deletions

3
.changelog/11136.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
acl: fixes the fallback behaviour of down_policy with setting extend-cache/async-cache when the token is not cached.
```

View File

@ -255,7 +255,11 @@ func ManageAll() Authorizer {
return manageAll
}
// RootAuthorizer returns a possible Authorizer if the ID matches a root policy
// RootAuthorizer returns a possible Authorizer if the ID matches a root policy.
//
// TODO: rename this function. While the returned authorizer is used as a root
// authorizer in some cases, in others it is not. A more appropriate name might
// be NewAuthorizerFromPolicyName.
func RootAuthorizer(id string) Authorizer {
switch id {
case "allow":

View File

@ -355,7 +355,7 @@ func NewACLResolver(config *ACLResolverConfig) (*ACLResolver, error) {
case "deny":
down = acl.DenyAll()
case "async-cache", "extend-cache":
// Leave the down policy as nil to signal this.
down = acl.RootAuthorizer(config.Config.ACLDefaultPolicy)
default:
return nil, fmt.Errorf("invalid ACL down policy %q", config.Config.ACLDownPolicy)
}

View File

@ -782,8 +782,6 @@ func TestACLResolver_ResolveRootACL(t *testing.T) {
}
func TestACLResolver_DownPolicy(t *testing.T) {
t.Parallel()
requireIdentityCached := func(t *testing.T, r *ACLResolver, id string, present bool, msg string) {
t.Helper()
@ -808,7 +806,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
}
t.Run("Deny", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -833,7 +830,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Allow", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -858,7 +854,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Expired-Policy", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -895,7 +890,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Expired-Role", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -927,7 +921,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Extend-Cache-Policy", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -957,8 +950,28 @@ func TestACLResolver_DownPolicy(t *testing.T) {
require.Equal(t, acl.Allow, authz2.NodeWrite("foo", nil))
})
t.Run("Extend-Cache with no cache entry defaults to default_policy", func(t *testing.T) {
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
localPolicies: true,
localRoles: true,
}
delegate.tokenReadFn = func(*structs.ACLTokenGetRequest, *structs.ACLTokenResponse) error {
return ACLRemoteError{Err: fmt.Errorf("connection problem")}
}
r := newTestACLResolver(t, delegate, func(config *ACLResolverConfig) {
config.Config.ACLDownPolicy = "extend-cache"
})
_, authz, err := r.ResolveTokenToIdentityAndAuthorizer("not-found")
require.NoError(t, err)
require.NotNil(t, authz)
require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil))
})
t.Run("Extend-Cache-Role", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -990,7 +1003,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Extend-Cache-Expired-Policy", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -1027,7 +1039,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Extend-Cache-Expired-Role", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -1060,7 +1071,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Async-Cache-Expired-Policy", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -1108,7 +1118,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Async-Cache-Expired-Role", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -1151,7 +1160,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Extend-Cache-Client-Policy", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -1187,7 +1195,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Extend-Cache-Client-Role", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -1224,7 +1231,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("Async-Cache", func(t *testing.T) {
t.Parallel()
delegate := &ACLResolverTestDelegate{
enabled: true,
datacenter: "dc1",
@ -1266,8 +1272,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("PolicyResolve-TokenNotFound", func(t *testing.T) {
t.Parallel()
_, rawToken, _ := testIdentityForToken("found")
foundToken := rawToken.(*structs.ACLToken)
secretID := foundToken.SecretID
@ -1333,8 +1337,6 @@ func TestACLResolver_DownPolicy(t *testing.T) {
})
t.Run("PolicyResolve-PermissionDenied", func(t *testing.T) {
t.Parallel()
_, rawToken, _ := testIdentityForToken("found")
foundToken := rawToken.(*structs.ACLToken)
secretID := foundToken.SecretID

View File

@ -599,8 +599,10 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'."
token cannot be read from the [`primary_datacenter`](#primary_datacenter) or
leader node, the down policy is applied. In "allow" mode, all actions are permitted,
"deny" restricts all operations, and "extend-cache" allows any cached objects
to be used, ignoring their TTL values. If a non-cached ACL is used, "extend-cache"
acts like "deny". The value "async-cache" acts the same way as "extend-cache"
to be used, ignoring the expiry time of the cached entry. If the request uses an
ACL that is not in the cache, "extend-cache" falls back to the behaviour of
`default_policy`.
The value "async-cache" acts the same way as "extend-cache"
but performs updates asynchronously when ACL is present but its TTL is expired,
thus, if latency is bad between the primary and secondary datacenters, latency
of operations is not impacted.