Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.

Commit 349fe87

Browse files
feat: Add resource CEL lib (#529)
Signed-off-by: Luc Chmielowski <luc.chmielowski@nirmata.com> Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
1 parent be158dd commit 349fe87

14 files changed

Lines changed: 93 additions & 17 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ require (
7878
github.com/coreos/go-semver v0.3.1 // indirect
7979
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
8080
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
81+
github.com/creack/pty v1.1.19 // indirect
8182
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
8283
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
8384
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X
124124
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
125125
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
126126
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
127-
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
128-
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
127+
github.com/creack/pty v1.1.19 h1:tUN6H7LWqNx4hQVxomd0CVsDwaDr9gaRQaI4GpSmrsA=
128+
github.com/creack/pty v1.1.19/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
129129
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
130130
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
131131
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

pkg/authz/server.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@ import (
99
"github.com/kyverno/kyverno-envoy-plugin/pkg/server"
1010
"google.golang.org/grpc"
1111
"google.golang.org/grpc/reflection"
12+
"k8s.io/client-go/dynamic"
1213
)
1314

14-
func NewServer(network, addr string, provider engine.Provider) server.ServerFunc {
15+
func NewServer(network, addr string, provider engine.Provider, dynclient dynamic.Interface) server.ServerFunc {
1516
return func(ctx context.Context) error {
1617
// create a server
1718
s := grpc.NewServer()
1819
// setup our authorization service
1920
svc := &service{
20-
provider: provider,
21+
provider: provider,
22+
dynclient: dynclient,
2123
}
2224
// register our authorization service
2325
authv3.RegisterAuthorizationServer(s, svc)

pkg/authz/service.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import (
55

66
authv3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
77
"github.com/kyverno/kyverno-envoy-plugin/pkg/engine"
8+
"k8s.io/client-go/dynamic"
89
ctrl "sigs.k8s.io/controller-runtime"
910
)
1011

1112
type service struct {
12-
provider engine.Provider
13+
provider engine.Provider
14+
dynclient dynamic.Interface
1315
}
1416

1517
func (s *service) Check(ctx context.Context, r *authv3.CheckRequest) (*authv3.CheckResponse, error) {
@@ -34,7 +36,7 @@ func (s *service) check(ctx context.Context, r *authv3.CheckRequest) (_r *authv3
3436
// iterate over policies
3537
for _, policy := range policies {
3638
// collect allow/deny
37-
a, d := policy.For(r)
39+
a, d := policy.For(r, s.dynclient)
3840
if a != nil {
3941
allow = append(allow, a)
4042
}

pkg/cel/env.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/kyverno/kyverno/pkg/cel/libs/http"
1111
"github.com/kyverno/kyverno/pkg/cel/libs/image"
1212
"github.com/kyverno/kyverno/pkg/cel/libs/imagedata"
13+
"github.com/kyverno/kyverno/pkg/cel/libs/resource"
1314
"k8s.io/apiserver/pkg/cel/library"
1415
)
1516

@@ -46,5 +47,6 @@ func NewEnv() (*cel.Env, error) {
4647
image.Lib(),
4748
imagedata.Lib(),
4849
http.Lib(),
50+
resource.Lib(),
4951
)
5052
}

pkg/commands/serve/authz-server/command.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"k8s.io/apimachinery/pkg/fields"
2929
"k8s.io/apimachinery/pkg/runtime"
3030
"k8s.io/apimachinery/pkg/util/wait"
31+
"k8s.io/client-go/dynamic"
3132
"k8s.io/client-go/kubernetes"
3233
"k8s.io/client-go/tools/clientcmd"
3334
ctrl "sigs.k8s.io/controller-runtime"
@@ -74,18 +75,19 @@ func Command() *cobra.Command {
7475
var group wait.Group
7576
// wait all tasks in the group are over
7677
defer group.Wait()
77-
7878
secrets := make([]string, 0)
7979
if len(imagePullSecrets) > 0 {
8080
secrets = append(secrets, imagePullSecrets...)
8181
}
82-
82+
dynclient, err := dynamic.NewForConfig(config)
83+
if err != nil {
84+
return err
85+
}
8386
// Create kubernetes client
8487
kubeclient, err := kubernetes.NewForConfig(config)
8588
if err != nil {
8689
return err
8790
}
88-
8991
namespace, _, err := kubeConfig.Namespace()
9092
if err != nil {
9193
return fmt.Errorf("failed to get namespace from kubeconfig: %w", err)
@@ -95,12 +97,10 @@ func Command() *cobra.Command {
9597
log.Printf("Using namespace '%s' - consider setting explicit namespace", namespace)
9698
}
9799
rOpts, nOpts, err := ocifs.RegistryOpts(kubeclient.CoreV1().Secrets(namespace), allowInsecureRegistry, secrets...)
98-
99100
if err != nil {
100101
log.Fatalf("failed to initialize registry opts: %v", err)
101102
os.Exit(1)
102103
}
103-
104104
// create compilers
105105
apolCompiler := apolcompiler.NewCompiler()
106106
vpolCompiler := vpolcompiler.NewCompiler()
@@ -162,7 +162,7 @@ func Command() *cobra.Command {
162162
}
163163
// create http and grpc servers
164164
http := probes.NewServer(probesAddress)
165-
grpc := authz.NewServer(grpcNetwork, grpcAddress, provider)
165+
grpc := authz.NewServer(grpcNetwork, grpcAddress, provider, dynclient)
166166
// run servers
167167
group.StartWithContext(ctx, func(ctx context.Context) {
168168
// cancel context at the end

pkg/engine/apol/compiler/compiler.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/kyverno/kyverno-envoy-plugin/pkg/engine"
1212
"github.com/kyverno/kyverno/pkg/cel/libs/http"
1313
"github.com/kyverno/kyverno/pkg/cel/libs/imagedata"
14+
"github.com/kyverno/kyverno/pkg/cel/libs/resource"
1415
"k8s.io/apimachinery/pkg/util/validation/field"
1516
)
1617

@@ -19,6 +20,7 @@ const (
1920
ImageDataKey = "image"
2021
ObjectKey = "object"
2122
VariablesKey = "variables"
23+
ResourceKey = "resource"
2224
)
2325

2426
type Compiler = engine.Compiler[*v1alpha1.AuthorizationPolicy]
@@ -41,6 +43,7 @@ func (c *compiler) Compile(policy *v1alpha1.AuthorizationPolicy) (engine.Compile
4143
cel.Variable(ImageDataKey, imagedata.ContextType),
4244
cel.Variable(ObjectKey, envoy.CheckRequest),
4345
cel.Variable(VariablesKey, authzcel.VariablesType),
46+
cel.Variable(ResourceKey, resource.ContextType),
4447
cel.CustomTypeProvider(provider),
4548
)
4649
if err != nil {

pkg/engine/apol/compiler/compiler_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func TestCompiler(t *testing.T) {
109109
}
110110

111111
for _, test := range tests {
112-
allow, deny := compiled.For(test.request)
112+
allow, deny := compiled.For(test.request, nil)
113113
resp, err := deny()
114114
assert.NoError(t, err)
115115
if resp == nil {

pkg/engine/apol/compiler/policy.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import (
1414
"github.com/kyverno/kyverno-envoy-plugin/pkg/engine/variables"
1515
"github.com/kyverno/kyverno/pkg/cel/libs/http"
1616
"github.com/kyverno/kyverno/pkg/cel/libs/imagedata"
17+
"github.com/kyverno/kyverno/pkg/cel/libs/resource"
1718
"go.uber.org/multierr"
1819
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
1920
"k8s.io/apiserver/pkg/cel/lazy"
21+
"k8s.io/client-go/dynamic"
2022
)
2123

2224
type authorizationProgram struct {
@@ -32,7 +34,7 @@ type compiledPolicy struct {
3234
deny []authorizationProgram
3335
}
3436

35-
func (p compiledPolicy) For(r *authv3.CheckRequest) (engine.PolicyFunc, engine.PolicyFunc) {
37+
func (p compiledPolicy) For(r *authv3.CheckRequest, dynclient dynamic.Interface) (engine.PolicyFunc, engine.PolicyFunc) {
3638
match := sync.OnceValues(func() (bool, error) {
3739
data := map[string]any{
3840
ObjectKey: r,
@@ -70,6 +72,7 @@ func (p compiledPolicy) For(r *authv3.CheckRequest) (engine.PolicyFunc, engine.P
7072
HttpKey: http.Context{ContextInterface: http.NewHTTP(nil)},
7173
ImageDataKey: imagedata.Context{ContextInterface: loader},
7274
ObjectKey: r,
75+
ResourceKey: resource.Context{ContextInterface: variables.NewResourceProvider(dynclient)},
7376
VariablesKey: vars,
7477
}
7578
for name, variable := range p.variables {

pkg/engine/policy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package engine
22

33
import (
44
authv3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
5+
"k8s.io/client-go/dynamic"
56
)
67

78
type PolicyFunc func() (*authv3.CheckResponse, error)
89

910
type CompiledPolicy interface {
10-
For(r *authv3.CheckRequest) (PolicyFunc, PolicyFunc)
11+
For(*authv3.CheckRequest, dynamic.Interface) (PolicyFunc, PolicyFunc)
1112
}

0 commit comments

Comments
 (0)