mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
Specify headers by environment variable (#21993)
* Specify headers by environment var * Add changelog entry * Add tests, docs * Formatting --------- Co-authored-by: Violet Hynes <violet.hynes@hashicorp.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -41,6 +42,7 @@ const (
|
||||
EnvVaultClientCert = "VAULT_CLIENT_CERT"
|
||||
EnvVaultClientKey = "VAULT_CLIENT_KEY"
|
||||
EnvVaultClientTimeout = "VAULT_CLIENT_TIMEOUT"
|
||||
EnvVaultHeaders = "VAULT_HEADERS"
|
||||
EnvVaultSRVLookup = "VAULT_SRV_LOOKUP"
|
||||
EnvVaultSkipVerify = "VAULT_SKIP_VERIFY"
|
||||
EnvVaultNamespace = "VAULT_NAMESPACE"
|
||||
@@ -665,6 +667,30 @@ func NewClient(c *Config) (*Client, error) {
|
||||
client.setNamespace(namespace)
|
||||
}
|
||||
|
||||
if envHeaders := os.Getenv(EnvVaultHeaders); envHeaders != "" {
|
||||
var result map[string]any
|
||||
err := json.Unmarshal([]byte(envHeaders), &result)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not unmarshal environment-supplied headers")
|
||||
}
|
||||
var forbiddenHeaders []string
|
||||
for key, value := range result {
|
||||
if strings.HasPrefix(key, "X-Vault-") {
|
||||
forbiddenHeaders = append(forbiddenHeaders, key)
|
||||
continue
|
||||
}
|
||||
|
||||
value, ok := value.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("environment-supplied headers include non-string values")
|
||||
}
|
||||
client.AddHeader(key, value)
|
||||
}
|
||||
if len(forbiddenHeaders) > 0 {
|
||||
return nil, fmt.Errorf("failed to setup Headers[%s]: Header starting by 'X-Vault-' are for internal usage only", strings.Join(forbiddenHeaders, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -374,6 +374,61 @@ func TestDefaulRetryPolicy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientEnvHeaders(t *testing.T) {
|
||||
oldHeaders := os.Getenv(EnvVaultHeaders)
|
||||
|
||||
defer func() {
|
||||
os.Setenv(EnvVaultHeaders, oldHeaders)
|
||||
}()
|
||||
|
||||
cases := []struct {
|
||||
Input string
|
||||
Valid bool
|
||||
}{
|
||||
{
|
||||
"{}",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"{\"foo\": \"bar\"}",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"{\"foo\": 1}", // Values must be strings
|
||||
false,
|
||||
},
|
||||
{
|
||||
"{\"X-Vault-Foo\": \"bar\"}", // X-Vault-* not allowed
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
os.Setenv(EnvVaultHeaders, tc.Input)
|
||||
config := DefaultConfig()
|
||||
config.ReadEnvironment()
|
||||
_, err := NewClient(config)
|
||||
if err != nil {
|
||||
if tc.Valid {
|
||||
t.Fatalf("unexpected error reading headers from environment: %v", err)
|
||||
}
|
||||
} else {
|
||||
if !tc.Valid {
|
||||
t.Fatal("no error reading headers from environment when error was expected")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os.Setenv(EnvVaultHeaders, "{\"foo\": \"bar\"}")
|
||||
config := DefaultConfig()
|
||||
config.ReadEnvironment()
|
||||
cli, _ := NewClient(config)
|
||||
|
||||
if !reflect.DeepEqual(cli.Headers().Values("foo"), []string{"bar"}) {
|
||||
t.Error("Environment-supplied headers not set in CLI client")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientEnvSettings(t *testing.T) {
|
||||
cwd, _ := os.Getwd()
|
||||
|
||||
|
||||
3
changelog/21993.txt
Normal file
3
changelog/21993.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:improvement
|
||||
cli: Allow vault CLI HTTP headers to be specified using the JSON-encoded VAULT_HEADERS environment variable
|
||||
```
|
||||
@@ -439,6 +439,12 @@ Prevents the Vault client from following redirects. By default, the Vault client
|
||||
|
||||
~> **Note:** Disabling redirect following behavior could cause issues with commands such as 'vault operator raft snapshot' as this command redirects the request to the cluster's primary node.
|
||||
|
||||
### `VAULT_HEADERS`
|
||||
|
||||
JSON-encoded headers to include in Vault HTTP requests performed by the CLI. For example: `{"FOO": "BAR"}`.
|
||||
|
||||
Like the `-header` CLI parameter, headers starting with `X-Vault-` are forbidden.
|
||||
|
||||
## Flags
|
||||
|
||||
There are different CLI flags that are available depending on subcommands. Some
|
||||
|
||||
Reference in New Issue
Block a user