Skip to content

Commit

Permalink
Make v1/agent/connect/authorize namespace aware
Browse files Browse the repository at this point in the history
  • Loading branch information
mkeeler committed Jan 10, 2020
1 parent 1c186ca commit 506663b
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 11 deletions.
7 changes: 5 additions & 2 deletions agent/agent_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)}
}
Expand Down
18 changes: 9 additions & 9 deletions agent/connect_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
}

Expand All @@ -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,
},
},
Expand Down Expand Up @@ -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
}
3 changes: 3 additions & 0 deletions agent/structs/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down
7 changes: 7 additions & 0 deletions agent/structs/connect_oss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !consulent

package structs

func (req *ConnectAuthorizeRequest) TargetNamespace() string {
return IntentionDefaultNamespace
}
6 changes: 6 additions & 0 deletions website/source/api/agent/connect.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ The table below shows this endpoint's support for
- `ClientCertSerial` `(string: <required>)` - 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

Expand Down

0 comments on commit 506663b

Please sign in to comment.