mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-06 14:47:01 +02:00
Support trimming trailing slashes via a mount tuneable to support CMPv2 (#28752)
* Support trimming trailing slashes via a mount tuneable to support CMPv2 * changelog/ * Perform trimming in handleLoginRequest too * Eagerly fetch the mount entry so we only test this once * Add a mount match function that gets path and entry * Update vault/request_handling.go Co-authored-by: Steven Clark <steven.clark@hashicorp.com> * more docs * Some patches (from ENT) didnt apply * patch fail * Update vault/router.go Co-authored-by: Steven Clark <steven.clark@hashicorp.com> * PR feedback * dupe * another dupe * Add support for enabling trim_request_trailing_slashes on mount creation * Fix read mount api returning configuration for trim_request_trailing_slashes * Fix test assertion * Switch enable and tune arguments to BoolPtrVal to allow end-users to specify false flag * Add trim-request-trailing-slashes to the auth enable API and CLI --------- Co-authored-by: Steven Clark <steven.clark@hashicorp.com>
This commit is contained in:
parent
314874c2b1
commit
415d260995
@ -290,23 +290,23 @@ type MountInput struct {
|
||||
}
|
||||
|
||||
type MountConfigInput struct {
|
||||
Options map[string]string `json:"options" mapstructure:"options"`
|
||||
DefaultLeaseTTL string `json:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
Description *string `json:"description,omitempty" mapstructure:"description"`
|
||||
MaxLeaseTTL string `json:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
ForceNoCache bool `json:"force_no_cache" mapstructure:"force_no_cache"`
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility string `json:"listing_visibility,omitempty" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" mapstructure:"allowed_response_headers"`
|
||||
TokenType string `json:"token_type,omitempty" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
PluginVersion string `json:"plugin_version,omitempty"`
|
||||
UserLockoutConfig *UserLockoutConfigInput `json:"user_lockout_config,omitempty"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
|
||||
Options map[string]string `json:"options" mapstructure:"options"`
|
||||
DefaultLeaseTTL string `json:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
Description *string `json:"description,omitempty" mapstructure:"description"`
|
||||
MaxLeaseTTL string `json:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
ForceNoCache bool `json:"force_no_cache" mapstructure:"force_no_cache"`
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility string `json:"listing_visibility,omitempty" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" mapstructure:"allowed_response_headers"`
|
||||
TokenType string `json:"token_type,omitempty" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
PluginVersion string `json:"plugin_version,omitempty"`
|
||||
UserLockoutConfig *UserLockoutConfigInput `json:"user_lockout_config,omitempty"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
TrimRequestTrailingSlashes *bool `json:"trim_request_trailing_slashes,omitempty" mapstructure:"trim_request_trailing_slashes"`
|
||||
// Deprecated: This field will always be blank for newer server responses.
|
||||
PluginName string `json:"plugin_name,omitempty" mapstructure:"plugin_name"`
|
||||
}
|
||||
@ -328,19 +328,20 @@ type MountOutput struct {
|
||||
}
|
||||
|
||||
type MountConfigOutput struct {
|
||||
DefaultLeaseTTL int `json:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL int `json:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
ForceNoCache bool `json:"force_no_cache" mapstructure:"force_no_cache"`
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility string `json:"listing_visibility,omitempty" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" mapstructure:"allowed_response_headers"`
|
||||
TokenType string `json:"token_type,omitempty" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
UserLockoutConfig *UserLockoutConfigOutput `json:"user_lockout_config,omitempty"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
DefaultLeaseTTL int `json:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL int `json:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
ForceNoCache bool `json:"force_no_cache" mapstructure:"force_no_cache"`
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility string `json:"listing_visibility,omitempty" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" mapstructure:"allowed_response_headers"`
|
||||
TokenType string `json:"token_type,omitempty" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
UserLockoutConfig *UserLockoutConfigOutput `json:"user_lockout_config,omitempty"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
TrimRequestTrailingSlashes bool `json:"trim_request_trailing_slashes,omitempty" mapstructure:"trim_request_trailing_slashes"`
|
||||
|
||||
// Deprecated: This field will always be blank for newer server responses.
|
||||
PluginName string `json:"plugin_name,omitempty" mapstructure:"plugin_name"`
|
||||
|
3
changelog/28752.txt
Normal file
3
changelog/28752.txt
Normal file
@ -0,0 +1,3 @@
|
||||
```release-note:improvement
|
||||
core: Add a mount tuneable that trims trailing slashes of request paths during POST. Needed to support CMPv2 in PKI.
|
||||
```
|
@ -23,24 +23,25 @@ var (
|
||||
type AuthEnableCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPluginName string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagTokenType string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagIdentityTokenKey string
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPluginName string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagTokenType string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *AuthEnableCommand) Synopsis() string {
|
||||
@ -217,6 +218,12 @@ func (c *AuthEnableCommand) Flags() *FlagSets {
|
||||
Usage: "Select the key used to sign plugin identity tokens.",
|
||||
})
|
||||
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@ -324,6 +331,11 @@ func (c *AuthEnableCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
authOpts.Config.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
authOpts.Config.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
if err := client.Sys().EnableAuthWithOptions(authPath, authOpts); err != nil {
|
||||
|
@ -100,6 +100,7 @@ func TestAuthEnableCommand_Run(t *testing.T) {
|
||||
"-allowed-response-headers", "authorization",
|
||||
"-listing-visibility", "unauth",
|
||||
"-identity-token-key", "default",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"userpass",
|
||||
})
|
||||
if exp := 0; code != exp {
|
||||
@ -127,6 +128,9 @@ func TestAuthEnableCommand_Run(t *testing.T) {
|
||||
if exp := "The best kind of test"; authInfo.Description != exp {
|
||||
t.Errorf("expected %q to be %q", authInfo.Description, exp)
|
||||
}
|
||||
if !authInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization,authentication", "www-authentication"}, authInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values in PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ type AuthTuneCommand struct {
|
||||
flagUserLockoutCounterResetDuration time.Duration
|
||||
flagUserLockoutDisable bool
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *AuthTuneCommand) Synopsis() string {
|
||||
@ -195,6 +196,11 @@ func (c *AuthTuneCommand) Flags() *FlagSets {
|
||||
Usage: "Select the semantic version of the plugin to run. The new version must be registered in " +
|
||||
"the plugin catalog, and will not start running until the plugin is reloaded.",
|
||||
})
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: flagNameIdentityTokenKey,
|
||||
@ -306,6 +312,11 @@ func (c *AuthTuneCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
mountConfigInput.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
mountConfigInput.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
// Append /auth (since that's where auths live) and a trailing slash to
|
||||
|
@ -120,6 +120,7 @@ func TestAuthTuneCommand_Run(t *testing.T) {
|
||||
"-listing-visibility", "unauth",
|
||||
"-plugin-version", version,
|
||||
"-identity-token-key", "default",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"my-auth/",
|
||||
})
|
||||
if exp := 0; code != exp {
|
||||
@ -156,6 +157,9 @@ func TestAuthTuneCommand_Run(t *testing.T) {
|
||||
if exp := 3600; mountInfo.Config.MaxLeaseTTL != exp {
|
||||
t.Errorf("expected %d to be %d", mountInfo.Config.MaxLeaseTTL, exp)
|
||||
}
|
||||
if !mountInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization", "www-authentication"}, mountInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values in PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
@ -97,6 +97,8 @@ const (
|
||||
flagNamePluginVersion = "plugin-version"
|
||||
// flagNameIdentityTokenKey selects the key used to sign plugin identity tokens
|
||||
flagNameIdentityTokenKey = "identity-token-key"
|
||||
// flagNameTrimRequestTrailingSlashes selects the key used to determine whether to trim trailing slashes
|
||||
flagNameTrimRequestTrailingSlashes = "trim-request-trailing-slashes"
|
||||
// flagNameUserLockoutThreshold is the flag name used for tuning the auth mount lockout threshold parameter
|
||||
flagNameUserLockoutThreshold = "user-lockout-threshold"
|
||||
// flagNameUserLockoutDuration is the flag name used for tuning the auth mount lockout duration parameter
|
||||
|
@ -23,26 +23,27 @@ var (
|
||||
type SecretsEnableCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagForceNoCache bool
|
||||
flagPluginName string
|
||||
flagPluginVersion string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagVersion int
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagDescription string
|
||||
flagPath string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagListingVisibility string
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagForceNoCache bool
|
||||
flagPluginName string
|
||||
flagPluginVersion string
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagExternalEntropyAccess bool
|
||||
flagVersion int
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *SecretsEnableCommand) Synopsis() string {
|
||||
@ -245,6 +246,12 @@ func (c *SecretsEnableCommand) Flags() *FlagSets {
|
||||
Usage: "Select the key used to sign plugin identity tokens.",
|
||||
})
|
||||
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@ -359,6 +366,11 @@ func (c *SecretsEnableCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
mountInput.Config.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
mountInput.Config.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
if err := client.Sys().Mount(mountPath, mountInput); err != nil {
|
||||
|
@ -120,6 +120,7 @@ func TestSecretsEnableCommand_Run(t *testing.T) {
|
||||
"-allowed-managed-keys", "key1,key2",
|
||||
"-identity-token-key", "default",
|
||||
"-delegated-auth-accessors", "authAcc1,authAcc2",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"-force-no-cache",
|
||||
"pki",
|
||||
})
|
||||
@ -157,6 +158,9 @@ func TestSecretsEnableCommand_Run(t *testing.T) {
|
||||
if exp := true; mountInfo.Config.ForceNoCache != exp {
|
||||
t.Errorf("expected %t to be %t", mountInfo.Config.ForceNoCache, exp)
|
||||
}
|
||||
if !mountInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization,authentication", "www-authentication"}, mountInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values in PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
@ -23,20 +23,21 @@ var (
|
||||
type SecretsTuneCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagDescription string
|
||||
flagListingVisibility string
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagAuditNonHMACRequestKeys []string
|
||||
flagAuditNonHMACResponseKeys []string
|
||||
flagDefaultLeaseTTL time.Duration
|
||||
flagDescription string
|
||||
flagListingVisibility string
|
||||
flagMaxLeaseTTL time.Duration
|
||||
flagPassthroughRequestHeaders []string
|
||||
flagAllowedResponseHeaders []string
|
||||
flagOptions map[string]string
|
||||
flagVersion int
|
||||
flagPluginVersion string
|
||||
flagAllowedManagedKeys []string
|
||||
flagDelegatedAuthAccessors []string
|
||||
flagIdentityTokenKey string
|
||||
flagTrimRequestTrailingSlashes BoolPtr
|
||||
}
|
||||
|
||||
func (c *SecretsTuneCommand) Synopsis() string {
|
||||
@ -175,6 +176,12 @@ func (c *SecretsTuneCommand) Flags() *FlagSets {
|
||||
Usage: "Select the key used to sign plugin identity tokens.",
|
||||
})
|
||||
|
||||
f.BoolPtrVar(&BoolPtrVar{
|
||||
Name: flagNameTrimRequestTrailingSlashes,
|
||||
Target: &c.flagTrimRequestTrailingSlashes,
|
||||
Usage: "Whether to trim trailing slashes for incoming requests to this mount",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@ -267,6 +274,10 @@ func (c *SecretsTuneCommand) Run(args []string) int {
|
||||
if fl.Name == flagNameIdentityTokenKey {
|
||||
mountConfigInput.IdentityTokenKey = c.flagIdentityTokenKey
|
||||
}
|
||||
if fl.Name == flagNameTrimRequestTrailingSlashes && c.flagTrimRequestTrailingSlashes.IsSet() {
|
||||
val := c.flagTrimRequestTrailingSlashes.Get()
|
||||
mountConfigInput.TrimRequestTrailingSlashes = &val
|
||||
}
|
||||
})
|
||||
|
||||
if err := client.Sys().TuneMount(mountPath, mountConfigInput); err != nil {
|
||||
|
@ -196,6 +196,7 @@ func TestSecretsTuneCommand_Run(t *testing.T) {
|
||||
"-listing-visibility", "unauth",
|
||||
"-plugin-version", version,
|
||||
"-delegated-auth-accessors", "authAcc1,authAcc2",
|
||||
"-trim-request-trailing-slashes=true",
|
||||
"mount_tune_integration/",
|
||||
})
|
||||
if exp := 0; code != exp {
|
||||
@ -232,6 +233,9 @@ func TestSecretsTuneCommand_Run(t *testing.T) {
|
||||
if exp := 3600; mountInfo.Config.MaxLeaseTTL != exp {
|
||||
t.Errorf("expected %d to be %d", mountInfo.Config.MaxLeaseTTL, exp)
|
||||
}
|
||||
if !mountInfo.Config.TrimRequestTrailingSlashes {
|
||||
t.Errorf("expected trim_request_trailing_slashes to be enabled")
|
||||
}
|
||||
if diff := deep.Equal([]string{"authorization", "www-authentication"}, mountInfo.Config.PassthroughRequestHeaders); len(diff) > 0 {
|
||||
t.Errorf("Failed to find expected values for PassthroughRequestHeaders. Difference is: %v", diff)
|
||||
}
|
||||
|
@ -1389,7 +1389,9 @@ func (b *SystemBackend) mountInfo(ctx context.Context, entry *MountEntry, legacy
|
||||
entryConfig["max_lease_ttl"] = coreMaxTTL
|
||||
}
|
||||
}
|
||||
|
||||
if entry.Config.TrimRequestTrailingSlashes {
|
||||
entryConfig["trim_request_trailing_slashes"] = true
|
||||
}
|
||||
if rawVal, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok {
|
||||
entryConfig["audit_non_hmac_request_keys"] = rawVal.([]string)
|
||||
}
|
||||
@ -1613,6 +1615,10 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d
|
||||
config.ForceNoCache = true
|
||||
}
|
||||
|
||||
if apiConfig.TrimRequestTrailingSlashes {
|
||||
config.TrimRequestTrailingSlashes = true
|
||||
}
|
||||
|
||||
if err := checkListingVisibility(apiConfig.ListingVisibility); err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf("invalid listing_visibility %s", apiConfig.ListingVisibility)), nil
|
||||
}
|
||||
@ -2149,6 +2155,10 @@ func (b *SystemBackend) handleTuneReadCommon(ctx context.Context, path string) (
|
||||
resp.Data["identity_token_key"] = rawVal.(string)
|
||||
}
|
||||
|
||||
if mountEntry.Config.TrimRequestTrailingSlashes {
|
||||
resp.Data["trim_request_trailing_slashes"] = mountEntry.Config.TrimRequestTrailingSlashes
|
||||
}
|
||||
|
||||
if mountEntry.Config.UserLockoutConfig != nil {
|
||||
resp.Data["user_lockout_counter_reset_duration"] = int64(mountEntry.Config.UserLockoutConfig.LockoutCounterReset.Seconds())
|
||||
resp.Data["user_lockout_threshold"] = mountEntry.Config.UserLockoutConfig.LockoutThreshold
|
||||
@ -2753,6 +2763,30 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
|
||||
}
|
||||
}
|
||||
|
||||
if rawVal, ok := data.GetOk("trim_request_trailing_slashes"); ok {
|
||||
trimRequestTrailingSlashes := rawVal.(bool)
|
||||
|
||||
oldVal := mountEntry.Config.TrimRequestTrailingSlashes
|
||||
mountEntry.Config.TrimRequestTrailingSlashes = trimRequestTrailingSlashes
|
||||
|
||||
// Update the mount table
|
||||
var err error
|
||||
switch {
|
||||
case strings.HasPrefix(path, "auth/"):
|
||||
err = b.Core.persistAuth(ctx, b.Core.auth, &mountEntry.Local)
|
||||
default:
|
||||
err = b.Core.persistMounts(ctx, b.Core.mounts, &mountEntry.Local)
|
||||
}
|
||||
if err != nil {
|
||||
mountEntry.Config.TrimRequestTrailingSlashes = oldVal
|
||||
return handleError(err)
|
||||
}
|
||||
|
||||
if b.Core.logger.IsInfo() {
|
||||
b.Core.logger.Info("mount tuning of trim_request_trailing_slashes successful", "path", path)
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
var resp *logical.Response
|
||||
var options map[string]string
|
||||
@ -3269,6 +3303,7 @@ func (b *SystemBackend) handleEnableAuth(ctx context.Context, req *logical.Reque
|
||||
return logical.ErrorResponse(fmt.Sprintf("invalid listing_visibility %s", apiConfig.ListingVisibility)), nil
|
||||
}
|
||||
config.ListingVisibility = apiConfig.ListingVisibility
|
||||
config.TrimRequestTrailingSlashes = apiConfig.TrimRequestTrailingSlashes
|
||||
|
||||
if len(apiConfig.AuditNonHMACRequestKeys) > 0 {
|
||||
config.AuditNonHMACRequestKeys = apiConfig.AuditNonHMACRequestKeys
|
||||
@ -7156,4 +7191,8 @@ This path responds to the following HTTP methods.
|
||||
`The label representing a path-prefix within the /.well-known/ path`,
|
||||
"",
|
||||
},
|
||||
"trim_request_trailing_slashes": {
|
||||
`Whether to trim a trailing slash on incoming requests to this mount`,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
@ -3826,6 +3826,10 @@ func (b *SystemBackend) authPaths() []*framework.Path {
|
||||
Description: strings.TrimSpace(sysHelp["identity_token_key"][0]),
|
||||
Required: false,
|
||||
},
|
||||
"trim_request_trailing_slashes": {
|
||||
Type: framework.TypeBool,
|
||||
Required: false,
|
||||
},
|
||||
},
|
||||
Operations: map[logical.Operation]framework.OperationHandler{
|
||||
logical.ReadOperation: &framework.PathOperation{
|
||||
@ -3916,6 +3920,10 @@ func (b *SystemBackend) authPaths() []*framework.Path {
|
||||
Type: framework.TypeString,
|
||||
Required: false,
|
||||
},
|
||||
"trim_request_trailing_slashes": {
|
||||
Type: framework.TypeBool,
|
||||
Required: false,
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
@ -4686,6 +4694,10 @@ func (b *SystemBackend) mountPaths() []*framework.Path {
|
||||
Type: framework.TypeString,
|
||||
Description: strings.TrimSpace(sysHelp["identity_token_key"][0]),
|
||||
},
|
||||
"trim_request_trailing_slashes": {
|
||||
Type: framework.TypeBool,
|
||||
Description: strings.TrimSpace(sysHelp["trim_request_trailing_slashes"][0]),
|
||||
},
|
||||
},
|
||||
|
||||
Operations: map[logical.Operation]framework.OperationHandler{
|
||||
@ -4788,6 +4800,10 @@ func (b *SystemBackend) mountPaths() []*framework.Path {
|
||||
Type: framework.TypeString,
|
||||
Required: false,
|
||||
},
|
||||
"trim_request_trailing_slashes": {
|
||||
Type: framework.TypeBool,
|
||||
Required: false,
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
|
@ -349,19 +349,20 @@ type MountEntry struct {
|
||||
|
||||
// MountConfig is used to hold settable options
|
||||
type MountConfig struct {
|
||||
DefaultLeaseTTL time.Duration `json:"default_lease_ttl,omitempty" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"` // Override for global default
|
||||
MaxLeaseTTL time.Duration `json:"max_lease_ttl,omitempty" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` // Override for global default
|
||||
ForceNoCache bool `json:"force_no_cache,omitempty" structs:"force_no_cache" mapstructure:"force_no_cache"` // Override for global default
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" structs:"audit_non_hmac_request_keys" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" structs:"audit_non_hmac_response_keys" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility ListingVisibilityType `json:"listing_visibility,omitempty" structs:"listing_visibility" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" structs:"passthrough_request_headers" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" structs:"allowed_response_headers" mapstructure:"allowed_response_headers"`
|
||||
TokenType logical.TokenType `json:"token_type,omitempty" structs:"token_type" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
UserLockoutConfig *UserLockoutConfig `json:"user_lockout_config,omitempty" mapstructure:"user_lockout_config"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
DefaultLeaseTTL time.Duration `json:"default_lease_ttl,omitempty" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"` // Override for global default
|
||||
MaxLeaseTTL time.Duration `json:"max_lease_ttl,omitempty" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` // Override for global default
|
||||
ForceNoCache bool `json:"force_no_cache,omitempty" structs:"force_no_cache" mapstructure:"force_no_cache"` // Override for global default
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" structs:"audit_non_hmac_request_keys" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" structs:"audit_non_hmac_response_keys" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility ListingVisibilityType `json:"listing_visibility,omitempty" structs:"listing_visibility" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" structs:"passthrough_request_headers" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" structs:"allowed_response_headers" mapstructure:"allowed_response_headers"`
|
||||
TokenType logical.TokenType `json:"token_type,omitempty" structs:"token_type" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
UserLockoutConfig *UserLockoutConfig `json:"user_lockout_config,omitempty" mapstructure:"user_lockout_config"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
TrimRequestTrailingSlashes bool `json:"trim_request_trailing_slashes,omitempty" mapstructure:"trim_request_trailing_slashes"` // If requests to this mount should have trailing slashes trimmed
|
||||
|
||||
// PluginName is the name of the plugin registered in the catalog.
|
||||
//
|
||||
@ -389,20 +390,21 @@ type APIUserLockoutConfig struct {
|
||||
|
||||
// APIMountConfig is an embedded struct of api.MountConfigInput
|
||||
type APIMountConfig struct {
|
||||
DefaultLeaseTTL string `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"`
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" structs:"audit_non_hmac_request_keys" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" structs:"audit_non_hmac_response_keys" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility ListingVisibilityType `json:"listing_visibility,omitempty" structs:"listing_visibility" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" structs:"passthrough_request_headers" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" structs:"allowed_response_headers" mapstructure:"allowed_response_headers"`
|
||||
TokenType string `json:"token_type" structs:"token_type" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
UserLockoutConfig *UserLockoutConfig `json:"user_lockout_config,omitempty" mapstructure:"user_lockout_config"`
|
||||
PluginVersion string `json:"plugin_version,omitempty" mapstructure:"plugin_version"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
DefaultLeaseTTL string `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"`
|
||||
AuditNonHMACRequestKeys []string `json:"audit_non_hmac_request_keys,omitempty" structs:"audit_non_hmac_request_keys" mapstructure:"audit_non_hmac_request_keys"`
|
||||
AuditNonHMACResponseKeys []string `json:"audit_non_hmac_response_keys,omitempty" structs:"audit_non_hmac_response_keys" mapstructure:"audit_non_hmac_response_keys"`
|
||||
ListingVisibility ListingVisibilityType `json:"listing_visibility,omitempty" structs:"listing_visibility" mapstructure:"listing_visibility"`
|
||||
PassthroughRequestHeaders []string `json:"passthrough_request_headers,omitempty" structs:"passthrough_request_headers" mapstructure:"passthrough_request_headers"`
|
||||
AllowedResponseHeaders []string `json:"allowed_response_headers,omitempty" structs:"allowed_response_headers" mapstructure:"allowed_response_headers"`
|
||||
TokenType string `json:"token_type" structs:"token_type" mapstructure:"token_type"`
|
||||
AllowedManagedKeys []string `json:"allowed_managed_keys,omitempty" mapstructure:"allowed_managed_keys"`
|
||||
UserLockoutConfig *UserLockoutConfig `json:"user_lockout_config,omitempty" mapstructure:"user_lockout_config"`
|
||||
PluginVersion string `json:"plugin_version,omitempty" mapstructure:"plugin_version"`
|
||||
DelegatedAuthAccessors []string `json:"delegated_auth_accessors,omitempty" mapstructure:"delegated_auth_accessors"`
|
||||
IdentityTokenKey string `json:"identity_token_key,omitempty" mapstructure:"identity_token_key"`
|
||||
TrimRequestTrailingSlashes bool `json:"trim_request_trailing_slashes,omitempty" mapstructure:"trim_request_trailing_slashes"` // If requests to this mount should have trailing slashes trimmed
|
||||
|
||||
// PluginName is the name of the plugin registered in the catalog.
|
||||
//
|
||||
|
@ -612,6 +612,25 @@ func (c *Core) switchedLockHandleRequest(httpCtx context.Context, req *logical.R
|
||||
}
|
||||
|
||||
func (c *Core) handleCancelableRequest(ctx context.Context, req *logical.Request) (resp *logical.Response, err error) {
|
||||
waitGroup, err := waitForReplicationState(ctx, c, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Decrement the wait group when our request is done
|
||||
if waitGroup != nil {
|
||||
defer waitGroup.Done()
|
||||
}
|
||||
|
||||
if c.MissingRequiredState(req.RequiredState(), c.perfStandby) {
|
||||
return nil, logical.ErrMissingRequiredState
|
||||
}
|
||||
|
||||
// Ensure the req contains a MountPoint as it is depended on by some
|
||||
// functionality (e.g. quotas)
|
||||
var entry *MountEntry
|
||||
req.MountPoint, entry = c.router.MatchingMountAndEntry(ctx, req.Path)
|
||||
|
||||
// Allowing writing to a path ending in / makes it extremely difficult to
|
||||
// understand user intent for the filesystem-like backends (kv,
|
||||
// cubbyhole) -- did they want a key named foo/ or did they want to write
|
||||
@ -622,24 +641,11 @@ func (c *Core) handleCancelableRequest(ctx context.Context, req *logical.Request
|
||||
(req.Operation == logical.UpdateOperation ||
|
||||
req.Operation == logical.CreateOperation ||
|
||||
req.Operation == logical.PatchOperation) {
|
||||
return logical.ErrorResponse("cannot write to a path ending in '/'"), nil
|
||||
}
|
||||
waitGroup, err := waitForReplicationState(ctx, c, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// MountPoint will not always be set at this point, so we ensure the req contains it
|
||||
// as it is depended on by some functionality (e.g. quotas)
|
||||
req.MountPoint = c.router.MatchingMount(ctx, req.Path)
|
||||
|
||||
// Decrement the wait group when our request is done
|
||||
if waitGroup != nil {
|
||||
defer waitGroup.Done()
|
||||
}
|
||||
|
||||
if c.MissingRequiredState(req.RequiredState(), c.perfStandby) {
|
||||
return nil, logical.ErrMissingRequiredState
|
||||
if entry == nil || !entry.Config.TrimRequestTrailingSlashes {
|
||||
return logical.ErrorResponse("cannot write to a path ending in '/'"), nil
|
||||
} else {
|
||||
req.Path = strings.TrimSuffix(req.Path, "/")
|
||||
}
|
||||
}
|
||||
|
||||
err = c.PopulateTokenEntry(ctx, req)
|
||||
@ -892,7 +898,6 @@ func (c *Core) handleCancelableRequest(ctx context.Context, req *logical.Request
|
||||
|
||||
var nonHMACReqDataKeys []string
|
||||
var nonHMACRespDataKeys []string
|
||||
entry := c.router.MatchingMountEntry(ctx, req.Path)
|
||||
if entry != nil {
|
||||
// Get and set ignored HMAC'd value. Reset those back to empty afterwards.
|
||||
if rawVals, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok {
|
||||
|
@ -373,23 +373,28 @@ func (r *Router) MatchingMountByAccessor(mountAccessor string) *MountEntry {
|
||||
// MatchingMount returns the mount prefix that would be used for a path
|
||||
func (r *Router) MatchingMount(ctx context.Context, path string) string {
|
||||
r.l.RLock()
|
||||
mount := r.matchingMountInternal(ctx, path)
|
||||
mount, _ := r.matchingMountInternal(ctx, path)
|
||||
r.l.RUnlock()
|
||||
return mount
|
||||
}
|
||||
|
||||
func (r *Router) matchingMountInternal(ctx context.Context, path string) string {
|
||||
// MatchingMountAndEntry returns the MountEntry used for a path and it's router path
|
||||
func (r *Router) MatchingMountAndEntry(ctx context.Context, path string) (string, *MountEntry) {
|
||||
return r.matchingMountInternal(ctx, path)
|
||||
}
|
||||
|
||||
func (r *Router) matchingMountInternal(ctx context.Context, path string) (string, *MountEntry) {
|
||||
ns, err := namespace.FromContext(ctx)
|
||||
if err != nil {
|
||||
return ""
|
||||
return "", nil
|
||||
}
|
||||
path = ns.Path + path
|
||||
|
||||
mount, _, ok := r.root.LongestPrefix(path)
|
||||
mount, raw, ok := r.root.LongestPrefix(path)
|
||||
if !ok {
|
||||
return ""
|
||||
return "", nil
|
||||
}
|
||||
return mount
|
||||
return mount, raw.(*routeEntry).mountEntry
|
||||
}
|
||||
|
||||
// matchingPrefixInternal returns a mount prefix that a path may be a part of
|
||||
@ -416,7 +421,7 @@ func (r *Router) matchingPrefixInternal(ctx context.Context, path string) string
|
||||
func (r *Router) MountConflict(ctx context.Context, path string) string {
|
||||
r.l.RLock()
|
||||
defer r.l.RUnlock()
|
||||
if exactMatch := r.matchingMountInternal(ctx, path); exactMatch != "" {
|
||||
if exactMatch, _ := r.matchingMountInternal(ctx, path); exactMatch != "" {
|
||||
return exactMatch
|
||||
}
|
||||
if prefixMatch := r.matchingPrefixInternal(ctx, path); prefixMatch != "" {
|
||||
|
@ -89,6 +89,10 @@ flags](/vault/docs/commands) included on all commands.
|
||||
- `-token-type` `(string: "")` - Specifies the type of tokens that should be
|
||||
returned by the auth method.
|
||||
|
||||
- `-trim-request-trailing-slashes` `(bool: false)` - If true, requests to
|
||||
this mount with trailing slashes will have those slashes trimmed.
|
||||
Necessary for some standards based APIs handled by Vault.
|
||||
|
||||
- `-plugin-version` `(string: "")` - Configures the semantic version of the plugin
|
||||
to use. If unspecified, implies the built-in or any matching unversioned plugin
|
||||
that may have been registered.
|
||||
|
@ -168,6 +168,10 @@ flags](/vault/docs/commands) included on all commands.
|
||||
- `-token-type` `(string: "")` - Specifies the type of tokens that should be
|
||||
returned by the auth method.
|
||||
|
||||
- `-trim-request-trailing-slashes` `(bool: false)` - If true, requests to
|
||||
this mount with trailing slashes will have those slashes trimmed.
|
||||
Necessary for some standards based APIs handled by Vault.
|
||||
|
||||
- `-plugin-version` `(string: "")` - Configures the semantic version of the plugin
|
||||
to use. The new version will not start running until the mount is
|
||||
[reloaded](/vault/docs/commands/plugin/reload).
|
||||
|
@ -111,6 +111,10 @@ flags](/vault/docs/commands) included on all commands.
|
||||
backend can delegate authentication to. To allow multiple accessors, provide
|
||||
the `delegated-auth-accessors` multiple times, each time with 1 accessor.
|
||||
|
||||
- `-trim-request-trailing-slashes` `(bool: false)` - If true, requests to
|
||||
this mount with trailing slashes will have those slashes trimmed.
|
||||
Necessary for some standards based APIs handled by Vault.
|
||||
|
||||
- `-plugin-version` `(string: "")` - Configures the semantic version of the plugin
|
||||
to use. If unspecified, implies the built-in or any matching unversioned plugin
|
||||
that may have been registered.
|
||||
|
@ -97,6 +97,10 @@ flags](/vault/docs/commands) included on all commands.
|
||||
backend can delegate authentication to. To allow multiple accessors, provide
|
||||
the `delegated-auth-accessors` multiple times, each time with 1 accessor.
|
||||
|
||||
- `-trim-request-trailing-slashes` `(bool: false)` - If true, requests to
|
||||
this mount with trailing slashes will have those slashes trimmed.
|
||||
Necessary for some standards based APIs handled by Vault.
|
||||
|
||||
- `-plugin-version` `(string: "")` - Configures the semantic version of the plugin
|
||||
to use. The new version will not start running until the mount is
|
||||
[reloaded](/vault/docs/commands/plugin/reload).
|
||||
|
@ -87,10 +87,10 @@ To get an authentication mount's accessor field, the following command can be us
|
||||
$ vault read -field=accessor sys/auth/auth/cert
|
||||
```
|
||||
|
||||
For CMP to work within certain clients, a few response headers need to be explicitly allowed
|
||||
along with configuring the list of accessors the mount can delegate authentication towards.
|
||||
The following will grant the required response headers, you will need to replace the values for the `delegated-auth-accessors`
|
||||
to match your values.
|
||||
For CMP to work within certain clients, a few response headers need to be explicitly
|
||||
allowed, trailing slashes must be trimmed, and the list of accessors the mount can delegate authentication towards
|
||||
must be configured. The following will grant the required response headers, you will need to replace the values for
|
||||
the `delegated-auth-accessors` to match your values.
|
||||
|
||||
```shell-session
|
||||
$ vault secrets tune \
|
||||
@ -98,6 +98,7 @@ $ vault secrets tune \
|
||||
-allowed-response-headers="Content-Length" \
|
||||
-allowed-response-headers="WWW-Authenticate" \
|
||||
-delegated-auth-accessors="auth_cert_4088ac2d" \
|
||||
-trim-request-trailing-slashes="true" \
|
||||
pki
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user