feat: add plugin metadata to audit logging (#19814)
This commit is contained in:
parent
e26aa0aff2
commit
fcf06d5874
|
@ -119,6 +119,10 @@ func (f *AuditFormatter) FormatRequest(ctx context.Context, w io.Writer, config
|
|||
Operation: req.Operation,
|
||||
MountType: req.MountType,
|
||||
MountAccessor: req.MountAccessor,
|
||||
MountRunningVersion: req.MountRunningVersion(),
|
||||
MountRunningSha256: req.MountRunningSha256(),
|
||||
MountIsExternalPlugin: req.MountIsExternalPlugin(),
|
||||
MountClass: req.MountClass(),
|
||||
Namespace: &AuditNamespace{
|
||||
ID: ns.ID,
|
||||
Path: ns.Path,
|
||||
|
@ -318,6 +322,10 @@ func (f *AuditFormatter) FormatResponse(ctx context.Context, w io.Writer, config
|
|||
Operation: req.Operation,
|
||||
MountType: req.MountType,
|
||||
MountAccessor: req.MountAccessor,
|
||||
MountRunningVersion: req.MountRunningVersion(),
|
||||
MountRunningSha256: req.MountRunningSha256(),
|
||||
MountIsExternalPlugin: req.MountIsExternalPlugin(),
|
||||
MountClass: req.MountClass(),
|
||||
Namespace: &AuditNamespace{
|
||||
ID: ns.ID,
|
||||
Path: ns.Path,
|
||||
|
@ -335,6 +343,10 @@ func (f *AuditFormatter) FormatResponse(ctx context.Context, w io.Writer, config
|
|||
Response: &AuditResponse{
|
||||
MountType: req.MountType,
|
||||
MountAccessor: req.MountAccessor,
|
||||
MountRunningVersion: req.MountRunningVersion(),
|
||||
MountRunningSha256: req.MountRunningSha256(),
|
||||
MountIsExternalPlugin: req.MountIsExternalPlugin(),
|
||||
MountClass: req.MountClass(),
|
||||
Auth: respAuth,
|
||||
Secret: respSecret,
|
||||
Data: respData,
|
||||
|
@ -399,6 +411,10 @@ type AuditRequest struct {
|
|||
Operation logical.Operation `json:"operation,omitempty"`
|
||||
MountType string `json:"mount_type,omitempty"`
|
||||
MountAccessor string `json:"mount_accessor,omitempty"`
|
||||
MountRunningVersion string `json:"mount_running_version,omitempty"`
|
||||
MountRunningSha256 string `json:"mount_running_sha256,omitempty"`
|
||||
MountClass string `json:"mount_class,omitempty"`
|
||||
MountIsExternalPlugin bool `json:"mount_is_external_plugin,omitempty"`
|
||||
ClientToken string `json:"client_token,omitempty"`
|
||||
ClientTokenAccessor string `json:"client_token_accessor,omitempty"`
|
||||
Namespace *AuditNamespace `json:"namespace,omitempty"`
|
||||
|
@ -416,6 +432,10 @@ type AuditResponse struct {
|
|||
Auth *AuditAuth `json:"auth,omitempty"`
|
||||
MountType string `json:"mount_type,omitempty"`
|
||||
MountAccessor string `json:"mount_accessor,omitempty"`
|
||||
MountRunningVersion string `json:"mount_running_plugin_version,omitempty"`
|
||||
MountRunningSha256 string `json:"mount_running_sha256,omitempty"`
|
||||
MountClass string `json:"mount_class,omitempty"`
|
||||
MountIsExternalPlugin bool `json:"mount_is_external_plugin,omitempty"`
|
||||
Secret *AuditSecret `json:"secret,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:feature
|
||||
audit: add plugin metadata, including plugin name, type, version, sha256, and whether plugin is external, to audit logging
|
||||
```
|
|
@ -11,6 +11,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -760,3 +761,180 @@ func TestLogical_ErrRelativePath(t *testing.T) {
|
|||
t.Errorf("expected response for write to include %q", logical.ErrRelativePath.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func testBuiltinPluginMetadataAuditLog(t *testing.T, log map[string]interface{}, expectedMountClass string) {
|
||||
if mountClass, ok := log["mount_class"].(string); !ok {
|
||||
t.Fatalf("mount_class should be a string, not %T", log["mount_class"])
|
||||
} else if mountClass != expectedMountClass {
|
||||
t.Fatalf("bad: mount_class should be %s, not %s", expectedMountClass, mountClass)
|
||||
}
|
||||
|
||||
if _, ok := log["mount_running_version"].(string); !ok {
|
||||
t.Fatalf("mount_running_version should be a string, not %T", log["mount_running_version"])
|
||||
}
|
||||
|
||||
if _, ok := log["mount_running_sha256"].(string); ok {
|
||||
t.Fatalf("mount_running_sha256 should be nil, not %T", log["mount_running_sha256"])
|
||||
}
|
||||
|
||||
if mountIsExternalPlugin, ok := log["mount_is_external_plugin"].(bool); ok && mountIsExternalPlugin {
|
||||
t.Fatalf("mount_is_external_plugin should be nil or false, not %T", log["mount_is_external_plugin"])
|
||||
}
|
||||
}
|
||||
|
||||
// TestLogical_AuditEnabled_ShouldLogPluginMetadata_Auth tests that we have plugin metadata of a builtin auth plugin
|
||||
// in audit log when it is enabled
|
||||
func TestLogical_AuditEnabled_ShouldLogPluginMetadata_Auth(t *testing.T) {
|
||||
coreConfig := &vault.CoreConfig{
|
||||
AuditBackends: map[string]audit.Factory{
|
||||
"file": auditFile.Factory,
|
||||
},
|
||||
}
|
||||
|
||||
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
||||
HandlerFunc: Handler,
|
||||
})
|
||||
|
||||
cluster.Start()
|
||||
defer cluster.Cleanup()
|
||||
|
||||
cores := cluster.Cores
|
||||
|
||||
core := cores[0].Core
|
||||
c := cluster.Cores[0].Client
|
||||
vault.TestWaitActive(t, core)
|
||||
|
||||
// Enable the audit backend
|
||||
tempDir := t.TempDir()
|
||||
auditLogFile, err := os.CreateTemp(tempDir, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = c.Sys().EnableAuditWithOptions("file", &api.EnableAuditOptions{
|
||||
Type: "file",
|
||||
Options: map[string]string{
|
||||
"file_path": auditLogFile.Name(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = c.Logical().Write("auth/token/create", map[string]interface{}{
|
||||
"ttl": "10s",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check the audit trail on request and response
|
||||
decoder := json.NewDecoder(auditLogFile)
|
||||
var auditRecord map[string]interface{}
|
||||
for decoder.Decode(&auditRecord) == nil {
|
||||
auditRequest := map[string]interface{}{}
|
||||
if req, ok := auditRecord["request"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditRequest["path"] != "auth/token/create" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testBuiltinPluginMetadataAuditLog(t, auditRequest, consts.PluginTypeCredential.String())
|
||||
|
||||
auditResponse := map[string]interface{}{}
|
||||
if req, ok := auditRecord["response"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditResponse["path"] != "auth/token/create" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testBuiltinPluginMetadataAuditLog(t, auditResponse, consts.PluginTypeCredential.String())
|
||||
}
|
||||
}
|
||||
|
||||
// TestLogical_AuditEnabled_ShouldLogPluginMetadata_Secret tests that we have plugin metadata of a builtin secret plugin
|
||||
// in audit log when it is enabled
|
||||
func TestLogical_AuditEnabled_ShouldLogPluginMetadata_Secret(t *testing.T) {
|
||||
coreConfig := &vault.CoreConfig{
|
||||
LogicalBackends: map[string]logical.Factory{
|
||||
"kv": kv.VersionedKVFactory,
|
||||
},
|
||||
AuditBackends: map[string]audit.Factory{
|
||||
"file": auditFile.Factory,
|
||||
},
|
||||
}
|
||||
|
||||
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
||||
HandlerFunc: Handler,
|
||||
})
|
||||
|
||||
cluster.Start()
|
||||
defer cluster.Cleanup()
|
||||
|
||||
cores := cluster.Cores
|
||||
|
||||
core := cores[0].Core
|
||||
c := cluster.Cores[0].Client
|
||||
vault.TestWaitActive(t, core)
|
||||
|
||||
if err := c.Sys().Mount("kv/", &api.MountInput{
|
||||
Type: "kv-v2",
|
||||
}); err != nil {
|
||||
t.Fatalf("kv-v2 mount attempt failed - err: %#v\n", err)
|
||||
}
|
||||
|
||||
// Enable the audit backend
|
||||
tempDir := t.TempDir()
|
||||
auditLogFile, err := os.CreateTemp(tempDir, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = c.Sys().EnableAuditWithOptions("file", &api.EnableAuditOptions{
|
||||
Type: "file",
|
||||
Options: map[string]string{
|
||||
"file_path": auditLogFile.Name(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
{
|
||||
writeData := map[string]interface{}{
|
||||
"data": map[string]interface{}{
|
||||
"bar": "a",
|
||||
},
|
||||
}
|
||||
corehelpers.RetryUntil(t, 10*time.Second, func() error {
|
||||
resp, err := c.Logical().Write("kv/data/foo", writeData)
|
||||
if err != nil {
|
||||
t.Fatalf("write request failed, err: %#v, resp: %#v\n", err, resp)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// Check the audit trail on request and response
|
||||
decoder := json.NewDecoder(auditLogFile)
|
||||
var auditRecord map[string]interface{}
|
||||
for decoder.Decode(&auditRecord) == nil {
|
||||
auditRequest := map[string]interface{}{}
|
||||
if req, ok := auditRecord["request"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditRequest["path"] != "kv/data/foo" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testBuiltinPluginMetadataAuditLog(t, auditRequest, consts.PluginTypeSecrets.String())
|
||||
|
||||
auditResponse := map[string]interface{}{}
|
||||
if req, ok := auditRecord["response"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditResponse["path"] != "kv/data/foo" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testBuiltinPluginMetadataAuditLog(t, auditResponse, consts.PluginTypeSecrets.String())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,22 @@ type Request struct {
|
|||
// backends can be tied to the mount it belongs to.
|
||||
MountAccessor string `json:"mount_accessor" structs:"mount_accessor" mapstructure:"mount_accessor" sentinel:""`
|
||||
|
||||
// mountRunningVersion is used internally to propagate the semantic version
|
||||
// of the mounted plugin as reported by its vault.MountEntry to audit logging
|
||||
mountRunningVersion string
|
||||
|
||||
// mountRunningSha256 is used internally to propagate the encoded sha256
|
||||
// of the mounted plugin as reported its vault.MountEntry to audit logging
|
||||
mountRunningSha256 string
|
||||
|
||||
// mountIsExternalPlugin is used internally to propagate whether
|
||||
// the backend of the mounted plugin is running externally (i.e., over GRPC)
|
||||
// to audit logging
|
||||
mountIsExternalPlugin bool
|
||||
|
||||
// mountClass is used internally to propagate the mount class of the mounted plugin to audit logging
|
||||
mountClass string
|
||||
|
||||
// WrapInfo contains requested response wrapping parameters
|
||||
WrapInfo *RequestWrapInfo `json:"wrap_info" structs:"wrap_info" mapstructure:"wrap_info" sentinel:""`
|
||||
|
||||
|
@ -283,6 +299,38 @@ func (r *Request) SentinelKeys() []string {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Request) MountRunningVersion() string {
|
||||
return r.mountRunningVersion
|
||||
}
|
||||
|
||||
func (r *Request) SetMountRunningVersion(mountRunningVersion string) {
|
||||
r.mountRunningVersion = mountRunningVersion
|
||||
}
|
||||
|
||||
func (r *Request) MountRunningSha256() string {
|
||||
return r.mountRunningSha256
|
||||
}
|
||||
|
||||
func (r *Request) SetMountRunningSha256(mountRunningSha256 string) {
|
||||
r.mountRunningSha256 = mountRunningSha256
|
||||
}
|
||||
|
||||
func (r *Request) MountIsExternalPlugin() bool {
|
||||
return r.mountIsExternalPlugin
|
||||
}
|
||||
|
||||
func (r *Request) SetMountIsExternalPlugin(mountIsExternalPlugin bool) {
|
||||
r.mountIsExternalPlugin = mountIsExternalPlugin
|
||||
}
|
||||
|
||||
func (r *Request) MountClass() string {
|
||||
return r.mountClass
|
||||
}
|
||||
|
||||
func (r *Request) SetMountClass(mountClass string) {
|
||||
r.mountClass = mountClass
|
||||
}
|
||||
|
||||
func (r *Request) LastRemoteWAL() uint64 {
|
||||
return r.lastRemoteWAL
|
||||
}
|
||||
|
|
|
@ -5,12 +5,16 @@ package plugin_test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/audit"
|
||||
auditFile "github.com/hashicorp/vault/builtin/audit/file"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/api/auth/approle"
|
||||
"github.com/hashicorp/vault/builtin/logical/database"
|
||||
|
@ -27,6 +31,35 @@ import (
|
|||
_ "github.com/jackc/pgx/v4/stdlib"
|
||||
)
|
||||
|
||||
func getClusterWithFileAuditBackend(t *testing.T, typ consts.PluginType, numCores int) *vault.TestCluster {
|
||||
pluginDir, cleanup := corehelpers.MakeTestPluginDir(t)
|
||||
t.Cleanup(func() { cleanup(t) })
|
||||
coreConfig := &vault.CoreConfig{
|
||||
PluginDirectory: pluginDir,
|
||||
LogicalBackends: map[string]logical.Factory{
|
||||
"database": database.Factory,
|
||||
},
|
||||
AuditBackends: map[string]audit.Factory{
|
||||
"file": auditFile.Factory,
|
||||
},
|
||||
}
|
||||
|
||||
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
||||
TempDir: pluginDir,
|
||||
NumCores: numCores,
|
||||
Plugins: &vault.TestPluginConfig{
|
||||
Typ: typ,
|
||||
Versions: []string{""},
|
||||
},
|
||||
HandlerFunc: vaulthttp.Handler,
|
||||
})
|
||||
|
||||
cluster.Start()
|
||||
vault.TestWaitActive(t, cluster.Cores[0].Core)
|
||||
|
||||
return cluster
|
||||
}
|
||||
|
||||
func getCluster(t *testing.T, typ consts.PluginType, numCores int) *vault.TestCluster {
|
||||
pluginDir, cleanup := corehelpers.MakeTestPluginDir(t)
|
||||
t.Cleanup(func() { cleanup(t) })
|
||||
|
@ -826,3 +859,164 @@ CREATE ROLE "{{name}}" WITH
|
|||
VALID UNTIL '{{expiration}}';
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "{{name}}";
|
||||
`
|
||||
|
||||
func testExternalPluginMetadataAuditLog(t *testing.T, log map[string]interface{}, expectedMountClass string) {
|
||||
if mountClass, ok := log["mount_class"].(string); !ok {
|
||||
t.Fatalf("mount_class should be a string, not %T", log["mount_class"])
|
||||
} else if mountClass != expectedMountClass {
|
||||
t.Fatalf("bad: mount_class should be %s, not %s", expectedMountClass, mountClass)
|
||||
}
|
||||
|
||||
if mountIsExternalPlugin, ok := log["mount_is_external_plugin"].(bool); !ok {
|
||||
t.Fatalf("mount_is_external_plugin should be a bool, not %T", log["mount_is_external_plugin"])
|
||||
} else if !mountIsExternalPlugin {
|
||||
t.Fatalf("bad: mount_is_external_plugin should be true, not %t", mountIsExternalPlugin)
|
||||
}
|
||||
|
||||
if _, ok := log["mount_running_sha256"].(string); !ok {
|
||||
t.Fatalf("mount_running_sha256 should be a string, not %T", log["mount_running_sha256"])
|
||||
}
|
||||
}
|
||||
|
||||
// TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Auth tests that we have plugin metadata of an auth plugin
|
||||
// in audit log when it is enabled
|
||||
func TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Auth(t *testing.T) {
|
||||
cluster := getClusterWithFileAuditBackend(t, consts.PluginTypeCredential, 1)
|
||||
defer cluster.Cleanup()
|
||||
|
||||
plugin := cluster.Plugins[0]
|
||||
client := cluster.Cores[0].Client
|
||||
client.SetToken(cluster.RootToken)
|
||||
|
||||
testRegisterAndEnable(t, client, plugin)
|
||||
|
||||
// Enable the audit backend
|
||||
tempDir := t.TempDir()
|
||||
auditLogFile, err := os.CreateTemp(tempDir, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = client.Sys().EnableAuditWithOptions("file", &api.EnableAuditOptions{
|
||||
Type: "file",
|
||||
Options: map[string]string{
|
||||
"file_path": auditLogFile.Name(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = client.Logical().Write("auth/"+plugin.Name+"/role/role1", map[string]interface{}{
|
||||
"bind_secret_id": "true",
|
||||
"period": "300",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check the audit trail on request and response
|
||||
decoder := json.NewDecoder(auditLogFile)
|
||||
var auditRecord map[string]interface{}
|
||||
for decoder.Decode(&auditRecord) == nil {
|
||||
auditRequest := map[string]interface{}{}
|
||||
if req, ok := auditRecord["request"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditRequest["path"] != "auth/"+plugin.Name+"/role/role1" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testExternalPluginMetadataAuditLog(t, auditRequest, consts.PluginTypeCredential.String())
|
||||
|
||||
auditResponse := map[string]interface{}{}
|
||||
if req, ok := auditRecord["response"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditResponse["path"] != "auth/"+plugin.Name+"/role/role1" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testExternalPluginMetadataAuditLog(t, auditResponse, consts.PluginTypeCredential.String())
|
||||
}
|
||||
|
||||
// Deregister
|
||||
if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{
|
||||
Name: plugin.Name,
|
||||
Type: api.PluginType(plugin.Typ),
|
||||
Version: plugin.Version,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Secret tests that we have plugin metadata of a secret plugin
|
||||
// in audit log when it is enabled
|
||||
func TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Secret(t *testing.T) {
|
||||
cluster := getClusterWithFileAuditBackend(t, consts.PluginTypeSecrets, 1)
|
||||
defer cluster.Cleanup()
|
||||
|
||||
plugin := cluster.Plugins[0]
|
||||
client := cluster.Cores[0].Client
|
||||
client.SetToken(cluster.RootToken)
|
||||
|
||||
testRegisterAndEnable(t, client, plugin)
|
||||
|
||||
// Enable the audit backend
|
||||
tempDir := t.TempDir()
|
||||
auditLogFile, err := os.CreateTemp(tempDir, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = client.Sys().EnableAuditWithOptions("file", &api.EnableAuditOptions{
|
||||
Type: "file",
|
||||
Options: map[string]string{
|
||||
"file_path": auditLogFile.Name(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Configure
|
||||
cleanupConsul, consulConfig := consul.PrepareTestContainer(t, "", false, true)
|
||||
defer cleanupConsul()
|
||||
_, err = client.Logical().Write(plugin.Name+"/config/access", map[string]interface{}{
|
||||
"address": consulConfig.Address(),
|
||||
"token": consulConfig.Token,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check the audit trail on request and response
|
||||
decoder := json.NewDecoder(auditLogFile)
|
||||
var auditRecord map[string]interface{}
|
||||
for decoder.Decode(&auditRecord) == nil {
|
||||
auditRequest := map[string]interface{}{}
|
||||
if req, ok := auditRecord["request"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditRequest["path"] != plugin.Name+"/config/access" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testExternalPluginMetadataAuditLog(t, auditRequest, consts.PluginTypeSecrets.String())
|
||||
|
||||
auditResponse := map[string]interface{}{}
|
||||
if req, ok := auditRecord["response"]; ok {
|
||||
auditRequest = req.(map[string]interface{})
|
||||
if auditResponse["path"] != plugin.Name+"/config/access" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
testExternalPluginMetadataAuditLog(t, auditResponse, consts.PluginTypeSecrets.String())
|
||||
}
|
||||
|
||||
// Deregister
|
||||
if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{
|
||||
Name: plugin.Name,
|
||||
Type: api.PluginType(plugin.Typ),
|
||||
Version: plugin.Version,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,6 +422,25 @@ func (e *MountEntry) Clone() (*MountEntry, error) {
|
|||
return cp.(*MountEntry), nil
|
||||
}
|
||||
|
||||
// IsExternalPlugin returns whether the plugin is running externally
|
||||
// if the RunningSha256 is non-empty, the builtin is external. Otherwise, it's builtin
|
||||
func (e *MountEntry) IsExternalPlugin() bool {
|
||||
return e.RunningSha256 != ""
|
||||
}
|
||||
|
||||
// MountClass returns the mount class based on Accessor and Path
|
||||
func (e *MountEntry) MountClass() string {
|
||||
if e.Accessor == "" || strings.HasPrefix(e.Path, fmt.Sprintf("%s/", systemMountPath)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if e.Table == credentialTableType {
|
||||
return consts.PluginTypeCredential.String()
|
||||
}
|
||||
|
||||
return consts.PluginTypeSecrets.String()
|
||||
}
|
||||
|
||||
// Namespace returns the namespace for the mount entry
|
||||
func (e *MountEntry) Namespace() *namespace.Namespace {
|
||||
return e.namespace
|
||||
|
|
|
@ -850,6 +850,11 @@ func (c *Core) handleRequest(ctx context.Context, req *logical.Request) (retResp
|
|||
if entry != nil {
|
||||
// Set here so the audit log has it even if authorization fails
|
||||
req.MountType = entry.Type
|
||||
req.SetMountRunningSha256(entry.RunningSha256)
|
||||
req.SetMountRunningVersion(entry.RunningVersion)
|
||||
req.SetMountIsExternalPlugin(entry.IsExternalPlugin())
|
||||
req.SetMountClass(entry.MountClass())
|
||||
|
||||
// Get and set ignored HMAC'd value.
|
||||
if rawVals, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok {
|
||||
nonHMACReqDataKeys = rawVals.([]string)
|
||||
|
@ -1270,6 +1275,11 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re
|
|||
if entry != nil {
|
||||
// Set here so the audit log has it even if authorization fails
|
||||
req.MountType = entry.Type
|
||||
req.SetMountRunningSha256(entry.RunningSha256)
|
||||
req.SetMountRunningVersion(entry.RunningVersion)
|
||||
req.SetMountIsExternalPlugin(entry.IsExternalPlugin())
|
||||
req.SetMountClass(entry.MountClass())
|
||||
|
||||
// Get and set ignored HMAC'd value.
|
||||
if rawVals, ok := entry.synthesizedConfigCache.Load("audit_non_hmac_request_keys"); ok {
|
||||
nonHMACReqDataKeys = rawVals.([]string)
|
||||
|
|
|
@ -618,6 +618,11 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
|||
req.Path = strings.TrimPrefix(ns.Path+req.Path, mount)
|
||||
req.MountPoint = mount
|
||||
req.MountType = re.mountEntry.Type
|
||||
req.SetMountRunningSha256(re.mountEntry.RunningSha256)
|
||||
req.SetMountRunningVersion(re.mountEntry.RunningVersion)
|
||||
req.SetMountIsExternalPlugin(re.mountEntry.IsExternalPlugin())
|
||||
req.SetMountClass(re.mountEntry.MountClass())
|
||||
|
||||
if req.Path == "/" {
|
||||
req.Path = ""
|
||||
}
|
||||
|
@ -733,6 +738,11 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc
|
|||
req.Path = originalPath
|
||||
req.MountPoint = mount
|
||||
req.MountType = re.mountEntry.Type
|
||||
req.SetMountRunningSha256(re.mountEntry.RunningSha256)
|
||||
req.SetMountRunningVersion(re.mountEntry.RunningVersion)
|
||||
req.SetMountIsExternalPlugin(re.mountEntry.IsExternalPlugin())
|
||||
req.SetMountClass(re.mountEntry.MountClass())
|
||||
|
||||
req.Connection = originalConn
|
||||
req.ID = originalReqID
|
||||
req.Storage = nil
|
||||
|
|
Loading…
Reference in New Issue