mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-03 20:17:59 +00:00 
			
		
		
		
	Add list of granting policies audit logs (#15457)
* Add list of granting policies audit logs * Add changelog
This commit is contained in:
		@@ -135,6 +135,20 @@ func (f *AuditFormatter) FormatRequest(ctx context.Context, w io.Writer, config
 | 
				
			|||||||
		reqEntry.Auth.TokenIssueTime = auth.IssueTime.Format(time.RFC3339)
 | 
							reqEntry.Auth.TokenIssueTime = auth.IssueTime.Format(time.RFC3339)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if auth.PolicyResults != nil {
 | 
				
			||||||
 | 
							reqEntry.Auth.PolicyResults = &AuditPolicyResults{
 | 
				
			||||||
 | 
								Allowed: auth.PolicyResults.Allowed,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, p := range auth.PolicyResults.GrantingPolicies {
 | 
				
			||||||
 | 
								reqEntry.Auth.PolicyResults.GrantingPolicies = append(reqEntry.Auth.PolicyResults.GrantingPolicies, PolicyInfo{
 | 
				
			||||||
 | 
									Name:        p.Name,
 | 
				
			||||||
 | 
									NamespaceId: p.NamespaceId,
 | 
				
			||||||
 | 
									Type:        p.Type,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if req.WrapInfo != nil {
 | 
						if req.WrapInfo != nil {
 | 
				
			||||||
		reqEntry.Request.WrapTTL = int(req.WrapInfo.TTL / time.Second)
 | 
							reqEntry.Request.WrapTTL = int(req.WrapInfo.TTL / time.Second)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -277,6 +291,7 @@ func (f *AuditFormatter) FormatResponse(ctx context.Context, w io.Writer, config
 | 
				
			|||||||
			ID:                  req.ID,
 | 
								ID:                  req.ID,
 | 
				
			||||||
			ClientToken:         req.ClientToken,
 | 
								ClientToken:         req.ClientToken,
 | 
				
			||||||
			ClientTokenAccessor: req.ClientTokenAccessor,
 | 
								ClientTokenAccessor: req.ClientTokenAccessor,
 | 
				
			||||||
 | 
								ClientID:            req.ClientID,
 | 
				
			||||||
			Operation:           req.Operation,
 | 
								Operation:           req.Operation,
 | 
				
			||||||
			MountType:           req.MountType,
 | 
								MountType:           req.MountType,
 | 
				
			||||||
			MountAccessor:       req.MountAccessor,
 | 
								MountAccessor:       req.MountAccessor,
 | 
				
			||||||
@@ -307,6 +322,20 @@ func (f *AuditFormatter) FormatResponse(ctx context.Context, w io.Writer, config
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if auth.PolicyResults != nil {
 | 
				
			||||||
 | 
							respEntry.Auth.PolicyResults = &AuditPolicyResults{
 | 
				
			||||||
 | 
								Allowed: auth.PolicyResults.Allowed,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, p := range auth.PolicyResults.GrantingPolicies {
 | 
				
			||||||
 | 
								respEntry.Auth.PolicyResults.GrantingPolicies = append(respEntry.Auth.PolicyResults.GrantingPolicies, PolicyInfo{
 | 
				
			||||||
 | 
									Name:        p.Name,
 | 
				
			||||||
 | 
									NamespaceId: p.NamespaceId,
 | 
				
			||||||
 | 
									Type:        p.Type,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !auth.IssueTime.IsZero() {
 | 
						if !auth.IssueTime.IsZero() {
 | 
				
			||||||
		respEntry.Auth.TokenIssueTime = auth.IssueTime.Format(time.RFC3339)
 | 
							respEntry.Auth.TokenIssueTime = auth.IssueTime.Format(time.RFC3339)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -381,6 +410,7 @@ type AuditAuth struct {
 | 
				
			|||||||
	IdentityPolicies          []string            `json:"identity_policies,omitempty"`
 | 
						IdentityPolicies          []string            `json:"identity_policies,omitempty"`
 | 
				
			||||||
	ExternalNamespacePolicies map[string][]string `json:"external_namespace_policies,omitempty"`
 | 
						ExternalNamespacePolicies map[string][]string `json:"external_namespace_policies,omitempty"`
 | 
				
			||||||
	NoDefaultPolicy           bool                `json:"no_default_policy,omitempty"`
 | 
						NoDefaultPolicy           bool                `json:"no_default_policy,omitempty"`
 | 
				
			||||||
 | 
						PolicyResults             *AuditPolicyResults `json:"policy_results,omitempty"`
 | 
				
			||||||
	Metadata                  map[string]string   `json:"metadata,omitempty"`
 | 
						Metadata                  map[string]string   `json:"metadata,omitempty"`
 | 
				
			||||||
	NumUses                   int                 `json:"num_uses,omitempty"`
 | 
						NumUses                   int                 `json:"num_uses,omitempty"`
 | 
				
			||||||
	RemainingUses             int                 `json:"remaining_uses,omitempty"`
 | 
						RemainingUses             int                 `json:"remaining_uses,omitempty"`
 | 
				
			||||||
@@ -390,6 +420,17 @@ type AuditAuth struct {
 | 
				
			|||||||
	TokenIssueTime            string              `json:"token_issue_time,omitempty"`
 | 
						TokenIssueTime            string              `json:"token_issue_time,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AuditPolicyResults struct {
 | 
				
			||||||
 | 
						Allowed          bool         `json:"allowed"`
 | 
				
			||||||
 | 
						GrantingPolicies []PolicyInfo `json:"granting_policies,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PolicyInfo struct {
 | 
				
			||||||
 | 
						Name        string `json:"name,omitempty"`
 | 
				
			||||||
 | 
						NamespaceId string `json:"namespace_id,omitempty"`
 | 
				
			||||||
 | 
						Type        string `json:"type"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AuditSecret struct {
 | 
					type AuditSecret struct {
 | 
				
			||||||
	LeaseID string `json:"lease_id,omitempty"`
 | 
						LeaseID string `json:"lease_id,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								changelog/15457.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								changelog/15457.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					```release-note:improvement
 | 
				
			||||||
 | 
					audit: Add a policy_results block into the audit log that contains the set of
 | 
				
			||||||
 | 
					policies that granted this request access.
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
@@ -8,7 +8,8 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Auth is the resulting authentication information that is part of
 | 
					// Auth is the resulting authentication information that is part of
 | 
				
			||||||
// Response for credential backends.
 | 
					// Response for credential backends. It's also attached to Request objects and
 | 
				
			||||||
 | 
					// defines the authentication used for the request. This value is audit logged.
 | 
				
			||||||
type Auth struct {
 | 
					type Auth struct {
 | 
				
			||||||
	LeaseOptions
 | 
						LeaseOptions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -101,6 +102,10 @@ type Auth struct {
 | 
				
			|||||||
	// Orphan is set if the token does not have a parent
 | 
						// Orphan is set if the token does not have a parent
 | 
				
			||||||
	Orphan bool `json:"orphan"`
 | 
						Orphan bool `json:"orphan"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// PolicyResults is the set of policies that grant the token access to the
 | 
				
			||||||
 | 
						// requesting path.
 | 
				
			||||||
 | 
						PolicyResults *PolicyResults `json:"policy_results"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// MFARequirement
 | 
						// MFARequirement
 | 
				
			||||||
	MFARequirement *MFARequirement `json:"mfa_requirement"`
 | 
						MFARequirement *MFARequirement `json:"mfa_requirement"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -108,3 +113,14 @@ type Auth struct {
 | 
				
			|||||||
func (a *Auth) GoString() string {
 | 
					func (a *Auth) GoString() string {
 | 
				
			||||||
	return fmt.Sprintf("*%#v", *a)
 | 
						return fmt.Sprintf("*%#v", *a)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PolicyResults struct {
 | 
				
			||||||
 | 
						Allowed          bool         `json:"allowed"`
 | 
				
			||||||
 | 
						GrantingPolicies []PolicyInfo `json:"granting_policies"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PolicyInfo struct {
 | 
				
			||||||
 | 
						Name        string `json:"name"`
 | 
				
			||||||
 | 
						NamespaceId string `json:"namespace_id"`
 | 
				
			||||||
 | 
						Type        string `json:"type"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								vault/acl.go
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								vault/acl.go
									
									
									
									
									
								
							@@ -40,11 +40,12 @@ type PolicyCheckOpts struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AuthResults struct {
 | 
					type AuthResults struct {
 | 
				
			||||||
	ACLResults  *ACLResults
 | 
						ACLResults      *ACLResults
 | 
				
			||||||
	Allowed     bool
 | 
						SentinelResults *SentinelResults
 | 
				
			||||||
	RootPrivs   bool
 | 
						Allowed         bool
 | 
				
			||||||
	DeniedError bool
 | 
						RootPrivs       bool
 | 
				
			||||||
	Error       *multierror.Error
 | 
						DeniedError     bool
 | 
				
			||||||
 | 
						Error           *multierror.Error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ACLResults struct {
 | 
					type ACLResults struct {
 | 
				
			||||||
@@ -54,6 +55,11 @@ type ACLResults struct {
 | 
				
			|||||||
	MFAMethods         []string
 | 
						MFAMethods         []string
 | 
				
			||||||
	ControlGroup       *ControlGroup
 | 
						ControlGroup       *ControlGroup
 | 
				
			||||||
	CapabilitiesBitmap uint32
 | 
						CapabilitiesBitmap uint32
 | 
				
			||||||
 | 
						GrantingPolicies   []logical.PolicyInfo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SentinelResults struct {
 | 
				
			||||||
 | 
						GrantingPolicies []logical.PolicyInfo
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewACL is used to construct a policy based ACL from a set of policies.
 | 
					// NewACL is used to construct a policy based ACL from a set of policies.
 | 
				
			||||||
@@ -126,6 +132,10 @@ func NewACL(ctx context.Context, policies []*Policy) (*ACL, error) {
 | 
				
			|||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, fmt.Errorf("error cloning ACL permissions: %w", err)
 | 
										return nil, fmt.Errorf("error cloning ACL permissions: %w", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Store this policy name as the policy that permits these
 | 
				
			||||||
 | 
									// capabilities
 | 
				
			||||||
 | 
									clonedPerms.GrantingPoliciesMap = addGrantingPoliciesToMap(nil, policy, clonedPerms.CapabilitiesBitmap)
 | 
				
			||||||
				switch {
 | 
									switch {
 | 
				
			||||||
				case pc.HasSegmentWildcards:
 | 
									case pc.HasSegmentWildcards:
 | 
				
			||||||
					a.segmentWildcardPaths[pc.Path] = clonedPerms
 | 
										a.segmentWildcardPaths[pc.Path] = clonedPerms
 | 
				
			||||||
@@ -155,6 +165,7 @@ func NewACL(ctx context.Context, policies []*Policy) (*ACL, error) {
 | 
				
			|||||||
				// Insert the capabilities in this new policy into the existing
 | 
									// Insert the capabilities in this new policy into the existing
 | 
				
			||||||
				// value
 | 
									// value
 | 
				
			||||||
				existingPerms.CapabilitiesBitmap = existingPerms.CapabilitiesBitmap | pc.Permissions.CapabilitiesBitmap
 | 
									existingPerms.CapabilitiesBitmap = existingPerms.CapabilitiesBitmap | pc.Permissions.CapabilitiesBitmap
 | 
				
			||||||
 | 
									existingPerms.GrantingPoliciesMap = addGrantingPoliciesToMap(existingPerms.GrantingPoliciesMap, policy, pc.Permissions.CapabilitiesBitmap)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Note: In these stanzas, we're preferring minimum lifetimes. So
 | 
								// Note: In these stanzas, we're preferring minimum lifetimes. So
 | 
				
			||||||
@@ -326,6 +337,11 @@ func (a *ACL) AllowOperation(ctx context.Context, req *logical.Request, capCheck
 | 
				
			|||||||
		ret.Allowed = true
 | 
							ret.Allowed = true
 | 
				
			||||||
		ret.RootPrivs = true
 | 
							ret.RootPrivs = true
 | 
				
			||||||
		ret.IsRoot = true
 | 
							ret.IsRoot = true
 | 
				
			||||||
 | 
							ret.GrantingPolicies = []logical.PolicyInfo{{
 | 
				
			||||||
 | 
								Name:        "root",
 | 
				
			||||||
 | 
								NamespaceId: "root",
 | 
				
			||||||
 | 
								Type:        "acl",
 | 
				
			||||||
 | 
							}}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	op := req.Operation
 | 
						op := req.Operation
 | 
				
			||||||
@@ -397,25 +413,33 @@ CHECK:
 | 
				
			|||||||
	ret.MFAMethods = permissions.MFAMethods
 | 
						ret.MFAMethods = permissions.MFAMethods
 | 
				
			||||||
	ret.ControlGroup = permissions.ControlGroup
 | 
						ret.ControlGroup = permissions.ControlGroup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var grantingPolicies []logical.PolicyInfo
 | 
				
			||||||
	operationAllowed := false
 | 
						operationAllowed := false
 | 
				
			||||||
	switch op {
 | 
						switch op {
 | 
				
			||||||
	case logical.ReadOperation:
 | 
						case logical.ReadOperation:
 | 
				
			||||||
		operationAllowed = capabilities&ReadCapabilityInt > 0
 | 
							operationAllowed = capabilities&ReadCapabilityInt > 0
 | 
				
			||||||
 | 
							grantingPolicies = permissions.GrantingPoliciesMap[ReadCapabilityInt]
 | 
				
			||||||
	case logical.ListOperation:
 | 
						case logical.ListOperation:
 | 
				
			||||||
		operationAllowed = capabilities&ListCapabilityInt > 0
 | 
							operationAllowed = capabilities&ListCapabilityInt > 0
 | 
				
			||||||
 | 
							grantingPolicies = permissions.GrantingPoliciesMap[ListCapabilityInt]
 | 
				
			||||||
	case logical.UpdateOperation:
 | 
						case logical.UpdateOperation:
 | 
				
			||||||
		operationAllowed = capabilities&UpdateCapabilityInt > 0
 | 
							operationAllowed = capabilities&UpdateCapabilityInt > 0
 | 
				
			||||||
 | 
							grantingPolicies = permissions.GrantingPoliciesMap[UpdateCapabilityInt]
 | 
				
			||||||
	case logical.DeleteOperation:
 | 
						case logical.DeleteOperation:
 | 
				
			||||||
		operationAllowed = capabilities&DeleteCapabilityInt > 0
 | 
							operationAllowed = capabilities&DeleteCapabilityInt > 0
 | 
				
			||||||
 | 
							grantingPolicies = permissions.GrantingPoliciesMap[DeleteCapabilityInt]
 | 
				
			||||||
	case logical.CreateOperation:
 | 
						case logical.CreateOperation:
 | 
				
			||||||
		operationAllowed = capabilities&CreateCapabilityInt > 0
 | 
							operationAllowed = capabilities&CreateCapabilityInt > 0
 | 
				
			||||||
 | 
							grantingPolicies = permissions.GrantingPoliciesMap[CreateCapabilityInt]
 | 
				
			||||||
	case logical.PatchOperation:
 | 
						case logical.PatchOperation:
 | 
				
			||||||
		operationAllowed = capabilities&PatchCapabilityInt > 0
 | 
							operationAllowed = capabilities&PatchCapabilityInt > 0
 | 
				
			||||||
 | 
							grantingPolicies = permissions.GrantingPoliciesMap[PatchCapabilityInt]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// These three re-use UpdateCapabilityInt since that's the most appropriate
 | 
						// These three re-use UpdateCapabilityInt since that's the most appropriate
 | 
				
			||||||
	// capability/operation mapping
 | 
						// capability/operation mapping
 | 
				
			||||||
	case logical.RevokeOperation, logical.RenewOperation, logical.RollbackOperation:
 | 
						case logical.RevokeOperation, logical.RenewOperation, logical.RollbackOperation:
 | 
				
			||||||
		operationAllowed = capabilities&UpdateCapabilityInt > 0
 | 
							operationAllowed = capabilities&UpdateCapabilityInt > 0
 | 
				
			||||||
 | 
							grantingPolicies = permissions.GrantingPoliciesMap[UpdateCapabilityInt]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -425,6 +449,8 @@ CHECK:
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret.GrantingPolicies = grantingPolicies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if permissions.MaxWrappingTTL > 0 {
 | 
						if permissions.MaxWrappingTTL > 0 {
 | 
				
			||||||
		if req.WrapInfo == nil || req.WrapInfo.TTL > permissions.MaxWrappingTTL {
 | 
							if req.WrapInfo == nil || req.WrapInfo.TTL > permissions.MaxWrappingTTL {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -841,6 +841,127 @@ func TestACL_CreationRace(t *testing.T) {
 | 
				
			|||||||
	wg.Wait()
 | 
						wg.Wait()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestACLGrantingPolicies(t *testing.T) {
 | 
				
			||||||
 | 
						ns := namespace.RootNamespace
 | 
				
			||||||
 | 
						policy, err := ParseACLPolicy(ns, grantingTestPolicy)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("err: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						merged, err := ParseACLPolicy(ns, grantingTestPolicyMerged)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("err: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx := namespace.ContextWithNamespace(context.Background(), ns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						type tcase struct {
 | 
				
			||||||
 | 
							path     string
 | 
				
			||||||
 | 
							op       logical.Operation
 | 
				
			||||||
 | 
							policies []*Policy
 | 
				
			||||||
 | 
							expected []logical.PolicyInfo
 | 
				
			||||||
 | 
							allowed  bool
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						policyInfo := logical.PolicyInfo{
 | 
				
			||||||
 | 
							Name:        "granting_policy",
 | 
				
			||||||
 | 
							NamespaceId: "root",
 | 
				
			||||||
 | 
							Type:        "acl",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mergedInfo := logical.PolicyInfo{
 | 
				
			||||||
 | 
							Name:        "granting_policy_merged",
 | 
				
			||||||
 | 
							NamespaceId: "root",
 | 
				
			||||||
 | 
							Type:        "acl",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tcases := []tcase{
 | 
				
			||||||
 | 
							{"kv/foo", logical.ReadOperation, []*Policy{policy}, []logical.PolicyInfo{policyInfo}, true},
 | 
				
			||||||
 | 
							{"kv/foo", logical.UpdateOperation, []*Policy{policy}, []logical.PolicyInfo{policyInfo}, true},
 | 
				
			||||||
 | 
							{"kv/bad", logical.ReadOperation, []*Policy{policy}, nil, false},
 | 
				
			||||||
 | 
							{"kv/deny", logical.ReadOperation, []*Policy{policy}, nil, false},
 | 
				
			||||||
 | 
							{"kv/path/foo", logical.ReadOperation, []*Policy{policy}, []logical.PolicyInfo{policyInfo}, true},
 | 
				
			||||||
 | 
							{"kv/path/longer", logical.ReadOperation, []*Policy{policy}, []logical.PolicyInfo{policyInfo}, true},
 | 
				
			||||||
 | 
							{"kv/foo", logical.ReadOperation, []*Policy{policy, merged}, []logical.PolicyInfo{policyInfo, mergedInfo}, true},
 | 
				
			||||||
 | 
							{"kv/path/longer3", logical.ReadOperation, []*Policy{policy, merged}, []logical.PolicyInfo{mergedInfo}, true},
 | 
				
			||||||
 | 
							{"kv/bar", logical.ReadOperation, []*Policy{policy, merged}, []logical.PolicyInfo{mergedInfo}, true},
 | 
				
			||||||
 | 
							{"kv/deny", logical.ReadOperation, []*Policy{policy, merged}, nil, false},
 | 
				
			||||||
 | 
							{"kv/path/longer", logical.UpdateOperation, []*Policy{policy, merged}, []logical.PolicyInfo{policyInfo}, true},
 | 
				
			||||||
 | 
							{"kv/path/foo", logical.ReadOperation, []*Policy{policy, merged}, []logical.PolicyInfo{policyInfo, mergedInfo}, true},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tc := range tcases {
 | 
				
			||||||
 | 
							request := &logical.Request{
 | 
				
			||||||
 | 
								Path:      tc.path,
 | 
				
			||||||
 | 
								Operation: tc.op,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							acl, err := NewACL(ctx, tc.policies)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatalf("err: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							authResults := acl.AllowOperation(ctx, request, false)
 | 
				
			||||||
 | 
							if authResults.Allowed != tc.allowed {
 | 
				
			||||||
 | 
								t.Fatalf("bad: case %#v: %v", tc, authResults.Allowed)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !reflect.DeepEqual(authResults.GrantingPolicies, tc.expected) {
 | 
				
			||||||
 | 
								t.Fatalf("bad: case %#v: got\n%#v\nexpected\n%#v\n", tc, authResults.GrantingPolicies, tc.expected)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var grantingTestPolicy = `
 | 
				
			||||||
 | 
					name = "granting_policy"
 | 
				
			||||||
 | 
					path "kv/foo" {
 | 
				
			||||||
 | 
						capabilities = ["update", "read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/path/*" {
 | 
				
			||||||
 | 
						capabilities = ["read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/path/longer" {
 | 
				
			||||||
 | 
						capabilities = ["update", "read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/path/longer2" {
 | 
				
			||||||
 | 
						capabilities = ["update"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/deny" {
 | 
				
			||||||
 | 
						capabilities = ["deny"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "ns1/kv/foo" {
 | 
				
			||||||
 | 
						capabilities = ["update", "read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var grantingTestPolicyMerged = `
 | 
				
			||||||
 | 
					name = "granting_policy_merged"
 | 
				
			||||||
 | 
					path "kv/foo" {
 | 
				
			||||||
 | 
						capabilities = ["update", "read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/bar" {
 | 
				
			||||||
 | 
						capabilities = ["update", "read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/path/*" {
 | 
				
			||||||
 | 
						capabilities = ["read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/path/longer" {
 | 
				
			||||||
 | 
						capabilities = ["read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/path/longer3" {
 | 
				
			||||||
 | 
						capabilities = ["read"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path "kv/deny" {
 | 
				
			||||||
 | 
						capabilities = ["update"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var tokenCreationPolicy = `
 | 
					var tokenCreationPolicy = `
 | 
				
			||||||
name = "tokenCreation"
 | 
					name = "tokenCreation"
 | 
				
			||||||
path "auth/token/create*" {
 | 
					path "auth/token/create*" {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ import (
 | 
				
			|||||||
	"github.com/hashicorp/vault/helper/namespace"
 | 
						"github.com/hashicorp/vault/helper/namespace"
 | 
				
			||||||
	"github.com/hashicorp/vault/sdk/helper/hclutil"
 | 
						"github.com/hashicorp/vault/sdk/helper/hclutil"
 | 
				
			||||||
	"github.com/hashicorp/vault/sdk/helper/identitytpl"
 | 
						"github.com/hashicorp/vault/sdk/helper/identitytpl"
 | 
				
			||||||
 | 
						"github.com/hashicorp/vault/sdk/logical"
 | 
				
			||||||
	"github.com/mitchellh/copystructure"
 | 
						"github.com/mitchellh/copystructure"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -161,14 +162,15 @@ type IdentityFactor struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ACLPermissions struct {
 | 
					type ACLPermissions struct {
 | 
				
			||||||
	CapabilitiesBitmap uint32
 | 
						CapabilitiesBitmap  uint32
 | 
				
			||||||
	MinWrappingTTL     time.Duration
 | 
						MinWrappingTTL      time.Duration
 | 
				
			||||||
	MaxWrappingTTL     time.Duration
 | 
						MaxWrappingTTL      time.Duration
 | 
				
			||||||
	AllowedParameters  map[string][]interface{}
 | 
						AllowedParameters   map[string][]interface{}
 | 
				
			||||||
	DeniedParameters   map[string][]interface{}
 | 
						DeniedParameters    map[string][]interface{}
 | 
				
			||||||
	RequiredParameters []string
 | 
						RequiredParameters  []string
 | 
				
			||||||
	MFAMethods         []string
 | 
						MFAMethods          []string
 | 
				
			||||||
	ControlGroup       *ControlGroup
 | 
						ControlGroup        *ControlGroup
 | 
				
			||||||
 | 
						GrantingPoliciesMap map[uint32][]logical.PolicyInfo
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *ACLPermissions) Clone() (*ACLPermissions, error) {
 | 
					func (p *ACLPermissions) Clone() (*ACLPermissions, error) {
 | 
				
			||||||
@@ -225,9 +227,43 @@ func (p *ACLPermissions) Clone() (*ACLPermissions, error) {
 | 
				
			|||||||
		ret.ControlGroup = clonedControlGroup.(*ControlGroup)
 | 
							ret.ControlGroup = clonedControlGroup.(*ControlGroup)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch {
 | 
				
			||||||
 | 
						case p.GrantingPoliciesMap == nil:
 | 
				
			||||||
 | 
						case len(p.GrantingPoliciesMap) == 0:
 | 
				
			||||||
 | 
							ret.GrantingPoliciesMap = make(map[uint32][]logical.PolicyInfo)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							clonedGrantingPoliciesMap, err := copystructure.Copy(p.GrantingPoliciesMap)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ret.GrantingPoliciesMap = clonedGrantingPoliciesMap.(map[uint32][]logical.PolicyInfo)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret, nil
 | 
						return ret, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func addGrantingPoliciesToMap(m map[uint32][]logical.PolicyInfo, policy *Policy, capabilitiesBitmap uint32) map[uint32][]logical.PolicyInfo {
 | 
				
			||||||
 | 
						if m == nil {
 | 
				
			||||||
 | 
							m = make(map[uint32][]logical.PolicyInfo)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// For all possible policies, check if the provided capabilities include
 | 
				
			||||||
 | 
						// them
 | 
				
			||||||
 | 
						for _, capability := range cap2Int {
 | 
				
			||||||
 | 
							if capabilitiesBitmap&capability == 0 {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m[capability] = append(m[capability], logical.PolicyInfo{
 | 
				
			||||||
 | 
								Name:        policy.Name,
 | 
				
			||||||
 | 
								NamespaceId: policy.namespace.ID,
 | 
				
			||||||
 | 
								Type:        "acl",
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return m
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ParseACLPolicy is used to parse the specified ACL rules into an
 | 
					// ParseACLPolicy is used to parse the specified ACL rules into an
 | 
				
			||||||
// intermediary set of policies, before being compiled into
 | 
					// intermediary set of policies, before being compiled into
 | 
				
			||||||
// the ACL
 | 
					// the ACL
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -385,6 +385,10 @@ func (c *Core) checkToken(ctx context.Context, req *logical.Request, unauth bool
 | 
				
			|||||||
		RootPrivsRequired: rootPath,
 | 
							RootPrivsRequired: rootPath,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auth.PolicyResults = &logical.PolicyResults{
 | 
				
			||||||
 | 
							Allowed: authResults.Allowed,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !authResults.Allowed {
 | 
						if !authResults.Allowed {
 | 
				
			||||||
		retErr := authResults.Error
 | 
							retErr := authResults.Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -410,6 +414,13 @@ func (c *Core) checkToken(ctx context.Context, req *logical.Request, unauth bool
 | 
				
			|||||||
		return auth, te, retErr
 | 
							return auth, te, retErr
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if authResults.ACLResults != nil && len(authResults.ACLResults.GrantingPolicies) > 0 {
 | 
				
			||||||
 | 
							auth.PolicyResults.GrantingPolicies = authResults.ACLResults.GrantingPolicies
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if authResults.SentinelResults != nil && len(authResults.SentinelResults.GrantingPolicies) > 0 {
 | 
				
			||||||
 | 
							auth.PolicyResults.GrantingPolicies = append(auth.PolicyResults.GrantingPolicies, authResults.SentinelResults.GrantingPolicies...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If it is an authenticated ( i.e with vault token ) request, increment client count
 | 
						// If it is an authenticated ( i.e with vault token ) request, increment client count
 | 
				
			||||||
	if !unauth && c.activityLog != nil {
 | 
						if !unauth && c.activityLog != nil {
 | 
				
			||||||
		c.activityLog.HandleTokenUsage(ctx, te, clientID, isTWE)
 | 
							c.activityLog.HandleTokenUsage(ctx, te, clientID, isTWE)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user