diff --git a/.changelog/11782.txt b/.changelog/11782.txt new file mode 100644 index 000000000..631169480 --- /dev/null +++ b/.changelog/11782.txt @@ -0,0 +1,3 @@ +```release-note:bug +acl: **(Enterprise only)** ensure that the agent recovery token is properly partitioned +``` diff --git a/agent/consul/acl.go b/agent/consul/acl.go index 9a2c74a17..31626e52a 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -266,36 +266,32 @@ type ACLResolver struct { agentMasterAuthz acl.Authorizer } -func agentMasterAuthorizer(nodeName string, entMeta *structs.EnterpriseMeta) (acl.Authorizer, error) { - // TODO(partitions,acls): this function likely needs split so that the generated policy can be partitioned appropriately - - // TODO(partitions,acls): after this all works, write a test for this function when partitioned +func agentMasterAuthorizer(nodeName string, entMeta *structs.EnterpriseMeta, aclConf *acl.Config) (acl.Authorizer, error) { + var conf acl.Config + if aclConf != nil { + conf = *aclConf + } + setEnterpriseConf(entMeta, &conf) // Build a policy for the agent master token. + // // The builtin agent master policy allows reading any node information // and allows writes to the agent with the node name of the running agent // only. This used to allow a prefix match on agent names but that seems // entirely unnecessary so it is now using an exact match. - policy := &acl.Policy{ - PolicyRules: acl.PolicyRules{ - Agents: []*acl.AgentRule{ - { - Node: nodeName, - Policy: acl.PolicyWrite, - }, - }, - NodePrefixes: []*acl.NodeRule{ - { - Name: "", - Policy: acl.PolicyRead, - }, - }, - }, + policy, err := acl.NewPolicyFromSource(fmt.Sprintf(` + agent "%s" { + policy = "write" + } + node_prefix "" { + policy = "read" + } + `, nodeName), acl.SyntaxCurrent, &conf, entMeta.ToEnterprisePolicyMeta()) + if err != nil { + return nil, err } - cfg := acl.Config{} - setEnterpriseConf(entMeta, &cfg) - return acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, &cfg) + return acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, &conf) } func NewACLResolver(config *ACLResolverConfig) (*ACLResolver, error) { @@ -327,7 +323,7 @@ func NewACLResolver(config *ACLResolverConfig) (*ACLResolver, error) { return nil, fmt.Errorf("invalid ACL down policy %q", config.Config.ACLDownPolicy) } - authz, err := agentMasterAuthorizer(config.Config.NodeName, &config.Config.EnterpriseMeta) + authz, err := agentMasterAuthorizer(config.Config.NodeName, &config.Config.EnterpriseMeta, config.ACLConfig) if err != nil { return nil, fmt.Errorf("failed to initialize the agent master authorizer") } diff --git a/agent/structs/structs_oss.go b/agent/structs/structs_oss.go index acc3191d2..669361802 100644 --- a/agent/structs/structs_oss.go +++ b/agent/structs/structs_oss.go @@ -15,6 +15,10 @@ var emptyEnterpriseMeta = EnterpriseMeta{} // EnterpriseMeta stub type EnterpriseMeta struct{} +func (m *EnterpriseMeta) ToEnterprisePolicyMeta() *acl.EnterprisePolicyMeta { + return nil +} + func (m *EnterpriseMeta) estimateSize() int { return 0 }