diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index f791a90e957a..0b7b6034a2a0 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -1360,9 +1360,12 @@ func (s *HTTPServer) AgentConnectAuthorize(resp http.ResponseWriter, req *http.R var token string s.parseToken(req, &token) - // TODO (namespaces) probably need an update here to include the namespace with the target in the request - // Decode the request from the request body var authReq structs.ConnectAuthorizeRequest + + if err := s.parseEntMetaNoWildcard(req, &authReq.EnterpriseMeta); err != nil { + return nil, err + } + if err := decodeBody(req.Body, &authReq); err != nil { return nil, BadRequestError{fmt.Sprintf("Request decode failed: %v", err)} } diff --git a/agent/connect_auth.go b/agent/connect_auth.go index fc07fe60fb42..43ee70c5ed47 100644 --- a/agent/connect_auth.go +++ b/agent/connect_auth.go @@ -22,7 +22,7 @@ import ( // error is returned, otherwise error indicates an unexpected server failure. If // access is denied, no error is returned but the first return value is false. func (a *Agent) ConnectAuthorize(token string, - req *structs.ConnectAuthorizeRequest) (authz bool, reason string, m *cache.ResultMeta, err error) { + req *structs.ConnectAuthorizeRequest) (allowed bool, reason string, m *cache.ResultMeta, err error) { // Helper to make the error cases read better without resorting to named // returns which get messy and prone to mistakes in a method this long. @@ -53,12 +53,13 @@ func (a *Agent) ConnectAuthorize(token string, // We need to verify service:write permissions for the given token. // We do this manually here since the RPC request below only verifies // service:read. - rule, err := a.resolveToken(token) + var authzContext acl.AuthorizerContext + authz, err := a.resolveTokenAndDefaultMeta(token, &req.EnterpriseMeta, &authzContext) if err != nil { return returnErr(err) } - // TODO (namespaces) - pass through a real ent authz ctx - if rule != nil && rule.ServiceWrite(req.Target, nil) != acl.Allow { + + if authz != nil && authz.ServiceWrite(req.Target, &authzContext) != acl.Allow { return returnErr(acl.ErrPermissionDenied) } @@ -74,7 +75,7 @@ func (a *Agent) ConnectAuthorize(token string, Type: structs.IntentionMatchDestination, Entries: []structs.IntentionMatchEntry{ { - Namespace: structs.IntentionDefaultNamespace, + Namespace: req.TargetNamespace(), Name: req.Target, }, }, @@ -107,15 +108,14 @@ func (a *Agent) ConnectAuthorize(token string, // specifying the anonymous token, which will get the default behavior. The // default behavior if ACLs are disabled is to allow connections to mimic the // behavior of Consul itself: everything is allowed if ACLs are disabled. - rule, err = a.resolveToken("") + authz, err = a.resolveToken("") if err != nil { return returnErr(err) } - if rule == nil { + if authz == nil { // ACLs not enabled at all, the default is allow all. return true, "ACLs disabled, access is allowed by default", &meta, nil } reason = "Default behavior configured by ACLs" - // TODO (namespaces) - pass through a real ent authz ctx - return rule.IntentionDefaultAllow(nil) == acl.Allow, reason, &meta, nil + return authz.IntentionDefaultAllow(nil) == acl.Allow, reason, &meta, nil } diff --git a/agent/structs/connect.go b/agent/structs/connect.go index 7f08615d3925..1ca18cf7aada 100644 --- a/agent/structs/connect.go +++ b/agent/structs/connect.go @@ -6,6 +6,9 @@ type ConnectAuthorizeRequest struct { // Target is the name of the service that is being requested. Target string + // EnterpriseMeta is the embedded Consul Enterprise specific metadata + EnterpriseMeta + // ClientCertURI is a unique identifier for the requesting client. This // is currently the URI SAN from the TLS client certificate. // diff --git a/agent/structs/connect_oss.go b/agent/structs/connect_oss.go new file mode 100644 index 000000000000..30e168104742 --- /dev/null +++ b/agent/structs/connect_oss.go @@ -0,0 +1,7 @@ +// +build !consulent + +package structs + +func (req *ConnectAuthorizeRequest) TargetNamespace() string { + return IntentionDefaultNamespace +} diff --git a/website/source/api/agent/connect.html.md b/website/source/api/agent/connect.html.md index 4c0fe9a5b563..6c78272d8d47 100644 --- a/website/source/api/agent/connect.html.md +++ b/website/source/api/agent/connect.html.md @@ -56,6 +56,12 @@ The table below shows this endpoint's support for - `ClientCertSerial` `(string: )` - The colon-hex-encoded serial number for the requesting client cert. This is used to check against revocation lists. + +- `Namespace` `(string: "")` - **(Enterprise Only)** Specifies the namespace of + the target service. If not provided in the JSON body, the value of + the `ns` URL query parameter or in the `X-Consul-Namespace` header will be used. + If not provided at all, the namespace will be inherited from the request's ACL + token or will default to the `default` namespace. Added in Consul 1.7.0. ### Sample Payload