mirror of https://github.com/status-im/consul.git
Merge pull request #11433 from hashicorp/exported-service-acls
[OSS] acl: Expand ServiceRead and NodeRead to account for partition exports
This commit is contained in:
commit
ec7e94d129
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
connect: **(Enterprise only)** updates ServiceRead and NodeRead to account for the partition-exports config entry.
|
||||||
|
```
|
|
@ -14,6 +14,11 @@ type Config struct {
|
||||||
EnterpriseConfig
|
EnterpriseConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PartitionExportInfo interface {
|
||||||
|
// DownstreamPartitions returns the list of partitions the given service has been exported to.
|
||||||
|
DownstreamPartitions(service string, anyService bool, ctx *AuthorizerContext) []string
|
||||||
|
}
|
||||||
|
|
||||||
// GetWildcardName will retrieve the configured wildcard name or provide a default
|
// GetWildcardName will retrieve the configured wildcard name or provide a default
|
||||||
// in the case that the config is Nil or the wildcard name is unset.
|
// in the case that the config is Nil or the wildcard name is unset.
|
||||||
func (c *Config) GetWildcardName() string {
|
func (c *Config) GetWildcardName() string {
|
||||||
|
|
|
@ -149,6 +149,9 @@ type Authorizer interface {
|
||||||
// service
|
// service
|
||||||
ServiceWrite(string, *AuthorizerContext) EnforcementDecision
|
ServiceWrite(string, *AuthorizerContext) EnforcementDecision
|
||||||
|
|
||||||
|
// ServiceWriteAny checks for permission to read any service
|
||||||
|
ServiceWriteAny(*AuthorizerContext) EnforcementDecision
|
||||||
|
|
||||||
// SessionRead checks for permission to read sessions for a given node.
|
// SessionRead checks for permission to read sessions for a given node.
|
||||||
SessionRead(string, *AuthorizerContext) EnforcementDecision
|
SessionRead(string, *AuthorizerContext) EnforcementDecision
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,11 @@ func (m *mockAuthorizer) ServiceWrite(segment string, ctx *AuthorizerContext) En
|
||||||
return ret.Get(0).(EnforcementDecision)
|
return ret.Get(0).(EnforcementDecision)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
// SessionRead checks for permission to read sessions for a given node.
|
||||||
func (m *mockAuthorizer) SessionRead(segment string, ctx *AuthorizerContext) EnforcementDecision {
|
func (m *mockAuthorizer) SessionRead(segment string, ctx *AuthorizerContext) EnforcementDecision {
|
||||||
ret := m.Called(segment, ctx)
|
ret := m.Called(segment, ctx)
|
||||||
|
|
|
@ -235,6 +235,12 @@ func (c *ChainedAuthorizer) ServiceWrite(name string, entCtx *AuthorizerContext)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
// SessionRead checks for permission to read sessions for a given node.
|
||||||
func (c *ChainedAuthorizer) SessionRead(node string, entCtx *AuthorizerContext) EnforcementDecision {
|
func (c *ChainedAuthorizer) SessionRead(node string, entCtx *AuthorizerContext) EnforcementDecision {
|
||||||
return c.executeChain(func(authz Authorizer) EnforcementDecision {
|
return c.executeChain(func(authz Authorizer) EnforcementDecision {
|
||||||
|
|
|
@ -89,6 +89,9 @@ func (authz testAuthorizer) ServiceReadAll(*AuthorizerContext) EnforcementDecisi
|
||||||
func (authz testAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision {
|
func (authz testAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision {
|
||||||
return EnforcementDecision(authz)
|
return EnforcementDecision(authz)
|
||||||
}
|
}
|
||||||
|
func (authz testAuthorizer) ServiceWriteAny(*AuthorizerContext) EnforcementDecision {
|
||||||
|
return EnforcementDecision(authz)
|
||||||
|
}
|
||||||
func (authz testAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
|
func (authz testAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
|
||||||
return EnforcementDecision(authz)
|
return EnforcementDecision(authz)
|
||||||
}
|
}
|
||||||
|
|
|
@ -767,6 +767,10 @@ func (p *policyAuthorizer) ServiceWrite(name string, _ *AuthorizerContext) Enfor
|
||||||
return Default
|
return Default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *policyAuthorizer) ServiceWriteAny(_ *AuthorizerContext) EnforcementDecision {
|
||||||
|
return p.anyAllowed(p.serviceRules, AccessWrite)
|
||||||
|
}
|
||||||
|
|
||||||
// SessionRead checks for permission to read sessions for a given node.
|
// SessionRead checks for permission to read sessions for a given node.
|
||||||
func (p *policyAuthorizer) SessionRead(node string, _ *AuthorizerContext) EnforcementDecision {
|
func (p *policyAuthorizer) SessionRead(node string, _ *AuthorizerContext) EnforcementDecision {
|
||||||
if rule, ok := getPolicy(node, p.sessionRules); ok {
|
if rule, ok := getPolicy(node, p.sessionRules); ok {
|
||||||
|
|
|
@ -219,6 +219,13 @@ func (s *staticAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementD
|
||||||
return Deny
|
return Deny
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *staticAuthorizer) ServiceWriteAny(*AuthorizerContext) EnforcementDecision {
|
||||||
|
if s.defaultAllow {
|
||||||
|
return Allow
|
||||||
|
}
|
||||||
|
return Deny
|
||||||
|
}
|
||||||
|
|
||||||
func (s *staticAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
|
func (s *staticAuthorizer) SessionRead(string, *AuthorizerContext) EnforcementDecision {
|
||||||
if s.defaultAllow {
|
if s.defaultAllow {
|
||||||
return Allow
|
return Allow
|
||||||
|
|
|
@ -292,7 +292,10 @@ func agentMasterAuthorizer(nodeName string, entMeta *structs.EnterpriseMeta) (ac
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, nil)
|
|
||||||
|
cfg := acl.Config{}
|
||||||
|
setEnterpriseConf(entMeta, &cfg)
|
||||||
|
return acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, &cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewACLResolver(config *ACLResolverConfig) (*ACLResolver, error) {
|
func NewACLResolver(config *ACLResolverConfig) (*ACLResolver, error) {
|
||||||
|
@ -1090,8 +1093,13 @@ func (r *ACLResolver) ResolveTokenToIdentityAndAuthorizer(token string) (structs
|
||||||
|
|
||||||
// Build the Authorizer
|
// Build the Authorizer
|
||||||
var chain []acl.Authorizer
|
var chain []acl.Authorizer
|
||||||
|
var conf acl.Config
|
||||||
|
if r.aclConf != nil {
|
||||||
|
conf = *r.aclConf
|
||||||
|
}
|
||||||
|
setEnterpriseConf(identity.EnterpriseMetadata(), &conf)
|
||||||
|
|
||||||
authz, err := policies.Compile(r.cache, r.aclConf)
|
authz, err := policies.Compile(r.cache, &conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -1895,3 +1903,9 @@ func filterACL(r *ACLResolver, token string, subj interface{}) error {
|
||||||
filterACLWithAuthorizer(r.logger, authorizer, subj)
|
filterACLWithAuthorizer(r.logger, authorizer, subj)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type partitionInfoNoop struct{}
|
||||||
|
|
||||||
|
func (p *partitionInfoNoop) DownstreamPartitions(service string, anyService bool, ctx *acl.AuthorizerContext) []string {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,11 @@ func (s *Server) replicationEnterpriseMeta() *structs.EnterpriseMeta {
|
||||||
return structs.ReplicationEnterpriseMeta()
|
return structs.ReplicationEnterpriseMeta()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newACLConfig(hclog.Logger) *acl.Config {
|
func serverPartitionInfo(s *Server) acl.PartitionExportInfo {
|
||||||
|
return &partitionInfoNoop{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newACLConfig(_ acl.PartitionExportInfo, _ hclog.Logger) *acl.Config {
|
||||||
return &acl.Config{
|
return &acl.Config{
|
||||||
WildcardName: structs.WildcardSpecifier,
|
WildcardName: structs.WildcardSpecifier,
|
||||||
}
|
}
|
||||||
|
@ -41,3 +45,5 @@ func (_ *ACLResolver) resolveEnterpriseIdentityAndPolicies(_ structs.ACLIdentity
|
||||||
func (_ *ACLResolver) resolveLocallyManagedEnterpriseToken(_ string) (structs.ACLIdentity, acl.Authorizer, bool) {
|
func (_ *ACLResolver) resolveLocallyManagedEnterpriseToken(_ string) (structs.ACLIdentity, acl.Authorizer, bool) {
|
||||||
return nil, nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setEnterpriseConf(entMeta *structs.EnterpriseMeta, conf *acl.Config) {}
|
||||||
|
|
|
@ -123,7 +123,7 @@ func NewClient(config *Config, deps Deps) (*Client, error) {
|
||||||
Logger: c.logger,
|
Logger: c.logger,
|
||||||
DisableDuration: aclClientDisabledTTL,
|
DisableDuration: aclClientDisabledTTL,
|
||||||
CacheConfig: clientACLCacheConfig,
|
CacheConfig: clientACLCacheConfig,
|
||||||
ACLConfig: newACLConfig(c.logger),
|
ACLConfig: newACLConfig(&partitionInfoNoop{}, c.logger),
|
||||||
Tokens: deps.Tokens,
|
Tokens: deps.Tokens,
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
|
|
|
@ -427,7 +427,8 @@ func NewServer(config *Config, flat Deps) (*Server, error) {
|
||||||
// Initialize the stats fetcher that autopilot will use.
|
// Initialize the stats fetcher that autopilot will use.
|
||||||
s.statsFetcher = NewStatsFetcher(logger, s.connPool, s.config.Datacenter)
|
s.statsFetcher = NewStatsFetcher(logger, s.connPool, s.config.Datacenter)
|
||||||
|
|
||||||
s.aclConfig = newACLConfig(logger)
|
partitionInfo := serverPartitionInfo(s)
|
||||||
|
s.aclConfig = newACLConfig(partitionInfo, logger)
|
||||||
aclConfig := ACLResolverConfig{
|
aclConfig := ACLResolverConfig{
|
||||||
Config: config.ACLResolverSettings,
|
Config: config.ACLResolverSettings,
|
||||||
Delegate: s,
|
Delegate: s,
|
||||||
|
|
Loading…
Reference in New Issue