Skip to content

Commit

Permalink
Support access: security policies on Explore and Canvas resourc…
Browse files Browse the repository at this point in the history
…es (#5728)
  • Loading branch information
begelundmuller authored Sep 20, 2024
1 parent 792b3fa commit 10c6897
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 194 deletions.
386 changes: 200 additions & 186 deletions proto/gen/rill/runtime/v1/resources.pb.go

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions proto/gen/rill/runtime/v1/resources.pb.validate.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions proto/gen/rill/runtime/v1/runtime.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3385,6 +3385,11 @@ definitions:
items:
type: object
$ref: '#/definitions/v1CanvasItem'
securityRules:
type: array
items:
type: object
$ref: '#/definitions/v1SecurityRule'
v1CanvasState:
type: object
properties:
Expand Down
1 change: 1 addition & 0 deletions proto/rill/runtime/v1/resources.proto
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ message CanvasSpec {
uint32 gap = 3;
repeated ComponentVariable variables = 5;
repeated CanvasItem items = 4;
repeated SecurityRule security_rules = 6;
}

message CanvasState {
Expand Down
13 changes: 13 additions & 0 deletions runtime/compilers/rillv1/parse_canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type CanvasYAML struct {
Width *uint32 `yaml:"width"`
Height *uint32 `yaml:"height"`
} `yaml:"items"`
Security *SecurityPolicyYAML `yaml:"security"`
}

func (p *Parser) parseCanvas(node *Node) error {
Expand Down Expand Up @@ -80,6 +81,17 @@ func (p *Parser) parseCanvas(node *Node) error {
node.Refs = append(node.Refs, ResourceName{Kind: ResourceKindComponent, Name: component})
}

// Parse security rules
rules, err := tmp.Security.Proto()
if err != nil {
return err
}
for _, rule := range rules {
if rule.GetAccess() == nil {
return fmt.Errorf("the 'canvas' resource type only supports 'access' security rules")
}
}

// Track canvas
r, err := p.insertResource(ResourceKindCanvas, node.Name, node.Paths, node.Refs...)
if err != nil {
Expand All @@ -92,6 +104,7 @@ func (p *Parser) parseCanvas(node *Node) error {
r.CanvasSpec.Gap = tmp.Gap
r.CanvasSpec.Variables = variables
r.CanvasSpec.Items = items
r.CanvasSpec.SecurityRules = rules

// Track inline components
for _, def := range inlineComponentDefs {
Expand Down
13 changes: 13 additions & 0 deletions runtime/compilers/rillv1/parse_explore.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type ExploreYAML struct {
ComparisonMode string `yaml:"comparison_mode"`
ComparisonDimension string `yaml:"comparison_dimension"`
} `yaml:"presets"`
Security *SecurityPolicyYAML `yaml:"security"`
}

// NamesYAML parses a list of names with support for a '*' scalar for all names,
Expand Down Expand Up @@ -268,6 +269,17 @@ func (p *Parser) parseExplore(node *Node) error {
})
}

// Build security rules
rules, err := tmp.Security.Proto()
if err != nil {
return err
}
for _, rule := range rules {
if rule.GetAccess() == nil {
return fmt.Errorf("the 'explore' resource type only supports 'access' security rules")
}
}

// Track explore
r, err := p.insertResource(ResourceKindExplore, node.Name, node.Paths, node.Refs...)
if err != nil {
Expand All @@ -286,6 +298,7 @@ func (p *Parser) parseExplore(node *Node) error {
r.ExploreSpec.TimeRanges = timeRanges
r.ExploreSpec.TimeZones = tmp.TimeZones
r.ExploreSpec.Presets = presets
r.ExploreSpec.SecurityRules = rules

return nil
}
12 changes: 6 additions & 6 deletions runtime/compilers/rillv1/parse_metrics_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type MetricsViewYAML struct {
Ignore bool `yaml:"ignore"` // Deprecated
ValidPercentOfTotal bool `yaml:"valid_percent_of_total"`
}
Security *MetricsViewSecurityPolicyYAML
Security *SecurityPolicyYAML

// DEPRECATED FIELDS
DefaultTimeRange string `yaml:"default_time_range"`
Expand Down Expand Up @@ -191,7 +191,7 @@ func (f *MetricsViewMeasureWindow) UnmarshalYAML(v *yaml.Node) error {
return nil
}

type MetricsViewSecurityPolicyYAML struct {
type SecurityPolicyYAML struct {
Access string `yaml:"access"`
RowFilter string `yaml:"row_filter"`
Include []*struct {
Expand All @@ -202,10 +202,10 @@ type MetricsViewSecurityPolicyYAML struct {
Condition string `yaml:"if"`
Names yaml.Node // []string or "*" (will be parsed with parseNamesYAML)
}
Rules []*MetricsViewSecurityRuleYAML `yaml:"rules"`
Rules []*SecurityRuleYAML `yaml:"rules"`
}

func (p *MetricsViewSecurityPolicyYAML) Proto() ([]*runtimev1.SecurityRule, error) {
func (p *SecurityPolicyYAML) Proto() ([]*runtimev1.SecurityRule, error) {
var rules []*runtimev1.SecurityRule
if p == nil {
return rules, nil
Expand Down Expand Up @@ -355,7 +355,7 @@ func (p *MetricsViewSecurityPolicyYAML) Proto() ([]*runtimev1.SecurityRule, erro
return rules, nil
}

type MetricsViewSecurityRuleYAML struct {
type SecurityRuleYAML struct {
Type string
Action string
If string
Expand All @@ -364,7 +364,7 @@ type MetricsViewSecurityRuleYAML struct {
SQL string
}

func (r *MetricsViewSecurityRuleYAML) Proto() (*runtimev1.SecurityRule, error) {
func (r *SecurityRuleYAML) Proto() (*runtimev1.SecurityRule, error) {
condition := r.If
if condition != "" {
tmp, err := ResolveTemplate(condition, validationTemplateData)
Expand Down
12 changes: 10 additions & 2 deletions runtime/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,17 @@ func (p *securityEngine) resolveRules(claims *SecurityClaims, r *runtimev1.Resou
// Everyone can access a component.
case ResourceKindComponent:
rules = append(rules, allowAccessRule)
// Everyone can access a canvas.
// Determine access using the canvas' security rules. If there are none, then everyone can access it.
case ResourceKindCanvas:
rules = append(rules, allowAccessRule)
spec := r.GetCanvas().State.ValidSpec
if spec == nil {
spec = r.GetCanvas().Spec // Not ideal, but better than giving access to the full resource
}
if len(spec.SecurityRules) == 0 {
rules = append(rules, allowAccessRule)
} else {
rules = append(rules, spec.SecurityRules...)
}
// Determine access using the metrics view's security rules. If there are none, then everyone can access it.
case ResourceKindMetricsView:
spec := r.GetMetricsView().State.ValidSpec
Expand Down
6 changes: 6 additions & 0 deletions web-common/src/proto/gen/rill/runtime/v1/resources_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4177,6 +4177,11 @@ export class CanvasSpec extends Message<CanvasSpec> {
*/
items: CanvasItem[] = [];

/**
* @generated from field: repeated rill.runtime.v1.SecurityRule security_rules = 6;
*/
securityRules: SecurityRule[] = [];

constructor(data?: PartialMessage<CanvasSpec>) {
super();
proto3.util.initPartial(data, this);
Expand All @@ -4190,6 +4195,7 @@ export class CanvasSpec extends Message<CanvasSpec> {
{ no: 3, name: "gap", kind: "scalar", T: 13 /* ScalarType.UINT32 */ },
{ no: 5, name: "variables", kind: "message", T: ComponentVariable, repeated: true },
{ no: 4, name: "items", kind: "message", T: CanvasItem, repeated: true },
{ no: 6, name: "security_rules", kind: "message", T: SecurityRule, repeated: true },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CanvasSpec {
Expand Down
1 change: 1 addition & 0 deletions web-common/src/runtime-client/gen/index.schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,7 @@ export interface V1CanvasSpec {
gap?: number;
variables?: V1ComponentVariable[];
items?: V1CanvasItem[];
securityRules?: V1SecurityRule[];
}

export interface V1CanvasState {
Expand Down

1 comment on commit 10c6897

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.