Audit: move validation of audit related options for Enterprise/CE to audit package (#26575)

* move option validation for enterprise options to audit package from vault package

* remove commented lines

* remove blank line
This commit is contained in:
Peter Wilson
2024-04-22 16:39:52 +01:00
committed by GitHub
parent 2becdceab0
commit 1d67c3f3b4
5 changed files with 113 additions and 120 deletions

View File

@@ -307,9 +307,9 @@ func (b *backend) Invalidate(_ context.Context) {
b.salt.Store((*salt.Salt)(nil))
}
// HasInvalidAuditOptions is used to determine if a non-Enterprise version of Vault
// HasInvalidOptions is used to determine if a non-Enterprise version of Vault
// is being used when supplying options that contain options exclusive to Enterprise.
func HasInvalidAuditOptions(options map[string]string) bool {
func HasInvalidOptions(options map[string]string) bool {
return !constants.IsEnterprise && hasEnterpriseAuditOptions(options)
}

View File

@@ -10,7 +10,7 @@ import "fmt"
// validate ensures that this if we're not running Vault Enterprise, we cannot
// supply Enterprise-only audit configuration options.
func (c *BackendConfig) validate() error {
if HasInvalidAuditOptions(c.Config) {
if HasInvalidOptions(c.Config) {
return fmt.Errorf("enterprise-only options supplied: %w", ErrExternalOptions)
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/hashicorp/eventlogger"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/helper/constants"
"github.com/stretchr/testify/require"
)
@@ -144,3 +145,110 @@ func TestBackend_configureFormatterNode(t *testing.T) {
node := b.nodeMap[id]
require.Equal(t, eventlogger.NodeTypeFormatter, node.Type())
}
// TestBackend_hasEnterpriseAuditOptions checks that the existence of any Enterprise
// only options in the options which can be supplied to enable an audit device can
// be flagged.
func TestBackend_hasEnterpriseAuditOptions(t *testing.T) {
t.Parallel()
tests := map[string]struct {
input map[string]string
expected bool
}{
"nil": {
expected: false,
},
"empty": {
input: make(map[string]string),
expected: false,
},
"non-ent-opts": {
input: map[string]string{
"log_raw": "true",
},
expected: false,
},
"ent-opt-filter": {
input: map[string]string{
"filter": "mount_type == kv",
},
expected: true,
},
"ent-opt-fallback": {
input: map[string]string{
"fallback": "true",
},
expected: true,
},
"ent-opt-filter-and-fallback": {
input: map[string]string{
"filter": "mount_type == kv",
"fallback": "true",
},
expected: true,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
require.Equal(t, tc.expected, hasEnterpriseAuditOptions(tc.input))
})
}
}
// TestBackend_hasInvalidAuditOptions tests that depending on whether we are running
// an Enterprise or non-Enterprise version of Vault, the options supplied to enable
// an audit device may or may not be valid.
// NOTE: In the non-Enterprise version of Vault supplying audit options such as
// 'filter' or 'fallback' is not allowed.
func TestBackend_hasInvalidAuditOptions(t *testing.T) {
tests := map[string]struct {
input map[string]string
expected bool
}{
"non-ent-opts": {
input: map[string]string{
"log_raw": "true",
},
expected: false,
},
"ent-opt": {
input: map[string]string{
"filter": "mount_type == kv",
},
expected: !constants.IsEnterprise,
},
"ent-opt-filter": {
input: map[string]string{
"filter": "mount_type == kv",
},
expected: !constants.IsEnterprise,
},
"ent-opt-fallback": {
input: map[string]string{
"fallback": "true",
},
expected: !constants.IsEnterprise,
},
"ent-opt-filter-and-fallback": {
input: map[string]string{
"filter": "mount_type == kv",
"fallback": "true",
},
expected: !constants.IsEnterprise,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
require.Equal(t, tc.expected, HasInvalidOptions(tc.input))
})
}
}

View File

@@ -15,7 +15,6 @@ import (
"github.com/hashicorp/go-secure-stdlib/parseutil"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/helper/constants"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/jsonutil"
@@ -71,7 +70,7 @@ func (c *Core) enableAudit(ctx context.Context, entry *MountEntry, updateStorage
}
// We can check early to ensure that non-Enterprise versions aren't trying to supply Enterprise only options.
if hasInvalidAuditOptions(entry.Options) {
if audit.HasInvalidOptions(entry.Options) {
return fmt.Errorf("enterprise-only options supplied: %w", audit.ErrExternalOptions)
}
@@ -517,7 +516,7 @@ func (c *Core) removeAuditReloadFunc(entry *MountEntry) {
// newAuditBackend is used to create and configure a new audit backend by name
func (c *Core) newAuditBackend(entry *MountEntry, view logical.Storage, conf map[string]string) (audit.Backend, error) {
// Ensure that non-Enterprise versions aren't trying to supply Enterprise only options.
if hasInvalidAuditOptions(entry.Options) {
if audit.HasInvalidOptions(entry.Options) {
return nil, fmt.Errorf("enterprise-only options supplied: %w", audit.ErrInvalidParameter)
}
@@ -629,29 +628,3 @@ func (g genericAuditor) AuditResponse(ctx context.Context, input *logical.LogInp
logInput.Type = g.mountType + "-response"
return g.c.auditBroker.LogResponse(ctx, &logInput)
}
// hasInvalidAuditOptions is used to determine if a non-Enterprise version of Vault
// is being used when supplying options that contain options exclusive to Enterprise.
func hasInvalidAuditOptions(options map[string]string) bool {
return !constants.IsEnterprise && hasEnterpriseAuditOptions(options)
}
// hasValidEnterpriseAuditOptions is used to check if any of the options supplied
// are only for use in the Enterprise version of Vault.
func hasEnterpriseAuditOptions(options map[string]string) bool {
const enterpriseAuditOptionFilter = "filter"
const enterpriseAuditOptionFallback = "fallback"
enterpriseAuditOptions := []string{
enterpriseAuditOptionFallback,
enterpriseAuditOptionFilter,
}
for _, o := range enterpriseAuditOptions {
if _, ok := options[o]; ok {
return true
}
}
return false
}

View File

@@ -614,94 +614,6 @@ func TestAuditBroker_AuditHeaders(t *testing.T) {
}
}
// TestAudit_hasEnterpriseAuditOptions checks that the existence of any Enterprise
// only options in the options which can be supplied to enable an audit device can
// be flagged.
func TestAudit_hasEnterpriseAuditOptions(t *testing.T) {
t.Parallel()
tests := map[string]struct {
input map[string]string
expected bool
}{
"nil": {
expected: false,
},
"empty": {
input: make(map[string]string),
expected: false,
},
"non-ent-opts": {
input: map[string]string{
"log_raw": "true",
},
expected: false,
},
"ent-opt-filter": {
input: map[string]string{
"filter": "mount_type == kv",
},
expected: true,
},
"ent-opt-fallback": {
input: map[string]string{
"fallback": "true",
},
expected: true,
},
"ent-opt-filter-and-fallback": {
input: map[string]string{
"filter": "mount_type == kv",
"fallback": "true",
},
expected: true,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
require.Equal(t, tc.expected, hasEnterpriseAuditOptions(tc.input))
})
}
}
// TestAudit_hasInvalidAuditOptions tests that depending on whether we are running
// an Enterprise or non-Enterprise version of Vault, the options supplied to enable
// an audit device may or may not be valid.
// NOTE: In the non-Enterprise version of Vault supplying audit options such as
// 'filter' or 'fallback' is not allowed.
func TestAudit_hasInvalidAuditOptions(t *testing.T) {
tests := map[string]struct {
input map[string]string
expected bool
}{
"non-ent-opts": {
input: map[string]string{
"log_raw": "true",
},
expected: false,
},
"ent-opt": {
input: map[string]string{
"filter": "mount_type == kv",
},
expected: !constants.IsEnterprise,
},
}
for name, tc := range tests {
name := name
tc := tc
t.Run(name, func(t *testing.T) {
t.Parallel()
require.Equal(t, tc.expected, hasInvalidAuditOptions(tc.input))
})
}
}
// TestAudit_enableAudit ensures that we do not enable an audit device with Enterprise
// only options on a non-Enterprise version of Vault.
func TestAudit_enableAudit(t *testing.T) {