diff --git a/.changelog/_4696.txt b/.changelog/_4696.txt new file mode 100644 index 000000000000..951896fd66f3 --- /dev/null +++ b/.changelog/_4696.txt @@ -0,0 +1,3 @@ +```release-note:bug +peering: **(Consul Enterprise only)** Fix issue where connect-enabled services with peer upstreams incorrectly required `service:write` access in the `default` namespace to query data, which was too restrictive. Now having `service:write` to any namespace is sufficient to query the peering data. +``` diff --git a/agent/proxycfg-glue/trust_bundle.go b/agent/proxycfg-glue/trust_bundle.go index e642bb19ba69..0152c5fdfc22 100644 --- a/agent/proxycfg-glue/trust_bundle.go +++ b/agent/proxycfg-glue/trust_bundle.go @@ -33,12 +33,14 @@ type serverTrustBundle struct { } func (s *serverTrustBundle) Notify(ctx context.Context, req *cachetype.TrustBundleReadRequest, correlationID string, ch chan<- proxycfg.UpdateEvent) error { - entMeta := structs.NodeEnterpriseMetaInPartition(req.Request.Partition) + // Having the ability to write a service in ANY (at least one) namespace should be + // sufficient for reading the trust bundle, which is why we use a wildcard. + entMeta := acl.NewEnterpriseMetaWithPartition(req.Request.Partition, acl.WildcardName) return watch.ServerLocalNotify(ctx, correlationID, s.deps.GetStore, func(ws memdb.WatchSet, store Store) (uint64, *pbpeering.TrustBundleReadResponse, error) { var authzCtx acl.AuthorizerContext - authz, err := s.deps.ACLResolver.ResolveTokenAndDefaultMeta(req.Token, entMeta, &authzCtx) + authz, err := s.deps.ACLResolver.ResolveTokenAndDefaultMeta(req.Token, &entMeta, &authzCtx) if err != nil { return 0, nil, err } diff --git a/agent/rpc/peering/service.go b/agent/rpc/peering/service.go index ea473a74249a..daf27a02f96b 100644 --- a/agent/rpc/peering/service.go +++ b/agent/rpc/peering/service.go @@ -924,9 +924,12 @@ func (s *Server) TrustBundleRead(ctx context.Context, req *pbpeering.TrustBundle defer metrics.MeasureSince([]string{"peering", "trust_bundle_read"}, time.Now()) + // Having the ability to write a service in ANY (at least one) namespace should be + // sufficient for reading the trust bundle, which is why we use a wildcard. + entMeta := acl.NewEnterpriseMetaWithPartition(req.Partition, acl.WildcardName) + entMeta.Normalize() var authzCtx acl.AuthorizerContext - entMeta := structs.DefaultEnterpriseMetaInPartition(req.Partition) - authz, err := s.Backend.ResolveTokenAndDefaultMeta(options.Token, entMeta, &authzCtx) + authz, err := s.Backend.ResolveTokenAndDefaultMeta(options.Token, &entMeta, &authzCtx) if err != nil { return nil, err } @@ -937,7 +940,7 @@ func (s *Server) TrustBundleRead(ctx context.Context, req *pbpeering.TrustBundle idx, trustBundle, err := s.Backend.Store().PeeringTrustBundleRead(nil, state.Query{ Value: req.Name, - EnterpriseMeta: *entMeta, + EnterpriseMeta: entMeta, }) if err != nil { return nil, fmt.Errorf("failed to read trust bundle for peer %s: %w", req.Name, err)