diff --git a/.changelog/11665.txt b/.changelog/11665.txt new file mode 100644 index 000000000..f4812a107 --- /dev/null +++ b/.changelog/11665.txt @@ -0,0 +1,3 @@ +```release-note:deprecation +config: `acl.tokens.master` has been renamed to `acl.tokens.initial_management`, and `acl.tokens.agent_master` has been renamed to `acl.tokens.agent_recovery` - the old field names are now deprecated and will be removed in a future major release +``` diff --git a/agent/auto-config/config_translate.go b/agent/auto-config/config_translate.go index eb9d73f80..58721e021 100644 --- a/agent/auto-config/config_translate.go +++ b/agent/auto-config/config_translate.go @@ -65,12 +65,14 @@ func translateConfig(c *pbconfig.Config) config.Config { } result.ACL.Tokens = config.Tokens{ - Master: stringPtrOrNil(t.Master), Replication: stringPtrOrNil(t.Replication), - AgentMaster: stringPtrOrNil(t.AgentMaster), Default: stringPtrOrNil(t.Default), Agent: stringPtrOrNil(t.Agent), ManagedServiceProvider: tokens, + DeprecatedTokens: config.DeprecatedTokens{ + Master: stringPtrOrNil(t.Master), + AgentMaster: stringPtrOrNil(t.AgentMaster), + }, } } } diff --git a/agent/auto-config/config_translate_test.go b/agent/auto-config/config_translate_test.go index 0bdbec0bc..b306778d2 100644 --- a/agent/auto-config/config_translate_test.go +++ b/agent/auto-config/config_translate_test.go @@ -129,9 +129,7 @@ func TestTranslateConfig(t *testing.T) { EnableKeyListPolicy: boolPointer(true), EnableTokenPersistence: boolPointer(true), Tokens: config.Tokens{ - Master: stringPointer("99e7e490-6baf-43fc-9010-78b6aa9a6813"), Replication: stringPointer("51308d40-465c-4ac6-a636-7c0747edec89"), - AgentMaster: stringPointer("e012e1ea-78a2-41cc-bc8b-231a44196f39"), Default: stringPointer("8781a3f5-de46-4b45-83e1-c92f4cfd0332"), Agent: stringPointer("ddb8f1b0-8a99-4032-b601-87926bce244e"), ManagedServiceProvider: []config.ServiceProviderToken{ @@ -140,6 +138,10 @@ func TestTranslateConfig(t *testing.T) { SecretID: stringPointer("e28b820a-438e-4e2b-ad24-fe59e6a4914f"), }, }, + DeprecatedTokens: config.DeprecatedTokens{ + Master: stringPointer("99e7e490-6baf-43fc-9010-78b6aa9a6813"), + AgentMaster: stringPointer("e012e1ea-78a2-41cc-bc8b-231a44196f39"), + }, }, }, AutoEncrypt: config.AutoEncrypt{ diff --git a/agent/config/builder.go b/agent/config/builder.go index d1f3fed8f..012229ae3 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -861,7 +861,7 @@ func (b *builder) build() (rt RuntimeConfig, err error) { }, ACLEnableKeyListPolicy: boolVal(c.ACL.EnableKeyListPolicy), - ACLMasterToken: stringVal(c.ACL.Tokens.Master), + ACLMasterToken: stringVal(c.ACL.Tokens.InitialManagement), ACLTokenReplication: boolVal(c.ACL.TokenReplication), @@ -870,7 +870,7 @@ func (b *builder) build() (rt RuntimeConfig, err error) { EnablePersistence: boolValWithDefault(c.ACL.EnableTokenPersistence, false), ACLDefaultToken: stringVal(c.ACL.Tokens.Default), ACLAgentToken: stringVal(c.ACL.Tokens.Agent), - ACLAgentMasterToken: stringVal(c.ACL.Tokens.AgentMaster), + ACLAgentMasterToken: stringVal(c.ACL.Tokens.AgentRecovery), ACLReplicationToken: stringVal(c.ACL.Tokens.Replication), }, diff --git a/agent/config/builder_oss_test.go b/agent/config/builder_oss_test.go index 99a1be04d..2fd5f50ad 100644 --- a/agent/config/builder_oss_test.go +++ b/agent/config/builder_oss_test.go @@ -111,7 +111,11 @@ func TestValidateEnterpriseConfigKeys(t *testing.T) { config: Config{ ReadReplica: &boolVal, SegmentName: &stringVal, - ACL: ACL{Tokens: Tokens{AgentMaster: &stringVal}}, + ACL: ACL{ + Tokens: Tokens{ + DeprecatedTokens: DeprecatedTokens{AgentMaster: &stringVal}, + }, + }, }, badKeys: []string{"read_replica (or the deprecated non_voting_server)", "segment"}, }, diff --git a/agent/config/config.go b/agent/config/config.go index 3b5b417dd..61161b7b5 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -742,14 +742,23 @@ type ACL struct { } type Tokens struct { - Master *string `mapstructure:"master"` - Replication *string `mapstructure:"replication"` - AgentMaster *string `mapstructure:"agent_master"` - Default *string `mapstructure:"default"` - Agent *string `mapstructure:"agent"` + InitialManagement *string `mapstructure:"initial_management"` + Replication *string `mapstructure:"replication"` + AgentRecovery *string `mapstructure:"agent_recovery"` + Default *string `mapstructure:"default"` + Agent *string `mapstructure:"agent"` // Enterprise Only ManagedServiceProvider []ServiceProviderToken `mapstructure:"managed_service_provider"` + + DeprecatedTokens `mapstructure:",squash"` +} + +type DeprecatedTokens struct { + // DEPRECATED (ACL) - renamed to "initial_management" + Master *string `mapstructure:"master"` + // DEPRECATED (ACL) - renamed to "agent_recovery" + AgentMaster *string `mapstructure:"agent_master"` } // ServiceProviderToken groups an accessor and secret for a service provider token. Enterprise Only diff --git a/agent/config/deprecated.go b/agent/config/deprecated.go index 11ea57d15..c026b21e0 100644 --- a/agent/config/deprecated.go +++ b/agent/config/deprecated.go @@ -34,11 +34,21 @@ func applyDeprecatedConfig(d *decodeTarget) (Config, []string) { dep := d.DeprecatedConfig var warns []string - if dep.ACLAgentMasterToken != nil { - if d.Config.ACL.Tokens.AgentMaster == nil { - d.Config.ACL.Tokens.AgentMaster = dep.ACLAgentMasterToken + // TODO(boxofrad): The DeprecatedConfig struct only holds fields that were once + // on the top-level Config struct (not nested fields e.g. ACL.Tokens) maybe we + // should rethink this a bit? + if d.Config.ACL.Tokens.AgentMaster != nil { + if d.Config.ACL.Tokens.AgentRecovery == nil { + d.Config.ACL.Tokens.AgentRecovery = d.Config.ACL.Tokens.AgentMaster } - warns = append(warns, deprecationWarning("acl_agent_master_token", "acl.tokens.agent_master")) + warns = append(warns, deprecationWarning("acl.tokens.agent_master", "acl.tokens.agent_recovery")) + } + + if dep.ACLAgentMasterToken != nil { + if d.Config.ACL.Tokens.AgentRecovery == nil { + d.Config.ACL.Tokens.AgentRecovery = dep.ACLAgentMasterToken + } + warns = append(warns, deprecationWarning("acl_agent_master_token", "acl.tokens.agent_recovery")) } if dep.ACLAgentToken != nil { @@ -55,11 +65,18 @@ func applyDeprecatedConfig(d *decodeTarget) (Config, []string) { warns = append(warns, deprecationWarning("acl_token", "acl.tokens.default")) } - if dep.ACLMasterToken != nil { - if d.Config.ACL.Tokens.Master == nil { - d.Config.ACL.Tokens.Master = dep.ACLMasterToken + if d.Config.ACL.Tokens.Master != nil { + if d.Config.ACL.Tokens.InitialManagement == nil { + d.Config.ACL.Tokens.InitialManagement = d.Config.ACL.Tokens.Master } - warns = append(warns, deprecationWarning("acl_master_token", "acl.tokens.master")) + warns = append(warns, deprecationWarning("acl.tokens.master", "acl.tokens.initial_management")) + } + + if dep.ACLMasterToken != nil { + if d.Config.ACL.Tokens.InitialManagement == nil { + d.Config.ACL.Tokens.InitialManagement = dep.ACLMasterToken + } + warns = append(warns, deprecationWarning("acl_master_token", "acl.tokens.initial_management")) } if dep.ACLReplicationToken != nil { diff --git a/agent/config/deprecated_test.go b/agent/config/deprecated_test.go index 98f7fa07a..4cdcfb10d 100644 --- a/agent/config/deprecated_test.go +++ b/agent/config/deprecated_test.go @@ -15,12 +15,10 @@ data_dir = "/foo" acl_datacenter = "dcone" -acl_agent_master_token = "token1" -acl_agent_token = "token2" -acl_token = "token3" +acl_agent_token = "token1" +acl_token = "token2" -acl_master_token = "token4" -acl_replication_token = "token5" +acl_replication_token = "token3" acl_default_policy = "deny" acl_down_policy = "async-cache" @@ -35,13 +33,11 @@ acl_enable_key_list_policy = true require.NoError(t, err) expectWarns := []string{ - deprecationWarning("acl_agent_master_token", "acl.tokens.agent_master"), deprecationWarning("acl_agent_token", "acl.tokens.agent"), deprecationWarning("acl_datacenter", "primary_datacenter"), deprecationWarning("acl_default_policy", "acl.default_policy"), deprecationWarning("acl_down_policy", "acl.down_policy"), deprecationWarning("acl_enable_key_list_policy", "acl.enable_key_list_policy"), - deprecationWarning("acl_master_token", "acl.tokens.master"), deprecationWarning("acl_replication_token", "acl.tokens.replication"), deprecationWarning("acl_token", "acl.tokens.default"), deprecationWarning("acl_ttl", "acl.token_ttl"), @@ -55,11 +51,9 @@ acl_enable_key_list_policy = true rt := result.RuntimeConfig require.Equal(t, true, rt.ACLsEnabled) require.Equal(t, "dcone", rt.PrimaryDatacenter) - require.Equal(t, "token1", rt.ACLTokens.ACLAgentMasterToken) - require.Equal(t, "token2", rt.ACLTokens.ACLAgentToken) - require.Equal(t, "token3", rt.ACLTokens.ACLDefaultToken) - require.Equal(t, "token4", rt.ACLMasterToken) - require.Equal(t, "token5", rt.ACLTokens.ACLReplicationToken) + require.Equal(t, "token1", rt.ACLTokens.ACLAgentToken) + require.Equal(t, "token2", rt.ACLTokens.ACLDefaultToken) + require.Equal(t, "token3", rt.ACLTokens.ACLReplicationToken) require.Equal(t, "deny", rt.ACLResolverSettings.ACLDefaultPolicy) require.Equal(t, "async-cache", rt.ACLResolverSettings.ACLDownPolicy) require.Equal(t, 3*time.Hour, rt.ACLResolverSettings.ACLTokenTTL) @@ -91,3 +85,91 @@ enable_acl_replication = true rt := result.RuntimeConfig require.Equal(t, true, rt.ACLTokenReplication) } + +func TestLoad_DeprecatedConfig_ACLMasterTokens(t *testing.T) { + t.Run("top-level fields", func(t *testing.T) { + require := require.New(t) + + opts := LoadOpts{ + HCL: []string{` + data_dir = "/foo" + + acl_master_token = "token1" + acl_agent_master_token = "token2" + `}, + } + patchLoadOptsShims(&opts) + + result, err := Load(opts) + require.NoError(err) + + expectWarns := []string{ + deprecationWarning("acl_master_token", "acl.tokens.initial_management"), + deprecationWarning("acl_agent_master_token", "acl.tokens.agent_recovery"), + } + require.ElementsMatch(expectWarns, result.Warnings) + + rt := result.RuntimeConfig + require.Equal("token1", rt.ACLMasterToken) + require.Equal("token2", rt.ACLTokens.ACLAgentMasterToken) + }) + + t.Run("embedded in tokens struct", func(t *testing.T) { + require := require.New(t) + + opts := LoadOpts{ + HCL: []string{` + data_dir = "/foo" + + acl { + tokens { + master = "token1" + agent_master = "token2" + } + } + `}, + } + patchLoadOptsShims(&opts) + + result, err := Load(opts) + require.NoError(err) + + expectWarns := []string{ + deprecationWarning("acl.tokens.master", "acl.tokens.initial_management"), + deprecationWarning("acl.tokens.agent_master", "acl.tokens.agent_recovery"), + } + require.ElementsMatch(expectWarns, result.Warnings) + + rt := result.RuntimeConfig + require.Equal("token1", rt.ACLMasterToken) + require.Equal("token2", rt.ACLTokens.ACLAgentMasterToken) + }) + + t.Run("both", func(t *testing.T) { + require := require.New(t) + + opts := LoadOpts{ + HCL: []string{` + data_dir = "/foo" + + acl_master_token = "token1" + acl_agent_master_token = "token2" + + acl { + tokens { + master = "token3" + agent_master = "token4" + } + } + `}, + } + patchLoadOptsShims(&opts) + + result, err := Load(opts) + require.NoError(err) + + rt := result.RuntimeConfig + require.Equal("token3", rt.ACLMasterToken) + require.Equal("token4", rt.ACLTokens.ACLAgentMasterToken) + }) +} diff --git a/agent/config/runtime.go b/agent/config/runtime.go index aae4f67b5..2e7d7cf97 100644 --- a/agent/config/runtime.go +++ b/agent/config/runtime.go @@ -77,7 +77,7 @@ type RuntimeConfig struct { // on the servers in the PrimaryDatacenter. When the leader comes online, it ensures // that the Master token is available. This provides the initial token. // - // hcl: acl.tokens.master = string + // hcl: acl.tokens.initial_management = string ACLMasterToken string // ACLtokenReplication is used to indicate that both tokens and policies diff --git a/agent/config/runtime_test.go b/agent/config/runtime_test.go index 3bd4257bd..390305902 100644 --- a/agent/config/runtime_test.go +++ b/agent/config/runtime_test.go @@ -5343,7 +5343,7 @@ func TestLoad_FullConfig(t *testing.T) { DataDir: dataDir, ACLDefaultToken: "418fdff1", ACLAgentToken: "bed2377c", - ACLAgentMasterToken: "64fd0e08", + ACLAgentMasterToken: "1dba6aba", ACLReplicationToken: "5795983a", }, @@ -5361,7 +5361,7 @@ func TestLoad_FullConfig(t *testing.T) { ACLRoleTTL: 9876 * time.Second, }, ACLEnableKeyListPolicy: true, - ACLMasterToken: "8a19ac27", + ACLMasterToken: "3820e09a", ACLTokenReplication: true, AdvertiseAddrLAN: ipAddr("17.99.29.16"), AdvertiseAddrWAN: ipAddr("78.63.37.19"), @@ -6020,10 +6020,12 @@ func TestLoad_FullConfig(t *testing.T) { expectedWarns := []string{ deprecationWarning("acl_datacenter", "primary_datacenter"), - deprecationWarning("acl_agent_master_token", "acl.tokens.agent_master"), + deprecationWarning("acl_agent_master_token", "acl.tokens.agent_recovery"), + deprecationWarning("acl.tokens.agent_master", "acl.tokens.agent_recovery"), deprecationWarning("acl_agent_token", "acl.tokens.agent"), deprecationWarning("acl_token", "acl.tokens.default"), - deprecationWarning("acl_master_token", "acl.tokens.master"), + deprecationWarning("acl_master_token", "acl.tokens.initial_management"), + deprecationWarning("acl.tokens.master", "acl.tokens.initial_management"), deprecationWarning("acl_replication_token", "acl.tokens.replication"), deprecationWarning("enable_acl_replication", "acl.enable_token_replication"), deprecationWarning("acl_default_policy", "acl.default_policy"), diff --git a/agent/config/testdata/full-config.hcl b/agent/config/testdata/full-config.hcl index f21e26f0f..939745c9b 100644 --- a/agent/config/testdata/full-config.hcl +++ b/agent/config/testdata/full-config.hcl @@ -21,7 +21,9 @@ acl = { msp_disable_bootstrap = true tokens = { master = "8a19ac27", + initial_management = "3820e09a", agent_master = "64fd0e08", + agent_recovery = "1dba6aba", replication = "5795983a", agent = "bed2377c", default = "418fdff1", diff --git a/agent/config/testdata/full-config.json b/agent/config/testdata/full-config.json index 200731915..4649c86bf 100644 --- a/agent/config/testdata/full-config.json +++ b/agent/config/testdata/full-config.json @@ -22,7 +22,9 @@ "msp_disable_bootstrap": true, "tokens" : { "master" : "8a19ac27", + "initial_management" : "3820e09a", "agent_master" : "64fd0e08", + "agent_recovery" : "1dba6aba", "replication" : "5795983a", "agent" : "bed2377c", "default" : "418fdff1", diff --git a/website/content/api-docs/acl/index.mdx b/website/content/api-docs/acl/index.mdx index 5596ec0c5..5c69331ed 100644 --- a/website/content/api-docs/acl/index.mdx +++ b/website/content/api-docs/acl/index.mdx @@ -16,7 +16,7 @@ the [ACL tutorial](https://learn.hashicorp.com/tutorials/consul/access-control-s ## Bootstrap ACLs This endpoint does a special one-time bootstrap of the ACL system, making the first -management token if the [`acl.tokens.master`](/docs/agent/options#acl_tokens_master) +management token if the [`acl.tokens.initial_management`](/docs/agent/options#acl_tokens_initial_management) configuration entry is not specified in the Consul server configuration and if the cluster has not been bootstrapped previously. This is available in Consul 0.9.1 and later, and requires all Consul servers to be upgraded in order to operate. diff --git a/website/content/docs/agent/options.mdx b/website/content/docs/agent/options.mdx index e3ae0d589..4f1557c2c 100644 --- a/website/content/docs/agent/options.mdx +++ b/website/content/docs/agent/options.mdx @@ -642,19 +642,25 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'." - `tokens` ((#acl_tokens)) - This object holds all of the configured ACL tokens for the agents usage. - - `master` ((#acl_tokens_master)) - Only used for servers in the [`primary_datacenter`](#primary_datacenter). - This token will be created with management-level permissions if it does not - exist. It allows operators to bootstrap the ACL system with a token Secret - ID that is well-known. + - `initial_management` ((#acl_tokens_initial_management)) - This is available in + Consul 1.11 and later. In prior versions, use [`acl.tokens.master`](#acl_tokens_master). - The `master` token is only installed when a server acquires cluster - leadership. If you would like to install or change the `acl_master_token`, - set the new value for `master` in the configuration for all servers. Once - this is done, restart the current leader to force a leader election. If - the `master` token is not supplied, then the servers do not create a - master token. When you provide a value, it should be a UUID. To maintain - backwards compatibility and an upgrade path this restriction is not - currently enforced but will be in a future major Consul release. + Only used for servers in the [`primary_datacenter`](#primary_datacenter). + This token will be created with management-level permissions if it does not exist. + It allows operators to bootstrap the ACL system with a token Secret ID that is + well-known. + + The `initial_management` token is only installed when a server acquires cluster + leadership. If you would like to install or change it, set the new value for + `initial_management` in the configuration for all servers. Once this is done, + restart the current leader to force a leader election. If the `initial_management` + token is not supplied, then the servers do not create an initial management token. + When you provide a value, it should be a UUID. To maintain backwards compatibility + and an upgrade path this restriction is not currently enforced but will be in a + future major Consul release. + + - `master` ((#acl_tokens_master)) **Renamed in Consul 1.11 to + [`acl.tokens.initial_management`](#acl_tokens_initial_management).** - `default` ((#acl_tokens_default)) - When provided, the agent will use this token when making requests to the Consul servers. Clients can override @@ -670,8 +676,16 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'." register as in order to set any of the node-level information in the catalog such as metadata, or the node's tagged addresses. - - `agent_master` ((#acl_tokens_agent_master)) - Used to access [agent endpoints](/api/agent) - that require agent read or write privileges, or node read privileges, even if Consul servers aren't present to validate any tokens. This should only be used by operators during outages, regular ACL tokens should normally be used by applications. + - `agent_recovery` ((#acl_tokens_agent_recovery)) - This is available in Consul 1.11 + and later. In prior versions, use [`acl.tokens.agent_master`](#acl_tokens_agent_master). + + Used to access [agent endpoints](/api/agent) that require agent read or write privileges, + or node read privileges, even if Consul servers aren't present to validate any tokens. + This should only be used by operators during outages, regular ACL tokens should normally + be used by applications. + + - `agent_master` ((#acl_tokens_agent_master)) **Renamed in Consul 1.11 to + [`acl.tokens.agent_recovery`](#acl_tokens_agent_recovery).** - `replication` ((#acl_tokens_replication)) - The ACL token used to authorize secondary datacenters with the primary datacenter for replication @@ -743,17 +757,7 @@ Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'." by allowing policies to be in place before enforcement begins. - `acl_master_token` ((#acl_master_token_legacy)) - **Deprecated in Consul - 1.4.0. See the [`acl.tokens.master`](#acl_tokens_master) field instead.** Only - used for servers in the [`primary_datacenter`](#primary_datacenter). This token - will be created with management-level permissions if it does not exist. It allows - operators to bootstrap the ACL system with a token ID that is well-known. - - The `acl_master_token` is only installed when a server acquires cluster leadership. If - you would like to install or change the `acl_master_token`, set the new value for `acl_master_token` - in the configuration for all servers. Once this is done, restart the current leader to force a - leader election. If the `acl_master_token` is not supplied, then the servers do not create a master - token. When you provide a value, it can be any string value. Using a UUID would ensure that it looks - the same as the other tokens, but isn't strictly necessary. + 1.4.0. See the [`acl.tokens.master`](#acl_tokens_master) field instead.** - `acl_replication_token` ((#acl_replication_token_legacy)) - **Deprecated in Consul 1.4.0. See the [`acl.tokens.replication`](#acl_tokens_replication) field diff --git a/website/content/docs/security/acl/acl-rules.mdx b/website/content/docs/security/acl/acl-rules.mdx index cdba8d685..0d76efce7 100644 --- a/website/content/docs/security/acl/acl-rules.mdx +++ b/website/content/docs/security/acl/acl-rules.mdx @@ -493,7 +493,7 @@ with `bar`. Since [Agent API](/api/agent) utility operations may be required before an agent is joined to a cluster, or during an outage of the Consul servers or ACL datacenter, a special token may be -configured with [`acl.tokens.agent_master`](/docs/agent/options#acl_tokens_agent_master) to allow +configured with [`acl.tokens.agent_recovery`](/docs/agent/options#acl_tokens_agent_recovery) to allow write access to these operations even if no ACL resolution capability is available. ### Event Rules diff --git a/website/content/docs/security/acl/acl-system.mdx b/website/content/docs/security/acl/acl-system.mdx index 02451e1a1..927e0838d 100644 --- a/website/content/docs/security/acl/acl-system.mdx +++ b/website/content/docs/security/acl/acl-system.mdx @@ -202,16 +202,17 @@ the token itself. #### Builtin Tokens -During cluster bootstrapping when ACLs are enabled both the special `anonymous` and the `master` token will be +During cluster bootstrapping when ACLs are enabled both the special `anonymous` and the `initial_management` token will be injected. - **Anonymous Token** - The anonymous token is used when a request is made to Consul without specifying a bearer token. The anonymous token's description and policies may be updated but Consul will prevent this token's deletion. When created, it will be assigned `00000000-0000-0000-0000-000000000002` for its Accessor ID and `anonymous` for its Secret ID. -- **Master Token** - When a master token is present within the Consul configuration, it is created and will be linked - With the builtin Global Management policy giving it unrestricted privileges. The master token is created with the Secret ID - set to the value of the configuration entry. +- **Initial Management Token** - When an initial management token is present within the Consul configuration, it is created + and will be linked with the builtin Global Management policy giving it unrestricted privileges. The initial management + token is created with the Secret ID set to the value of the configuration entry. + In Consul 1.4 - 1.10, this was called the `master` token. It was renamed to `initial_management` token in Consul 1.11. #### Authorization @@ -291,18 +292,27 @@ as to whether they are set on servers, clients, or both. A number of special tokens can also be configured which allow for bootstrapping the ACL system, or accessing Consul in special situations: -| Special Token | Servers | Clients | Purpose | -| ------------------------------------------------------------------------ | ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`acl.tokens.agent_master`](/docs/agent/options#acl_tokens_agent_master) | `OPTIONAL` | `OPTIONAL` | Special token that can be used to access [Agent API](/api/agent) when remote bearer token resolution fails; used for setting up the cluster such as doing initial join operations, see the [ACL Agent Master Token](#acl-agent-master-token) section for more details | -| [`acl.tokens.agent`](/docs/agent/options#acl_tokens_agent) | `OPTIONAL` | `OPTIONAL` | Special token that is used for an agent's internal operations, see the [ACL Agent Token](#acl-agent-token) section for more details | -| [`acl.tokens.master`](/docs/agent/options#acl_tokens_master) | `OPTIONAL` | `N/A` | Special token used to bootstrap the ACL system, check the [Bootstrapping ACLs](https://learn.hashicorp.com/tutorials/consul/access-control-setup-production) tutorial for more details | -| [`acl.tokens.default`](/docs/agent/options#acl_tokens_default) | `OPTIONAL` | `OPTIONAL` | Default token to use for client requests where no token is supplied; this is often configured with read-only access to services to enable DNS service discovery on agents | +| Special Token | Servers | Clients | Purpose | +| ------------------------------------------------------------------------------------ | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`acl.tokens.agent_recovery`](/docs/agent/options#acl_tokens_agent_recovery) | `OPTIONAL` | `OPTIONAL` | Special token that can be used to access [Agent API](/api/agent) when remote bearer token resolution fails; used for setting up the cluster such as doing initial join operations, see the [ACL Agent Recovery Token](#acl-agent-recovery-token) section for more details | +| [`acl.tokens.agent`](/docs/agent/options#acl_tokens_agent) | `OPTIONAL` | `OPTIONAL` | Special token that is used for an agent's internal operations, see the [ACL Agent Token](#acl-agent-token) section for more details | +| [`acl.tokens.initial_management`](/docs/agent/options#acl_tokens_initial_management) | `OPTIONAL` | `N/A` | Special token used to bootstrap the ACL system, check the [Bootstrapping ACLs](https://learn.hashicorp.com/tutorials/consul/access-control-setup-production) tutorial for more details | +| [`acl.tokens.default`](/docs/agent/options#acl_tokens_default) | `OPTIONAL` | `OPTIONAL` | Default token to use for client requests where no token is supplied; this is often configured with read-only access to services to enable DNS service discovery on agents | -All of these tokens except the `master` token can all be introduced or updated via the [/v1/agent/token API](/api/agent#update-acl-tokens). +All of these tokens except the `initial_management` token can all be introduced or updated via the [/v1/agent/token API](/api/agent#update-acl-tokens). -#### ACL Agent Master Token +In Consul 1.4 - 1.10, the following special tokens were known by different names: -Since the [`acl.tokens.agent_master`](/docs/agent/options#acl_tokens_agent_master) is designed to be used when the Consul servers are not available, its policy is managed locally on the agent and does not need to have a token defined on the Consul servers via the ACL API. Once set, it implicitly has the following policy associated with it +| New Name (1.11+) | Old Name (1.4 - 1.10) | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| [`acl.tokens.agent_recovery`](/docs/agent/options#acl_tokens_agent_recovery) | [`acl.tokens.agent_master`](/docs/agent/options#acl_tokens_agent_master) | +| [`acl.tokens.initial_management`](/docs/agent/options#acl_tokens_initial_management) | [`acl.tokens.master`](/docs/agent/options#acl_tokens_master) | + +#### ACL Agent Recovery Token + +Since the [`acl.tokens.agent_recovery`](/docs/agent/options#acl_tokens_agent_recovery) is designed to be used when the Consul servers are not available, its policy is managed locally on the agent and does not need to have a token defined on the Consul servers via the ACL API. Once set, it implicitly has the following policy associated with it + +In Consul 1.4 - 1.10, this was called the `agent_master` token. It was renamed to `agent_recovery` token in Consul 1.11. ```hcl agent "" {