mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-06 14:47:01 +02:00
* VAULT-28577: change CSV MIME type to text/csv * VAULT-28578: require sudo for export API * add validation and associated error handling * change export API default to 204 if no data returned * VAULT-28579: allow export API in non-root namespace, add filtering support * update test fixtures to reflect filtering changes * TestActivityLog_Export moved to ENT-only test * add test to verify sudo access * add changelog entry
89 lines
5.5 KiB
Go
89 lines
5.5 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package api
|
|
|
|
import (
|
|
"regexp"
|
|
)
|
|
|
|
// sudoPaths is a map containing the paths that require a token's policy
|
|
// to have the "sudo" capability. The keys are the paths as strings, in
|
|
// the same format as they are returned by the OpenAPI spec. The values
|
|
// are the regular expressions that can be used to test whether a given
|
|
// path matches that path or not (useful specifically for the paths that
|
|
// contain templated fields.)
|
|
var sudoPaths = map[string]*regexp.Regexp{
|
|
"/auth/token/accessors": regexp.MustCompile(`^/auth/token/accessors/?$`),
|
|
"/auth/token/revoke-orphan": regexp.MustCompile(`^/auth/token/revoke-orphan$`),
|
|
"/pki/root": regexp.MustCompile(`^/pki/root$`),
|
|
"/pki/root/sign-self-issued": regexp.MustCompile(`^/pki/root/sign-self-issued$`),
|
|
"/sys/audit": regexp.MustCompile(`^/sys/audit$`),
|
|
"/sys/audit/{path}": regexp.MustCompile(`^/sys/audit/.+$`),
|
|
"/sys/auth/{path}": regexp.MustCompile(`^/sys/auth/.+$`),
|
|
"/sys/auth/{path}/tune": regexp.MustCompile(`^/sys/auth/.+/tune$`),
|
|
"/sys/config/auditing/request-headers": regexp.MustCompile(`^/sys/config/auditing/request-headers$`),
|
|
"/sys/config/auditing/request-headers/{header}": regexp.MustCompile(`^/sys/config/auditing/request-headers/.+$`),
|
|
"/sys/config/cors": regexp.MustCompile(`^/sys/config/cors$`),
|
|
"/sys/config/ui/headers": regexp.MustCompile(`^/sys/config/ui/headers/?$`),
|
|
"/sys/config/ui/headers/{header}": regexp.MustCompile(`^/sys/config/ui/headers/.+$`),
|
|
"/sys/internal/inspect/router/{tag}": regexp.MustCompile(`^/sys/internal/inspect/router/.+$`),
|
|
"/sys/internal/counters/activity/export": regexp.MustCompile(`^/sys/internal/counters/activity/export$`),
|
|
"/sys/leases": regexp.MustCompile(`^/sys/leases$`),
|
|
// This entry is a bit wrong... sys/leases/lookup does NOT require sudo. But sys/leases/lookup/ with a trailing
|
|
// slash DOES require sudo. But the part of the Vault CLI that uses this logic doesn't pass operation-appropriate
|
|
// trailing slashes, it always strips them off, so we end up giving the wrong answer for one of these.
|
|
"/sys/leases/lookup/{prefix}": regexp.MustCompile(`^/sys/leases/lookup(?:/.+)?$`),
|
|
"/sys/leases/revoke-force/{prefix}": regexp.MustCompile(`^/sys/leases/revoke-force/.+$`),
|
|
"/sys/leases/revoke-prefix/{prefix}": regexp.MustCompile(`^/sys/leases/revoke-prefix/.+$`),
|
|
"/sys/plugins/catalog/{name}": regexp.MustCompile(`^/sys/plugins/catalog/[^/]+$`),
|
|
"/sys/plugins/catalog/{type}": regexp.MustCompile(`^/sys/plugins/catalog/[\w-]+$`),
|
|
"/sys/plugins/catalog/{type}/{name}": regexp.MustCompile(`^/sys/plugins/catalog/[\w-]+/[^/]+$`),
|
|
"/sys/plugins/runtimes/catalog": regexp.MustCompile(`^/sys/plugins/runtimes/catalog/?$`),
|
|
"/sys/plugins/runtimes/catalog/{type}/{name}": regexp.MustCompile(`^/sys/plugins/runtimes/catalog/[\w-]+/[^/]+$`),
|
|
"/sys/raw/{path}": regexp.MustCompile(`^/sys/raw(?:/.+)?$`),
|
|
"/sys/remount": regexp.MustCompile(`^/sys/remount$`),
|
|
"/sys/revoke-force/{prefix}": regexp.MustCompile(`^/sys/revoke-force/.+$`),
|
|
"/sys/revoke-prefix/{prefix}": regexp.MustCompile(`^/sys/revoke-prefix/.+$`),
|
|
"/sys/rotate": regexp.MustCompile(`^/sys/rotate$`),
|
|
"/sys/seal": regexp.MustCompile(`^/sys/seal$`),
|
|
"/sys/step-down": regexp.MustCompile(`^/sys/step-down$`),
|
|
|
|
// enterprise-only paths
|
|
"/sys/replication/dr/primary/secondary-token": regexp.MustCompile(`^/sys/replication/dr/primary/secondary-token$`),
|
|
"/sys/replication/performance/primary/secondary-token": regexp.MustCompile(`^/sys/replication/performance/primary/secondary-token$`),
|
|
"/sys/replication/primary/secondary-token": regexp.MustCompile(`^/sys/replication/primary/secondary-token$`),
|
|
"/sys/replication/reindex": regexp.MustCompile(`^/sys/replication/reindex$`),
|
|
"/sys/storage/raft/snapshot-auto/config": regexp.MustCompile(`^/sys/storage/raft/snapshot-auto/config/?$`),
|
|
"/sys/storage/raft/snapshot-auto/config/{name}": regexp.MustCompile(`^/sys/storage/raft/snapshot-auto/config/[^/]+$`),
|
|
}
|
|
|
|
func SudoPaths() map[string]*regexp.Regexp {
|
|
return sudoPaths
|
|
}
|
|
|
|
// Determine whether the given path requires the sudo capability.
|
|
// Note that this uses hardcoded static path information, so will return incorrect results for paths in namespaces,
|
|
// or for secret engines mounted at non-default paths.
|
|
// Expects to receive a path with an initial slash, but no trailing slashes, as the Vault CLI (the only known and
|
|
// expected user of this function) sanitizes its paths that way.
|
|
func IsSudoPath(path string) bool {
|
|
// Return early if the path is any of the non-templated sudo paths.
|
|
if _, ok := sudoPaths[path]; ok {
|
|
return true
|
|
}
|
|
|
|
// Some sudo paths have templated fields in them.
|
|
// (e.g. /sys/revoke-prefix/{prefix})
|
|
// The values in the sudoPaths map are actually regular expressions,
|
|
// so we can check if our path matches against them.
|
|
for _, sudoPathRegexp := range sudoPaths {
|
|
match := sudoPathRegexp.MatchString(path)
|
|
if match {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|