...
1
16
17 package subjectrestriction
18
19 import (
20 "context"
21 "fmt"
22 "io"
23
24 certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
25 "k8s.io/apiserver/pkg/admission"
26 "k8s.io/klog/v2"
27 certificatesapi "k8s.io/kubernetes/pkg/apis/certificates"
28 )
29
30
31 const PluginName = "CertificateSubjectRestriction"
32
33
34 func Register(plugins *admission.Plugins) {
35 plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
36 return NewPlugin(), nil
37 })
38 }
39
40
41 type Plugin struct {
42 *admission.Handler
43 }
44
45
46 func (p *Plugin) ValidateInitialization() error {
47 return nil
48 }
49
50 var _ admission.ValidationInterface = &Plugin{}
51
52
53 func NewPlugin() *Plugin {
54 return &Plugin{
55 Handler: admission.NewHandler(admission.Create),
56 }
57 }
58
59 var csrGroupResource = certificatesapi.Resource("certificatesigningrequests")
60
61
62
63
64 func (p *Plugin) Validate(_ context.Context, a admission.Attributes, _ admission.ObjectInterfaces) error {
65 if a.GetResource().GroupResource() != csrGroupResource || a.GetSubresource() != "" {
66 return nil
67 }
68
69 csr, ok := a.GetObject().(*certificatesapi.CertificateSigningRequest)
70 if !ok {
71 return admission.NewForbidden(a, fmt.Errorf("expected type CertificateSigningRequest, got: %T", a.GetObject()))
72 }
73
74 if csr.Spec.SignerName != certificatesv1beta1.KubeAPIServerClientSignerName {
75 return nil
76 }
77
78 csrParsed, err := certificatesapi.ParseCSR(csr.Spec.Request)
79 if err != nil {
80 return admission.NewForbidden(a, fmt.Errorf("failed to parse CSR: %v", err))
81 }
82
83 for _, group := range csrParsed.Subject.Organization {
84 if group == "system:masters" {
85 klog.V(4).Infof("CSR %s rejected by admission plugin %s for attempting to use signer %s with system:masters group",
86 csr.Name, PluginName, certificatesv1beta1.KubeAPIServerClientSignerName)
87 return admission.NewForbidden(a, fmt.Errorf("use of %s signer with system:masters group is not allowed",
88 certificatesv1beta1.KubeAPIServerClientSignerName))
89 }
90 }
91
92 return nil
93 }
94
View as plain text