Merge pull request #10849 from hashicorp/dnephin/contrib-doc-xds-auth
xds: document how authorization works
This commit is contained in:
commit
4a0ae4048d
|
@ -138,7 +138,7 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove
|
|||
}
|
||||
|
||||
checkStreamACLs := func(cfgSnap *proxycfg.ConfigSnapshot) error {
|
||||
return s.checkStreamACLs(stream.Context(), cfgSnap)
|
||||
return s.authorize(stream.Context(), cfgSnap)
|
||||
}
|
||||
|
||||
for {
|
||||
|
|
|
@ -327,7 +327,7 @@ func (s *Server) process(stream ADSStream, reqCh <-chan *envoy_discovery_v3.Disc
|
|||
}
|
||||
|
||||
checkStreamACLs := func(cfgSnap *proxycfg.ConfigSnapshot) error {
|
||||
return s.checkStreamACLs(stream.Context(), cfgSnap)
|
||||
return s.authorize(stream.Context(), cfgSnap)
|
||||
}
|
||||
|
||||
for {
|
||||
|
@ -564,13 +564,22 @@ func NewGRPCServer(s *Server, tlsConfigurator *tlsutil.Configurator) *grpc.Serve
|
|||
return srv
|
||||
}
|
||||
|
||||
func (s *Server) checkStreamACLs(streamCtx context.Context, cfgSnap *proxycfg.ConfigSnapshot) error {
|
||||
// authorize the xDS request using the token stored in ctx. This authorization is
|
||||
// a bit different from most interfaces. Instead of explicitly authorizing or
|
||||
// filtering each piece of data in the response, the request is authorized
|
||||
// by checking the token has `service:write` for the service ID of the destination
|
||||
// service (for kind=ConnectProxy), or the gateway service (for other kinds).
|
||||
// This authorization strategy requires that agent/proxycfg only fetches data
|
||||
// using a token with the same permissions, and that it stores the data by
|
||||
// proxy ID. We assume that any data in the snapshot was already filtered,
|
||||
// which allows this authorization to be a shallow authorization check
|
||||
// for all the data in a ConfigSnapshot.
|
||||
func (s *Server) authorize(ctx context.Context, cfgSnap *proxycfg.ConfigSnapshot) error {
|
||||
if cfgSnap == nil {
|
||||
return status.Errorf(codes.Unauthenticated, "unauthenticated: no config snapshot")
|
||||
}
|
||||
|
||||
authz, err := s.ResolveToken(tokenFromContext(streamCtx))
|
||||
|
||||
authz, err := s.ResolveToken(tokenFromContext(ctx))
|
||||
if acl.IsErrNotFound(err) {
|
||||
return status.Errorf(codes.Unauthenticated, "unauthenticated: %v", err)
|
||||
} else if acl.IsErrPermissionDenied(err) {
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
# Service Mesh (Connect)
|
||||
|
||||
- call out: envoy/proxy is the data plane, Consul is the control plane
|
||||
- agent/xds - gRPC service that implements
|
||||
[xDS](https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol)
|
||||
- [agent/proxycfg](https://github.com/hashicorp/consul/blob/master/agent/proxycfg/proxycfg.go)
|
||||
- [xDS Server] - a gRPC service that implements [xDS] and handles requests from an [envoy proxy].
|
||||
- [agent/proxycfg]
|
||||
- CA Manager - certificate authority
|
||||
- command/connect/envoy - bootstrapping and running envoy
|
||||
- command/connect/proxy - built-in proxy that is dev-only and not supported
|
||||
for production.
|
||||
- `connect/` - "Native" service mesh
|
||||
|
||||
[xDS Server]: ./xds.md
|
||||
[xDS]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol
|
||||
[envoy proxy]: https://www.consul.io/docs/connect/proxies/envoy
|
||||
[agent/proxycfg]: https://github.com/hashicorp/consul/blob/main/agent/proxycfg
|
||||
|
|
25
contributing/service-mesh/xds.md
Normal file
25
contributing/service-mesh/xds.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# xDS Server
|
||||
|
||||
The xDS Server is a gRPC service that implements [xDS] and handles requests from
|
||||
an [envoy proxy].
|
||||
|
||||
[xDS]: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol
|
||||
[envoy proxy]: https://www.consul.io/docs/connect/proxies/envoy
|
||||
|
||||
|
||||
## Authorization
|
||||
|
||||
Requests to the xDS server are authorized based on an assumption of how
|
||||
`proxycfg.ConfigSnapshot` are constructed. Most interfaces (HTTP, DNS, RPC)
|
||||
authorize requests by authorizing the data in the response, or by filtering
|
||||
out data that the requester is not authorized to view. The xDS server authorizes
|
||||
requests by looking at the proxy ID in the request and ensuring the ACL token has
|
||||
`service:write` access to either the destination service (for kind=ConnectProxy), or
|
||||
the gateway service (for other kinds).
|
||||
|
||||
This authorization strategy requires that [agent/proxycfg] only fetches data using a
|
||||
token with the same permissions, and that it only stores data by proxy ID. We assume
|
||||
that any data in the snapshot was already filtered, which allows this authorization to
|
||||
only perform a shallow check against the proxy ID.
|
||||
|
||||
[agent/proxycfg]: https://github.com/hashicorp/consul/blob/main/agent/proxycfg
|
Loading…
Reference in a new issue