Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add managed service provider token #7218

Merged
merged 2 commits into from
Feb 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions acl/static_authorizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ var (

// manageAll is a singleton policy which allows all
// actions, including management
// TODO (acls) - Do we need to keep this around? Our config parsing doesn't allow
// specifying a default "manage" policy so I believe nothing will every use this.
manageAll Authorizer = &staticAuthorizer{
allowManage: true,
defaultAllow: true,
Expand Down
2 changes: 2 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ func (a *Agent) Start() error {
// load the tokens - this requires the logger to be setup
// which is why we can't do this in New
a.loadTokens(a.config)
a.loadEnterpriseTokens(a.config)

// create the local state
a.State = local.NewState(LocalConfig(c), a.logger, a.tokens)
Expand Down Expand Up @@ -3991,6 +3992,7 @@ func (a *Agent) ReloadConfig(newCfg *config.RuntimeConfig) error {
// to ensure the correct tokens are available for attaching to
// the checks and service registrations.
a.loadTokens(newCfg)
a.loadEnterpriseTokens(newCfg)

if err := a.tlsConfigurator.Update(newCfg.ToTLSUtilConfig()); err != nil {
return fmt.Errorf("Failed reloading tls configuration: %s", err)
Expand Down
4 changes: 4 additions & 0 deletions agent/agent_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package agent

import (
"github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/consul"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
Expand All @@ -16,3 +17,6 @@ func fillHealthCheckEnterpriseMeta(_ *api.HealthCheck, _ *structs.EnterpriseMeta

func (a *Agent) initEnterprise(consulCfg *consul.Config) {
}

func (a *Agent) loadEnterpriseTokens(conf *config.RuntimeConfig) {
}
12 changes: 6 additions & 6 deletions agent/config/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1197,12 +1197,6 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
}
}

if rt.AutoEncryptAllowTLS {
if !rt.VerifyIncoming && !rt.VerifyIncomingRPC {
b.warn("if auto_encrypt.allow_tls is turned on, either verify_incoming or verify_incoming_rpc should be enabled. It is necessary to turn it off during a migration to TLS, but it should definitely be turned on afterwards.")
}
}

// ----------------------------------------------------------------
// warnings
//
Expand All @@ -1223,6 +1217,12 @@ func (b *Builder) Validate(rt RuntimeConfig) error {
b.warn("bootstrap_expect > 0: expecting %d servers", rt.BootstrapExpect)
}

if rt.AutoEncryptAllowTLS {
if !rt.VerifyIncoming && !rt.VerifyIncomingRPC {
b.warn("if auto_encrypt.allow_tls is turned on, either verify_incoming or verify_incoming_rpc should be enabled. It is necessary to turn it off during a migration to TLS, but it should definitely be turned on afterwards.")
}
}

return nil
}

Expand Down
17 changes: 12 additions & 5 deletions agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func Parse(data string, format string) (c Config, err error) {
"services.proxy.upstreams",
"service.proxy.expose.paths",
"services.proxy.expose.paths",
"acl.tokens.managed_service_provider",

// Need all the service(s) exceptions also for nested sidecar service.
"service.connect.sidecar_service.checks",
Expand Down Expand Up @@ -707,11 +708,17 @@ type ACL struct {
}

type Tokens struct {
Master *string `json:"master,omitempty" hcl:"master" mapstructure:"master"`
Replication *string `json:"replication,omitempty" hcl:"replication" mapstructure:"replication"`
AgentMaster *string `json:"agent_master,omitempty" hcl:"agent_master" mapstructure:"agent_master"`
Default *string `json:"default,omitempty" hcl:"default" mapstructure:"default"`
Agent *string `json:"agent,omitempty" hcl:"agent" mapstructure:"agent"`
Master *string `json:"master,omitempty" hcl:"master" mapstructure:"master"`
Replication *string `json:"replication,omitempty" hcl:"replication" mapstructure:"replication"`
AgentMaster *string `json:"agent_master,omitempty" hcl:"agent_master" mapstructure:"agent_master"`
Default *string `json:"default,omitempty" hcl:"default" mapstructure:"default"`
Agent *string `json:"agent,omitempty" hcl:"agent" mapstructure:"agent"`
ManagedServiceProvider []ServiceProviderToken `json:"managed_service_provider,omitempty" hcl:"managed_service_provider" mapstructure:"managed_service_provider"`
}

type ServiceProviderToken struct {
AccessorID *string `json:"accessor_id,omitempty" hcl:"accessor_id" mapstructure:"accessor_id"`
SecretID *string `json:"secret_id,omitempty" hcl:"secret_id" mapstructure:"secret_id"`
}

type ConfigEntries struct {
Expand Down
24 changes: 22 additions & 2 deletions agent/config/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3694,7 +3694,17 @@ func TestFullConfig(t *testing.T) {
"agent_master" : "64fd0e08",
"replication" : "5795983a",
"agent" : "bed2377c",
"default" : "418fdff1"
"default" : "418fdff1",
"managed_service_provider": [
{
"accessor_id": "first",
"secret_id": "fb0cee1f-2847-467c-99db-a897cff5fd4d"
},
{
"accessor_id": "second",
"secret_id": "1046c8da-e166-4667-897a-aefb343db9db"
}
]
}
},
"addresses": {
Expand Down Expand Up @@ -4302,7 +4312,17 @@ func TestFullConfig(t *testing.T) {
agent_master = "64fd0e08",
replication = "5795983a",
agent = "bed2377c",
default = "418fdff1"
default = "418fdff1",
managed_service_provider = [
{
accessor_id = "first",
secret_id = "fb0cee1f-2847-467c-99db-a897cff5fd4d"
},
{
accessor_id = "second",
secret_id = "1046c8da-e166-4667-897a-aefb343db9db"
}
]
}
}
addresses = {
Expand Down
6 changes: 5 additions & 1 deletion agent/consul/acl_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,14 @@ func (s *Server) ResolveRoleFromID(roleID string) (bool, *structs.ACLRole, error
}

func (s *Server) ResolveToken(token string) (acl.Authorizer, error) {
return s.acls.ResolveToken(token)
_, authz, err := s.ResolveTokenToIdentityAndAuthorizer(token)
return authz, err
}

func (s *Server) ResolveTokenToIdentityAndAuthorizer(token string) (structs.ACLIdentity, acl.Authorizer, error) {
if id, authz := s.ResolveEntTokenToIdentityAndAuthorizer(token); id != nil && authz != nil {
return id, authz, nil
}
return s.acls.ResolveTokenToIdentityAndAuthorizer(token)
}

Expand Down
18 changes: 18 additions & 0 deletions agent/consul/acl_server_oss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// +build !consulent

package consul

import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
)

// Consul-enterprise only
func (s *Server) ResolveEntTokenToIdentityAndAuthorizer(token string) (structs.ACLIdentity, acl.Authorizer) {
return nil, nil
}

// Consul-enterprise only
func (s *Server) validateEnterpriseToken(identity structs.ACLIdentity) error {
return nil
}
5 changes: 4 additions & 1 deletion agent/consul/internal_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,13 @@ func (m *Internal) KeyringOperation(
reply *structs.KeyringResponses) error {

// Check ACLs
rule, err := m.srv.ResolveToken(args.Token)
identity, rule, err := m.srv.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
if err := m.srv.validateEnterpriseToken(identity); err != nil {
return err
}
if rule != nil {
switch args.Operation {
case structs.KeyringList:
Expand Down
15 changes: 12 additions & 3 deletions agent/consul/operator_autopilot_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ func (op *Operator) AutopilotGetConfiguration(args *structs.DCSpecificRequest, r
}

// This action requires operator read access.
rule, err := op.srv.ResolveToken(args.Token)
identity, rule, err := op.srv.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
if err := op.srv.validateEnterpriseToken(identity); err != nil {
return err
}
if rule != nil && rule.OperatorRead(nil) != acl.Allow {
return acl.ErrPermissionDenied
}
Expand All @@ -44,10 +47,13 @@ func (op *Operator) AutopilotSetConfiguration(args *structs.AutopilotSetConfigRe
}

// This action requires operator write access.
rule, err := op.srv.ResolveToken(args.Token)
identity, rule, err := op.srv.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
if err := op.srv.validateEnterpriseToken(identity); err != nil {
return err
}
if rule != nil && rule.OperatorWrite(nil) != acl.Allow {
return acl.ErrPermissionDenied
}
Expand Down Expand Up @@ -80,10 +86,13 @@ func (op *Operator) ServerHealth(args *structs.DCSpecificRequest, reply *autopil
}

// This action requires operator read access.
rule, err := op.srv.ResolveToken(args.Token)
identity, rule, err := op.srv.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
if err := op.srv.validateEnterpriseToken(identity); err != nil {
return err
}
if rule != nil && rule.OperatorRead(nil) != acl.Allow {
return acl.ErrPermissionDenied
}
Expand Down
10 changes: 8 additions & 2 deletions agent/consul/operator_raft_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,13 @@ func (op *Operator) RaftRemovePeerByAddress(args *structs.RaftRemovePeerRequest,

// This is a super dangerous operation that requires operator write
// access.
rule, err := op.srv.ResolveToken(args.Token)
identity, rule, err := op.srv.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
if err := op.srv.validateEnterpriseToken(identity); err != nil {
return err
}
if rule != nil && rule.OperatorWrite(nil) != acl.Allow {
return acl.ErrPermissionDenied
}
Expand Down Expand Up @@ -149,10 +152,13 @@ func (op *Operator) RaftRemovePeerByID(args *structs.RaftRemovePeerRequest, repl

// This is a super dangerous operation that requires operator write
// access.
rule, err := op.srv.ResolveToken(args.Token)
identity, rule, err := op.srv.ResolveTokenToIdentityAndAuthorizer(args.Token)
if err != nil {
return err
}
if err := op.srv.validateEnterpriseToken(identity); err != nil {
return err
}
if rule != nil && rule.OperatorWrite(nil) != acl.Allow {
return acl.ErrPermissionDenied
}
Expand Down
3 changes: 3 additions & 0 deletions agent/token/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ type Store struct {

// replicationTokenSource indicates where this token originated from
replicationTokenSource TokenSource

// enterpriseTokens contains tokens only used in consul-enterprise
enterpriseTokens
}

// UpdateUserToken replaces the current user token in the store.
Expand Down
7 changes: 7 additions & 0 deletions agent/token/store_oss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !consulent

package token

// Stub for enterpriseTokens
type enterpriseTokens struct {
}
12 changes: 12 additions & 0 deletions website/source/docs/agent/options.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,18 @@ default will automatically work with some tooling.
token replication is enabled then it must have "write" permissions. This also enables
Connect replication, for which the token will require both operator
"write" and intention "read" permissions for replicating CA and Intention data.

* <a name="acl_tokens_managed_service_provider"></a><a href="#acl_tokens_managed_service_provider">`managed_service_provider`</a> -
**(Enterprise Only)** An array of ACL tokens used by Consul managed service providers for cluster operations.

```javascript
"managed_service_provider": [
{
"accessor_id": "ed22003b-0832-4e48-ac65-31de64e5c2ff",
"secret_id": "cb6be010-bba8-4f30-a9ed-d347128dde17"
}
]
```

* <a name="acl_datacenter"></a><a href="#acl_datacenter">`acl_datacenter`</a> - **This field is
deprecated in Consul 1.4.0. See the [`primary_datacenter`](#primary_datacenter) field instead.**
Expand Down