MCPcopy Create free account
hub / github.com/rilldata/rill / expandTransitiveAccessRules

Method expandTransitiveAccessRules

runtime/security.go:728–813  ·  view source on GitHub ↗

expandTransitiveAccessRules expands any transitive access rules in the provided list of rules. This involves looking up the referenced resource, determining its dependencies, and adding the necessary access rules for those dependencies. For example, a transitive access rule on a report will add acce

(ctx context.Context, instanceID string, claims *SecurityClaims)

Source from the content-addressed store, hash-verified

726// This involves looking up the referenced resource, determining its dependencies, and adding the necessary access rules for those dependencies.
727// For example, a transitive access rule on a report will add access rules for the underlying metrics view, explore, and any fields or rows that are accessible in the report.
728func (p *securityEngine) expandTransitiveAccessRules(ctx context.Context, instanceID string, claims *SecurityClaims) ([]*runtimev1.SecurityRule, error) {
729 hasTransitive := false
730 transitiveCount := 0
731 var rules []*runtimev1.SecurityRule
732 for _, rule := range claims.AdditionalRules {
733 if rule.GetTransitiveAccess() == nil {
734 rules = append(rules, rule)
735 continue
736 }
737 hasTransitive = true
738 // If the rule is a transitive access rule, we need to resolve it
739 resName := rule.GetTransitiveAccess().GetResource()
740 if resName == nil {
741 return nil, fmt.Errorf("transitive access rule has no resource")
742 }
743 ctr, err := p.rt.Controller(ctx, instanceID)
744 if err != nil {
745 return nil, fmt.Errorf("failed to get controller: %w", err)
746 }
747 res, err := ctr.Get(ctx, resName, false)
748 if err != nil {
749 if errors.Is(err, drivers.ErrResourceNotFound) {
750 // resource not found, skip transitive access
751 continue
752 }
753 return nil, fmt.Errorf("failed to get resource %q of kind %q: %w", resName.Name, resName.Kind, err)
754 }
755 resolvedRules, err := ctr.reconciler(res.Meta.Name.Kind).ResolveTransitiveAccess(ctx, claims, res)
756 if err != nil {
757 return nil, fmt.Errorf("failed to resolve transitive access rule: %w", err)
758 }
759 transitiveCount++
760 rules = append(rules, resolvedRules...)
761 }
762
763 if hasTransitive && transitiveCount == 0 {
764 // add access: false rule as no transitive access could be resolved
765 rules = append(rules, &runtimev1.SecurityRule{
766 Rule: &runtimev1.SecurityRule_Access{
767 Access: &runtimev1.SecurityRuleAccess{
768 Allow: false,
769 },
770 },
771 })
772 }
773 // gather all conditions kinds and resources mentioned in the rules so that we can add a single security rule access policy for them at the end.
774 // making sure only a single rule with the exclusive flag is added, otherwise we may get false rejections depending on which rule with the exclusive flag is evaluated first
775 var mergedRules []*runtimev1.SecurityRule
776 var conditionKinds []string
777 var conditionResources []*runtimev1.ResourceName
778 var conditionExpression string
779 // merge all access rules with an exclusive flag set in single rule
780 for _, rule := range rules {
781 if access := rule.GetAccess(); access != nil && access.Exclusive {
782 if access.ConditionExpression != "" {
783 if conditionExpression != "" {
784 conditionExpression = fmt.Sprintf("(%s) OR (%s)", conditionExpression, access.ConditionExpression)
785 } else {

Callers 1

resolveSecurityMethod · 0.95

Calls 8

GetTransitiveAccessMethod · 0.80
ControllerMethod · 0.80
reconcilerMethod · 0.80
GetAccessMethod · 0.80
GetResourceMethod · 0.65
ErrorfMethod · 0.65
GetMethod · 0.65

Tested by

no test coverage detected