Skip to content

Commit

Permalink
acl: do not resolve local tokens from remote dcs (#8068)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanshasselberg authored and hashicorp-ci committed Jun 9, 2020
1 parent a18e052 commit 0c5f6ea
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
3 changes: 3 additions & 0 deletions agent/consul/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ func (r *ACLResolver) fetchAndCacheIdentityFromToken(token string, cached *struc
if resp.Token == nil {
r.cache.PutIdentity(cacheID, nil)
return nil, acl.ErrNotFound
} else if resp.Token.Local && r.config.Datacenter != resp.SourceDatacenter {
r.cache.PutIdentity(cacheID, nil)
return nil, acl.PermissionDeniedError{Cause: fmt.Sprintf("This is a local token in datacenter %q", resp.SourceDatacenter)}
} else {
r.cache.PutIdentity(cacheID, resp.Token)
return resp.Token, nil
Expand Down
1 change: 1 addition & 0 deletions agent/consul/acl_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ func (a *ACL) TokenRead(args *structs.ACLTokenGetRequest, reply *structs.ACLToke
}

reply.Index, reply.Token = index, token
reply.SourceDatacenter = args.Datacenter
return nil
})
}
Expand Down
46 changes: 46 additions & 0 deletions agent/consul/acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3622,3 +3622,49 @@ func TestDedupeServiceIdentities(t *testing.T) {
})
}
}
func TestACL_LocalToken(t *testing.T) {
t.Run("local token in same dc", func(t *testing.T) {
d := &ACLResolverTestDelegate{
datacenter: "dc1",
tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
reply.Token = &structs.ACLToken{Local: true}
// different dc
reply.SourceDatacenter = "dc1"
return nil
},
}
r := newTestACLResolver(t, d, nil)
_, err := r.fetchAndCacheIdentityFromToken("", nil)
require.NoError(t, err)
})

t.Run("non local token in remote dc", func(t *testing.T) {
d := &ACLResolverTestDelegate{
datacenter: "dc1",
tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
reply.Token = &structs.ACLToken{Local: false}
// different dc
reply.SourceDatacenter = "remote"
return nil
},
}
r := newTestACLResolver(t, d, nil)
_, err := r.fetchAndCacheIdentityFromToken("", nil)
require.NoError(t, err)
})

t.Run("local token in remote dc", func(t *testing.T) {
d := &ACLResolverTestDelegate{
datacenter: "dc1",
tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error {
reply.Token = &structs.ACLToken{Local: true}
// different dc
reply.SourceDatacenter = "remote"
return nil
},
}
r := newTestACLResolver(t, d, nil)
_, err := r.fetchAndCacheIdentityFromToken("", nil)
require.Equal(t, acl.PermissionDeniedError{Cause: "This is a local token in datacenter \"remote\""}, err)
})
}
5 changes: 3 additions & 2 deletions agent/structs/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1195,8 +1195,9 @@ type ACLTokenBootstrapRequest struct {

// ACLTokenResponse returns a single Token + metadata
type ACLTokenResponse struct {
Token *ACLToken
Redacted bool // whether the token's secret was redacted
Token *ACLToken
Redacted bool // whether the token's secret was redacted
SourceDatacenter string
QueryMeta
}

Expand Down

0 comments on commit 0c5f6ea

Please sign in to comment.