ACL pkg updates to support Agentless RPCs

For many of the new RPCs that will be added in Consul servers for Agentless work,
the ACL token will need to be authorized for service:write on any service in any namespace in any partition.

The ACL package updates are to make ServiceWriteAny related helpers available on the different authorizers.
This commit is contained in:
Riddhi Shah 2022-03-24 16:55:05 +05:30
parent 8f98bbda75
commit 96e0d8fd0d
8 changed files with 49 additions and 1 deletions

View File

@ -145,6 +145,10 @@ func checkAllowServiceWrite(t *testing.T, authz Authorizer, prefix string, entCt
require.Equal(t, Allow, authz.ServiceWrite(prefix, entCtx))
}
func checkAllowServiceWriteAny(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) {
require.Equal(t, Allow, authz.ServiceWriteAny(entCtx))
}
func checkAllowSessionRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) {
require.Equal(t, Allow, authz.SessionRead(prefix, entCtx))
}
@ -265,6 +269,10 @@ func checkDenyServiceWrite(t *testing.T, authz Authorizer, prefix string, entCtx
require.Equal(t, Deny, authz.ServiceWrite(prefix, entCtx))
}
func checkDenyServiceWriteAny(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) {
require.Equal(t, Deny, authz.ServiceWriteAny(entCtx))
}
func checkDenySessionRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) {
require.Equal(t, Deny, authz.SessionRead(prefix, entCtx))
}
@ -385,6 +393,10 @@ func checkDefaultServiceWrite(t *testing.T, authz Authorizer, prefix string, ent
require.Equal(t, Default, authz.ServiceWrite(prefix, entCtx))
}
func checkDefaultServiceWriteAny(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) {
require.Equal(t, Default, authz.ServiceWriteAny(entCtx))
}
func checkDefaultSessionRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) {
require.Equal(t, Default, authz.SessionRead(prefix, entCtx))
}

View File

@ -149,6 +149,9 @@ type Authorizer interface {
// service
ServiceWrite(string, *AuthorizerContext) EnforcementDecision
// ServiceWriteAny checks for write permission on any service
ServiceWriteAny(*AuthorizerContext) EnforcementDecision
// SessionRead checks for permission to read sessions for a given node.
SessionRead(string, *AuthorizerContext) EnforcementDecision
@ -411,6 +414,14 @@ func (a AllowAuthorizer) ServiceWriteAllowed(name string, ctx *AuthorizerContext
return nil
}
// ServiceWriteAnyAllowed checks for write permission on any service
func (a AllowAuthorizer) ServiceWriteAnyAllowed(ctx *AuthorizerContext) error {
if a.Authorizer.ServiceWriteAny(ctx) != Allow {
return PermissionDeniedByACL(a, ctx, ResourceService, AccessWrite, "any service")
}
return nil
}
// SessionReadAllowed checks for permission to read sessions for a given node.
func (a AllowAuthorizer) SessionReadAllowed(name string, ctx *AuthorizerContext) error {
if a.Authorizer.SessionRead(name, ctx) != Allow {

View File

@ -185,6 +185,12 @@ func (m *mockAuthorizer) ServiceWrite(segment string, ctx *AuthorizerContext) En
return ret.Get(0).(EnforcementDecision)
}
// ServiceWriteAny checks for service:write on any service
func (m *mockAuthorizer) ServiceWriteAny(ctx *AuthorizerContext) EnforcementDecision {
ret := m.Called(ctx)
return ret.Get(0).(EnforcementDecision)
}
// SessionRead checks for permission to read sessions for a given node.
func (m *mockAuthorizer) SessionRead(segment string, ctx *AuthorizerContext) EnforcementDecision {
ret := m.Called(segment, ctx)

View File

@ -235,6 +235,13 @@ func (c *ChainedAuthorizer) ServiceWrite(name string, entCtx *AuthorizerContext)
})
}
// ServiceWriteAny checks for write permission on any service
func (c *ChainedAuthorizer) ServiceWriteAny(entCtx *AuthorizerContext) EnforcementDecision {
return c.executeChain(func(authz Authorizer) EnforcementDecision {
return authz.ServiceWriteAny(entCtx)
})
}
// SessionRead checks for permission to read sessions for a given node.
func (c *ChainedAuthorizer) SessionRead(node string, entCtx *AuthorizerContext) EnforcementDecision {
return c.executeChain(func(authz Authorizer) EnforcementDecision {

View File

@ -89,6 +89,9 @@ func (authz testAuthorizer) ServiceReadAll(*AuthorizerContext) EnforcementDecisi
func (authz testAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision {
return EnforcementDecision(authz)
}
func (authz testAuthorizer) ServiceWriteAny(*AuthorizerContext) EnforcementDecision {
return EnforcementDecision(authz)
}
func (authz testAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
return EnforcementDecision(authz)
}

View File

@ -767,7 +767,7 @@ func (p *policyAuthorizer) ServiceWrite(name string, _ *AuthorizerContext) Enfor
return Default
}
func (p *policyAuthorizer) serviceWriteAny(_ *AuthorizerContext) EnforcementDecision {
func (p *policyAuthorizer) ServiceWriteAny(_ *AuthorizerContext) EnforcementDecision {
return p.anyAllowed(p.serviceRules, AccessWrite)
}

View File

@ -56,6 +56,7 @@ func TestPolicyAuthorizer(t *testing.T) {
{name: "DefaultPreparedQueryWrite", prefix: "foo", check: checkDefaultPreparedQueryWrite},
{name: "DefaultServiceRead", prefix: "foo", check: checkDefaultServiceRead},
{name: "DefaultServiceWrite", prefix: "foo", check: checkDefaultServiceWrite},
{name: "DefaultServiceWriteAny", prefix: "", check: checkDefaultServiceWriteAny},
{name: "DefaultSessionRead", prefix: "foo", check: checkDefaultSessionRead},
{name: "DefaultSessionWrite", prefix: "foo", check: checkDefaultSessionWrite},
{name: "DefaultSnapshot", prefix: "foo", check: checkDefaultSnapshot},
@ -267,6 +268,7 @@ func TestPolicyAuthorizer(t *testing.T) {
{name: "ServiceWritePrefixDenied", prefix: "food", check: checkDenyServiceWrite},
{name: "ServiceReadDenied", prefix: "football", check: checkDenyServiceRead},
{name: "ServiceWriteDenied", prefix: "football", check: checkDenyServiceWrite},
{name: "ServiceWriteAnyAllowed", prefix: "", check: checkAllowServiceWriteAny},
{name: "NodeReadPrefixAllowed", prefix: "fo", check: checkAllowNodeRead},
{name: "NodeWritePrefixDenied", prefix: "fo", check: checkDenyNodeWrite},

View File

@ -219,6 +219,13 @@ func (s *staticAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementD
return Deny
}
func (s *staticAuthorizer) ServiceWriteAny(*AuthorizerContext) EnforcementDecision {
if s.defaultAllow {
return Allow
}
return Deny
}
func (s *staticAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
if s.defaultAllow {
return Allow