From 203de6322a9e7414f2e08a2a681461cc89644a39 Mon Sep 17 00:00:00 2001 From: Andrew Haines Date: Fri, 1 Nov 2024 15:11:00 +0000 Subject: [PATCH] feat: Support constants Signed-off-by: Andrew Haines --- cerbos/grpc_admin_test.go | 1 + cerbos/model.go | 121 +++++++++++++++++- cerbos/model_test.go | 29 +++++ go.mod | 30 ++--- go.sum | 54 ++++---- .../derived_roles/derived_roles_04.yaml | 3 + .../export_constants/export_constants_01.yaml | 10 ++ .../export_variables/export_variables_01.yaml | 2 +- internal/validate.go | 11 ++ 9 files changed, 218 insertions(+), 43 deletions(-) create mode 100644 internal/tests/testdata/policies/export_constants/export_constants_01.yaml diff --git a/cerbos/grpc_admin_test.go b/cerbos/grpc_admin_test.go index 53a18c3..a533ddb 100644 --- a/cerbos/grpc_admin_test.go +++ b/cerbos/grpc_admin_test.go @@ -130,6 +130,7 @@ func TestAdminClient(t *testing.T) { "derived_roles.apatr_common_roles": "derived_roles/common_roles.yaml", "derived_roles.alpha": "derived_roles/derived_roles_01.yaml", "derived_roles.beta": "derived_roles/derived_roles_02.yaml", + "export_constants.bazqux": "export_constants/export_constants_01.yaml", "export_variables.foobar": "export_variables/export_variables_01.yaml", "principal.donald_duck.vdefault": "principal_policies/policy_02.yaml", "principal.donald_duck.vdefault/acme": "principal_policies/policy_02_acme.yaml", diff --git a/cerbos/model.go b/cerbos/model.go index 82f49fa..7eacd9e 100644 --- a/cerbos/model.go +++ b/cerbos/model.go @@ -517,6 +517,21 @@ func (ps *PolicySet) AddDerivedRoles(policies ...*DerivedRoles) *PolicySet { return ps } +// AddExportConstants adds the given exported constants to the set. +func (ps *PolicySet) AddExportConstants(policies ...*ExportConstants) *PolicySet { + for _, p := range policies { + if p == nil { + continue + } + + if err := ps.add(p); err != nil { + ps.err = multierr.Append(ps.err, fmt.Errorf("failed to add exported constants [%s]: %w", p.Obj.Name, err)) + } + } + + return ps +} + // AddExportVariables adds the given exported variables to the set. func (ps *PolicySet) AddExportVariables(policies ...*ExportVariables) *PolicySet { for _, p := range policies { @@ -706,6 +721,7 @@ func NewResourcePolicy(resource, version string) *ResourcePolicy { Obj: &policyv1.ResourcePolicy{ Resource: resource, Version: version, + Constants: &policyv1.Constants{Local: make(map[string]*structpb.Value)}, Variables: &policyv1.Variables{Local: make(map[string]string)}, }, } @@ -750,6 +766,23 @@ func (rp *ResourcePolicy) AddResourceRules(rules ...*ResourceRule) *ResourcePoli return rp } +// WithConstantsImports adds import statements for exported constants. +func (rp *ResourcePolicy) WithConstantsImports(name ...string) *ResourcePolicy { + rp.Obj.Constants.Import = append(rp.Obj.Constants.Import, name...) + return rp +} + +// WithConstant adds a constant definition for use in conditions. +// Valid value types are those that can be converted to a [google.protobuf.Value]. +// +// [google.protobuf.Value]: https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb#NewValue +func (rp *ResourcePolicy) WithConstant(name string, value any) *ResourcePolicy { + var err error + rp.Obj.Constants.Local[name], err = structpb.NewValue(value) + rp.err = multierr.Append(rp.err, err) + return rp +} + // WithVariablesImports adds import statements for exported variables. func (rp *ResourcePolicy) WithVariablesImports(name ...string) *ResourcePolicy { rp.Obj.Variables.Import = append(rp.Obj.Variables.Import, name...) @@ -864,6 +897,7 @@ func NewPrincipalPolicy(principal, version string) *PrincipalPolicy { Obj: &policyv1.PrincipalPolicy{ Principal: principal, Version: version, + Constants: &policyv1.Constants{Local: make(map[string]*structpb.Value)}, Variables: &policyv1.Variables{Local: make(map[string]string)}, }, } @@ -899,6 +933,23 @@ func (pp *PrincipalPolicy) WithVersion(version string) *PrincipalPolicy { return pp } +// WithConstantsImports adds import statements for exported constants. +func (pp *PrincipalPolicy) WithConstantsImports(name ...string) *PrincipalPolicy { + pp.Obj.Constants.Import = append(pp.Obj.Constants.Import, name...) + return pp +} + +// WithConstant adds a constant definition for use in conditions. +// Valid value types are those that can be converted to a [google.protobuf.Value]. +// +// [google.protobuf.Value]: https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb#NewValue +func (pp *PrincipalPolicy) WithConstant(name string, value any) *PrincipalPolicy { + var err error + pp.Obj.Constants.Local[name], err = structpb.NewValue(value) + pp.err = multierr.Append(pp.err, err) + return pp +} + // WithVariablesImports adds import statements for exported variables. func (pp *PrincipalPolicy) WithVariablesImports(name ...string) *PrincipalPolicy { pp.Obj.Variables.Import = append(pp.Obj.Variables.Import, name...) @@ -996,6 +1047,7 @@ func (pr *PrincipalRule) Validate() error { // DerivedRoles is a builder for derived roles. type DerivedRoles struct { Obj *policyv1.DerivedRoles + err error } // NewDerivedRoles creates a new derived roles set with the given name. @@ -1003,6 +1055,7 @@ func NewDerivedRoles(name string) *DerivedRoles { return &DerivedRoles{ Obj: &policyv1.DerivedRoles{ Name: name, + Constants: &policyv1.Constants{Local: make(map[string]*structpb.Value)}, Variables: &policyv1.Variables{Local: make(map[string]string)}, }, } @@ -1024,6 +1077,23 @@ func (dr *DerivedRoles) addRoleDef(name string, parentRoles []string, comp *poli return dr } +// WithConstantsImports adds import statements for exported constants. +func (dr *DerivedRoles) WithConstantsImports(name ...string) *DerivedRoles { + dr.Obj.Constants.Import = append(dr.Obj.Constants.Import, name...) + return dr +} + +// WithConstant adds a constant definition for use in conditions. +// Valid value types are those that can be converted to a [google.protobuf.Value]. +// +// [google.protobuf.Value]: https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb#NewValue +func (dr *DerivedRoles) WithConstant(name string, value any) *DerivedRoles { + var err error + dr.Obj.Constants.Local[name], err = structpb.NewValue(value) + dr.err = multierr.Append(dr.err, err) + return dr +} + // WithVariablesImports adds import statements for exported variables. func (dr *DerivedRoles) WithVariablesImports(name ...string) *DerivedRoles { dr.Obj.Variables.Import = append(dr.Obj.Variables.Import, name...) @@ -1038,7 +1108,7 @@ func (dr *DerivedRoles) WithVariable(name, expr string) *DerivedRoles { // Err returns any errors accumulated during the construction of the derived roles. func (dr *DerivedRoles) Err() error { - return nil + return dr.err } // Validate checks whether the derived roles are valid. @@ -1058,6 +1128,55 @@ func (dr *DerivedRoles) build() (*policyv1.Policy, error) { return p, internal.ValidatePolicy(p) } +// ExportConstants is a builder for exported constants. +type ExportConstants struct { + Obj *policyv1.ExportConstants + err error +} + +// NewExportConstants creates a new exported constants set with the given name. +func NewExportConstants(name string) *ExportConstants { + return &ExportConstants{ + Obj: &policyv1.ExportConstants{ + Name: name, + Definitions: make(map[string]*structpb.Value), + }, + } +} + +// AddConstant defines an exported constant with the given name to be the given value. +// Valid value types are those that can be converted to a [google.protobuf.Value]. +// +// [google.protobuf.Value]: https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb#NewValue +func (ec *ExportConstants) AddConstant(name string, value any) *ExportConstants { + var err error + ec.Obj.Definitions[name], err = structpb.NewValue(value) + ec.err = multierr.Append(ec.err, err) + return ec +} + +// Err returns any errors accumulated during the construction of the exported constants. +func (ec *ExportConstants) Err() error { + return ec.err +} + +// Validate checks whether the exported constants are valid. +func (ec *ExportConstants) Validate() error { + _, err := ec.build() + return err +} + +func (ec *ExportConstants) build() (*policyv1.Policy, error) { + p := &policyv1.Policy{ + ApiVersion: apiVersion, + PolicyType: &policyv1.Policy_ExportConstants{ + ExportConstants: ec.Obj, + }, + } + + return p, internal.ValidatePolicy(p) +} + // ExportVariables is a builder for exported variables. type ExportVariables struct { Obj *policyv1.ExportVariables diff --git a/cerbos/model_test.go b/cerbos/model_test.go index 4f7e9b6..dfc112f 100644 --- a/cerbos/model_test.go +++ b/cerbos/model_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/structpb" "github.com/cerbos/cerbos-sdk-go/cerbos" effectv1 "github.com/cerbos/cerbos/api/genpb/cerbos/effect/v1" @@ -19,9 +20,12 @@ import ( const ( actionApprove = "approve" actionCreate = "create" + constantName = "bar" + constantValue = float64(9000) id = "XX125" kind = "leave_request" derivedRolesName = "my_derived_roles" + exportConstantsName = "my_constants" exportVariablesName = "my_variables" ref = "cerbos:///principal.json" roleName = "employee_that_owns_the_record" @@ -65,6 +69,11 @@ func TestBuilders(t *testing.T) { require.NoError(t, dr.Validate()) cmpDerivedRoles(t, dr) }) + t.Run("ExportConstants", func(t *testing.T) { + ec := newExportConstants(t) + require.NoError(t, ec.Validate()) + cmpExportConstants(t, ec) + }) t.Run("ExportVariables", func(t *testing.T) { ev := newExportVariables(t) require.NoError(t, ev.Validate()) @@ -127,6 +136,13 @@ func cmpDerivedRoles(t *testing.T, dr *cerbos.DerivedRoles) { require.Equal(t, map[string]string{variableName: variableExpr}, dr.Obj.Variables.Local) } +func cmpExportConstants(t *testing.T, ec *cerbos.ExportConstants) { + t.Helper() + + require.Equal(t, exportConstantsName, ec.Obj.Name) + require.Equal(t, map[string]any{constantName: constantValue}, (&structpb.Struct{Fields: ec.Obj.Definitions}).AsMap()) +} + func cmpExportVariables(t *testing.T, ev *cerbos.ExportVariables) { t.Helper() @@ -242,11 +258,20 @@ func newDerivedRoles(t *testing.T) *cerbos.DerivedRoles { t.Helper() return cerbos.NewDerivedRoles(derivedRolesName). + WithConstantsImports(exportConstantsName). + WithConstant(constantName, constantValue). WithVariablesImports(exportVariablesName). WithVariable(variableName, variableExpr). AddRole(roleName, roles) } +func newExportConstants(t *testing.T) *cerbos.ExportConstants { + t.Helper() + + return cerbos.NewExportConstants(exportConstantsName). + AddConstant(constantName, constantValue) +} + func newExportVariables(t *testing.T) *cerbos.ExportVariables { t.Helper() @@ -280,6 +305,8 @@ func newPrincipalPolicy(t *testing.T) *cerbos.PrincipalPolicy { return cerbos.NewPrincipalPolicy(principal, version). WithScope(scope). + WithConstantsImports(exportConstantsName). + WithConstant(constantName, constantValue). WithVariablesImports(exportVariablesName). WithVariable(variableName, variableExpr). AddPrincipalRules( @@ -292,6 +319,8 @@ func newResourcePolicy(t *testing.T) *cerbos.ResourcePolicy { return cerbos.NewResourcePolicy(resource, version). WithScope(scope). + WithConstantsImports(exportConstantsName). + WithConstant(constantName, constantValue). WithVariablesImports(exportVariablesName). WithVariable(variableName, variableExpr) } diff --git a/go.mod b/go.mod index 427a91f..a6f6eb9 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/cerbos/cerbos-sdk-go -go 1.22 +go 1.22.0 toolchain go1.23.2 require ( github.com/bufbuild/protovalidate-go v0.7.2 github.com/cenkalti/backoff/v4 v4.3.0 - github.com/cerbos/cerbos/api/genpb v0.39.0 + github.com/cerbos/cerbos/api/genpb v0.39.1-0.20241104095130-b7e5c7703d82 github.com/ghodss/yaml v1.0.0 github.com/google/go-cmp v0.6.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 @@ -22,17 +22,17 @@ require ( ) require ( - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240920164238-5a7b106cbb87.2 // indirect - dario.cat/mergo v1.0.0 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240920164238-5a7b106cbb87.1 // indirect + dario.cat/mergo v1.0.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/containerd/continuity v0.4.3 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/docker/cli v27.1.1+incompatible // indirect - github.com/docker/docker v27.1.1+incompatible // indirect + github.com/docker/docker v27.2.0+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/go-viper/mapstructure/v2 v2.0.0 // indirect @@ -40,7 +40,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/google/cel-go v0.21.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httprc v1.0.6 // indirect @@ -52,9 +52,9 @@ require ( github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/runc v1.1.14 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20241011083415-71c992bc3c87 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect @@ -62,12 +62,12 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect golang.org/x/crypto v0.28.0 // indirect - golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 081c11a..b640e32 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240920164238-5a7b106cbb87.2 h1:hl0FrmGlNpQZIGvU1/jDz0lsPDd0BhCE0QDRwPfLZcA= -buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240920164238-5a7b106cbb87.2/go.mod h1:ylS4c28ACSI59oJrOdW4pHS4n0Hw4TgSPHn8rpHl4Yw= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240920164238-5a7b106cbb87.1 h1:9wP6ZZYWnF2Z0TxmII7m3XNykxnP4/w8oXeth6ekcRI= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240920164238-5a7b106cbb87.1/go.mod h1:Duw/9JoXkXIydyASnLYIiufkzySThoqavOsF+IihqvM= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= @@ -10,27 +10,28 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/bufbuild/protovalidate-go v0.7.2 h1:UuvKyZHl5p7u3ztEjtRtqtDxOjRKX5VUOgKFq6p6ETk= github.com/bufbuild/protovalidate-go v0.7.2/go.mod h1:PHV5pFuWlRzdDW02/cmVyNzdiQ+RNNwo7idGxdzS7o4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cerbos/cerbos/api/genpb v0.39.0 h1:1q1sII0hL1zhw60cib8DvfYbhFDtBuelr8l1CYbrPY8= -github.com/cerbos/cerbos/api/genpb v0.39.0/go.mod h1:3WDoMQBKxz736Bzmj15DmonHcdhSf50jcIYprtcjRsc= +github.com/cerbos/cerbos/api/genpb v0.39.1-0.20241104095130-b7e5c7703d82 h1:CPJ94XMOuUy0rf0LA4xN11tbA/9EvOYlWG9Y6r6qCQ4= +github.com/cerbos/cerbos/api/genpb v0.39.1-0.20241104095130-b7e5c7703d82/go.mod h1:2pxs1BwPapJs/nXdnWJpXmAHOVmPq3Bgkzwv2wcn+GE= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= -github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4= +github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -55,8 +56,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/jdxcode/netrc v1.0.0 h1:tJR3fyzTcjDi22t30pCdpOT8WJ5gb32zfYE1hFNCOjk= github.com/jdxcode/netrc v1.0.0/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -96,12 +97,13 @@ github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNG github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587 h1:xzZOeCMQLA/W198ZkdVdt4EKFKJtS26B773zNU377ZY= -github.com/planetscale/vtprotobuf v0.6.1-0.20240917153116-6f2963f01587/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/planetscale/vtprotobuf v0.6.1-0.20241011083415-71c992bc3c87 h1:ejBLlgnQdFWS/QGVdGYBRKsorfWl8rOysCC6aUOlCZc= +github.com/planetscale/vtprotobuf v0.6.1-0.20241011083415-71c992bc3c87/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= @@ -137,16 +139,16 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -169,10 +171,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61 h1:pAjq8XSSzXoP9ya73v/w+9QEAAJNluLrpmMq5qFJQNY= -google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:O6rP0uBq4k0mdi/b4ZEMAZjkhYWhS815kCvaMha4VN8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 h1:2oV8dfuIkM1Ti7DwXc0BJfnwr9csz4TDXI9EmiI+Rbw= +google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38/go.mod h1:vuAjtvlwkDKF6L1GQ0SokiRLCGFfeBUXWr/aFFkHACc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= diff --git a/internal/tests/testdata/policies/derived_roles/derived_roles_04.yaml b/internal/tests/testdata/policies/derived_roles/derived_roles_04.yaml index f2be769..f75bc51 100644 --- a/internal/tests/testdata/policies/derived_roles/derived_roles_04.yaml +++ b/internal/tests/testdata/policies/derived_roles/derived_roles_04.yaml @@ -3,6 +3,9 @@ apiVersion: api.cerbos.dev/v1 derivedRoles: name: import_variables + constants: + import: + - bazqux variables: import: - foobar diff --git a/internal/tests/testdata/policies/export_constants/export_constants_01.yaml b/internal/tests/testdata/policies/export_constants/export_constants_01.yaml new file mode 100644 index 0000000..bae93f3 --- /dev/null +++ b/internal/tests/testdata/policies/export_constants/export_constants_01.yaml @@ -0,0 +1,10 @@ +# yaml-language-server: $schema=../../../../../schema/jsonschema/cerbos/policy/v1/Policy.schema.json +--- +apiVersion: api.cerbos.dev/v1 +exportConstants: + name: bazqux + definitions: + baz: 42 + qux: + hello: + - world diff --git a/internal/tests/testdata/policies/export_variables/export_variables_01.yaml b/internal/tests/testdata/policies/export_variables/export_variables_01.yaml index 3ddc0ca..b810607 100644 --- a/internal/tests/testdata/policies/export_variables/export_variables_01.yaml +++ b/internal/tests/testdata/policies/export_variables/export_variables_01.yaml @@ -4,5 +4,5 @@ apiVersion: api.cerbos.dev/v1 exportVariables: name: foobar definitions: - foo: "42" + foo: C.baz bar: R.attr.foo == V.foo diff --git a/internal/validate.go b/internal/validate.go index f53d045..a2dce86 100644 --- a/internal/validate.go +++ b/internal/validate.go @@ -72,6 +72,8 @@ func ValidatePolicy(p *policyv1.Policy) error { return validatePrincipalPolicy(pt.PrincipalPolicy) case *policyv1.Policy_DerivedRoles: return validateDerivedRoles(pt.DerivedRoles) + case *policyv1.Policy_ExportConstants: + return validateExportConstants(p) case *policyv1.Policy_ExportVariables: return validateExportVariables(p) default: @@ -155,6 +157,15 @@ func validateDerivedRoles(dr *policyv1.DerivedRoles) (err error) { return } +func validateExportConstants(p *policyv1.Policy) error { + //nolint:staticcheck + if len(p.Variables) > 0 { + return fmt.Errorf("export constants policies do not support the deprecated top-level variables field") + } + + return nil +} + func validateExportVariables(p *policyv1.Policy) error { //nolint:staticcheck if len(p.Variables) > 0 {