VAULT-17292 CE portion of changes (#24667)

* VAULT-17292 CE portion of changes

* VAULT-17292 docs

* VAULT-17292 changelog
This commit is contained in:
Violet Hynes 2024-01-04 13:01:38 -05:00 committed by GitHub
parent ade75bcf00
commit a649d2b9a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 106 additions and 23 deletions

6
changelog/24667.txt Normal file
View File

@ -0,0 +1,6 @@
```release-note:improvement
agent: Added new namespace top level configuration parameter, which can be used to make requests made by Agent to go to that namespace.
```
```release-note:improvement
proxy: Added new namespace top level configuration parameter, and prepend_configured_namespace API Proxy configuration parameter, which can be used to make requests made to Proxy get proxied to that namespace.
```

View File

@ -309,14 +309,25 @@ func (c *AgentCommand) Run(args []string) int {
}
c.metricsHelper = metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled)
var templateNamespace string
// This indicates whether the namespace for the client has been set by environment variable.
// If it has, we don't touch it
namespaceSetByEnvironmentVariable := client.Namespace() != ""
if !namespaceSetByEnvironmentVariable && config.Vault != nil && config.Vault.Namespace != "" {
client.SetNamespace(config.Vault.Namespace)
}
var method auth.AuthMethod
var sinks []*sink.SinkConfig
var templateNamespace string
if config.AutoAuth != nil {
if client.Headers().Get(consts.NamespaceHeaderName) == "" && config.AutoAuth.Method.Namespace != "" {
// Note: This will only set namespace header to the value in config.AutoAuth.Method.Namespace
// only if it hasn't been set by config.Vault.Namespace above. In that case, the config value
// present at config.AutoAuth.Method.Namespace will still be used for auto-auth.
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
client.SetNamespace(config.AutoAuth.Method.Namespace)
}
templateNamespace = client.Headers().Get(consts.NamespaceHeaderName)
templateNamespace = client.Namespace()
sinkClient, err := client.CloneWithHeaders()
if err != nil {
@ -707,6 +718,11 @@ func (c *AgentCommand) Run(args []string) int {
return 1
}
// Override the set namespace with the auto-auth specific namespace
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
ahClient.SetNamespace(config.AutoAuth.Method.Namespace)
}
if config.DisableIdleConnsAutoAuth {
ahClient.SetMaxIdleConnections(-1)
}

View File

@ -91,6 +91,7 @@ type Vault struct {
ClientCert string `hcl:"client_cert"`
ClientKey string `hcl:"client_key"`
TLSServerName string `hcl:"tls_server_name"`
Namespace string `hcl:"namespace"`
Retry *Retry `hcl:"retry"`
}

View File

@ -262,7 +262,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
}
if ah.wrapTTL > 0 {
wrapClient, err := clientToUse.Clone()
wrapClient, err := clientToUse.CloneWithHeaders()
if err != nil {
ah.logger.Error("error creating client for wrapped call", "error", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
@ -289,7 +289,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
isTokenFileMethod = path == "auth/token/lookup-self"
if isTokenFileMethod {
token, _ := data["token"].(string)
lookupSelfClient, err := clientToUse.Clone()
lookupSelfClient, err := clientToUse.CloneWithHeaders()
if err != nil {
ah.logger.Error("failed to clone client to perform token lookup")
return err

View File

@ -12,6 +12,7 @@ import (
hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/http"
)
@ -41,6 +42,10 @@ type APIProxy struct {
lastIndexStates []string
userAgentString string
userAgentStringFunction func(string) string
// clientNamespace is a one-time set representation of the namespace of the client
// (i.e. client.Namespace()) to avoid repeated calls and lock usage.
clientNamespace string
prependConfiguredNamespace bool
}
var _ Proxier = &APIProxy{}
@ -56,6 +61,9 @@ type APIProxyConfig struct {
// UserAgentStringFunction is the function to transform the proxied client's
// user agent into one that includes Vault-specific information.
UserAgentStringFunction func(string) string
// PrependConfiguredNamespace configures whether the client's namespace
// should be prepended to proxied requests
PrependConfiguredNamespace bool
}
func NewAPIProxy(config *APIProxyConfig) (Proxier, error) {
@ -69,6 +77,8 @@ func NewAPIProxy(config *APIProxyConfig) (Proxier, error) {
whenInconsistentAction: config.WhenInconsistentAction,
userAgentString: config.UserAgentString,
userAgentStringFunction: config.UserAgentStringFunction,
prependConfiguredNamespace: config.PrependConfiguredNamespace,
clientNamespace: namespace.Canonicalize(config.Client.Namespace()),
}, nil
}
@ -102,6 +112,11 @@ func (ap *APIProxy) Send(ctx context.Context, req *SendRequest) (*SendResponse,
}
client.SetHeaders(req.Request.Header)
if ap.prependConfiguredNamespace && ap.clientNamespace != "" {
currentNamespace := namespace.Canonicalize(client.Namespace())
newNamespace := namespace.Canonicalize(ap.clientNamespace + currentNamespace)
client.SetNamespace(newNamespace)
}
fwReq := client.NewRequest(req.Request.Method, req.Request.URL.Path)
fwReq.BodyBytes = req.RequestBody

View File

@ -284,10 +284,21 @@ func (c *ProxyCommand) Run(args []string) int {
}
c.metricsHelper = metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled)
// This indicates whether the namespace for the client has been set by environment variable.
// If it has, we don't touch it
namespaceSetByEnvironmentVariable := client.Namespace() != ""
if !namespaceSetByEnvironmentVariable && config.Vault != nil && config.Vault.Namespace != "" {
client.SetNamespace(config.Vault.Namespace)
}
var method auth.AuthMethod
var sinks []*sink.SinkConfig
if config.AutoAuth != nil {
if client.Headers().Get(consts.NamespaceHeaderName) == "" && config.AutoAuth.Method.Namespace != "" {
// Note: This will only set namespace header to the value in config.AutoAuth.Method.Namespace
// only if it hasn't been set by config.Vault.Namespace above. In that case, the config value
// present at config.AutoAuth.Method.Namespace will still be used for auto-auth.
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
client.SetNamespace(config.AutoAuth.Method.Namespace)
}
@ -427,6 +438,7 @@ func (c *ProxyCommand) Run(args []string) int {
WhenInconsistentAction: whenInconsistent,
UserAgentStringFunction: useragent.ProxyStringWithProxiedUserAgent,
UserAgentString: useragent.ProxyAPIProxyString(),
PrependConfiguredNamespace: config.APIProxy != nil && config.APIProxy.PrependConfiguredNamespace,
})
if err != nil {
c.UI.Error(fmt.Sprintf("Error creating API proxy: %v", err))
@ -686,6 +698,11 @@ func (c *ProxyCommand) Run(args []string) int {
return 1
}
// Override the set namespace with the auto-auth specific namespace
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
ahClient.SetNamespace(config.AutoAuth.Method.Namespace)
}
if config.DisableIdleConnsAutoAuth {
ahClient.SetMaxIdleConnections(-1)
}

View File

@ -77,6 +77,7 @@ type Vault struct {
ClientCert string `hcl:"client_cert"`
ClientKey string `hcl:"client_key"`
TLSServerName string `hcl:"tls_server_name"`
Namespace string `hcl:"namespace"`
Retry *Retry `hcl:"retry"`
}
@ -97,6 +98,7 @@ type APIProxy struct {
ForceAutoAuthToken bool `hcl:"-"`
EnforceConsistency string `hcl:"enforce_consistency"`
WhenInconsistent string `hcl:"when_inconsistent"`
PrependConfiguredNamespace bool `hcl:"prepend_configured_namespace"`
}
// Cache contains any configuration needed for Cache mode

View File

@ -214,6 +214,12 @@ configuration entries:
connecting via TLS. This value can be overridden by setting the
`VAULT_TLS_SERVER_NAME` environment variable.
- `namespace` `(string: <optional>)` - Namespace to use for all of Vault Agent's
requests to Vault. This can also be specified by command line or environment variable.
The order of precedence is: this setting lowest, followed by the environment variable
`VAULT_NAMESPACE`, and then the highest precedence command-line option `-namespace`.
If none of these are specified, defaults to the root namespace.
#### retry stanza
The `vault` stanza may contain a `retry` stanza that controls how failing Vault

View File

@ -128,6 +128,10 @@ These are common configuration values that live within the `method` block:
If none of these are specified, defaults to the root namespace.
Note that because sink response wrapping and templating are also based
on the client created by auto-auth, they use the same namespace.
If specified alongside the `namespace` option in the Vault Stanza of
[Vault Agent](/vault/docs/agent-and-proxy/agent#vault-stanza) or
[Vault Proxy](/vault/docs/agent-and-proxy/proxy#vault-stanza), that
configuration will take precedence on everything except auto-auth.
- `wrap_ttl` `(string or integer: optional)` - If specified, the written token
will be response-wrapped by auto-auth. This is more secure than wrapping by

View File

@ -55,6 +55,16 @@ configuration will be overridden and the token in the request will be used to
forward the request to the Vault server. If set to `"force"` Proxy will use the
auto-auth token, overwriting the attached Vault token if set.
- `prepend_configured_namespace` `(bool: false)` - If set, when Proxy has a
namespace configured, such as through the
[Vault stanza](/vault/docs/agent-and-proxy/proxy#vault-stanza), all requests
proxied to Vault will have the configured namespace prepended to the namespace
header. If Proxy's namespace is set to `ns1` and Proxy is sent a request with the
namespace `ns2`, the request will go to the `ns1/ns2` namespace. Likewise, if Proxy
is sent a request without a namespace, the request will go to the `ns1` namespace.
In essence, what this means is that all proxied requests must go to the configured
namespace or to its child namespaces.
The following two `api_proxy` options are only useful when making requests to a Vault
Enterprise cluster, and are documented as part of its
[Eventual Consistency](/vault/docs/enterprise/consistency#vault-agent-and-consistency-headers)

View File

@ -188,6 +188,12 @@ be overridden by setting the `VAULT_SKIP_VERIFY` environment variable.
connecting via TLS. This value can be overridden by setting the
`VAULT_TLS_SERVER_NAME` environment variable.
- `namespace` `(string: <optional>)` - Namespace to use for all of Vault Proxy's
requests to Vault. This can also be specified by command line or environment variable.
The order of precedence is: this setting lowest, followed by the environment variable
`VAULT_NAMESPACE`, and then the highest precedence command-line option `-namespace`.
If none of these are specified, defaults to the root namespace.
#### retry stanza
The `vault` stanza may contain a `retry` stanza that controls how failing Vault