admission.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package scdeny
  14. import (
  15. "fmt"
  16. "io"
  17. apierrors "k8s.io/apimachinery/pkg/api/errors"
  18. "k8s.io/apiserver/pkg/admission"
  19. api "k8s.io/kubernetes/pkg/apis/core"
  20. )
  21. // PluginName indicates name of admission plugin.
  22. const PluginName = "SecurityContextDeny"
  23. // Register registers a plugin
  24. func Register(plugins *admission.Plugins) {
  25. plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
  26. return NewSecurityContextDeny(), nil
  27. })
  28. }
  29. // Plugin implements admission.Interface.
  30. type Plugin struct {
  31. *admission.Handler
  32. }
  33. var _ admission.ValidationInterface = &Plugin{}
  34. // NewSecurityContextDeny creates a new instance of the SecurityContextDeny admission controller
  35. func NewSecurityContextDeny() *Plugin {
  36. return &Plugin{
  37. Handler: admission.NewHandler(admission.Create, admission.Update),
  38. }
  39. }
  40. // Validate will deny any pod that defines SupplementalGroups, SELinuxOptions, RunAsUser or FSGroup
  41. func (p *Plugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
  42. if a.GetSubresource() != "" || a.GetResource().GroupResource() != api.Resource("pods") {
  43. return nil
  44. }
  45. pod, ok := a.GetObject().(*api.Pod)
  46. if !ok {
  47. return apierrors.NewBadRequest("Resource was marked with kind Pod but was unable to be converted")
  48. }
  49. if pod.Spec.SecurityContext != nil {
  50. if pod.Spec.SecurityContext.SupplementalGroups != nil {
  51. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("pod.Spec.SecurityContext.SupplementalGroups is forbidden"))
  52. }
  53. if pod.Spec.SecurityContext.SELinuxOptions != nil {
  54. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("pod.Spec.SecurityContext.SELinuxOptions is forbidden"))
  55. }
  56. if pod.Spec.SecurityContext.RunAsUser != nil {
  57. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("pod.Spec.SecurityContext.RunAsUser is forbidden"))
  58. }
  59. if pod.Spec.SecurityContext.FSGroup != nil {
  60. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("pod.Spec.SecurityContext.FSGroup is forbidden"))
  61. }
  62. }
  63. for _, v := range pod.Spec.InitContainers {
  64. if v.SecurityContext != nil {
  65. if v.SecurityContext.SELinuxOptions != nil {
  66. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("SecurityContext.SELinuxOptions is forbidden"))
  67. }
  68. if v.SecurityContext.RunAsUser != nil {
  69. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("SecurityContext.RunAsUser is forbidden"))
  70. }
  71. }
  72. }
  73. for _, v := range pod.Spec.Containers {
  74. if v.SecurityContext != nil {
  75. if v.SecurityContext.SELinuxOptions != nil {
  76. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("SecurityContext.SELinuxOptions is forbidden"))
  77. }
  78. if v.SecurityContext.RunAsUser != nil {
  79. return apierrors.NewForbidden(a.GetResource().GroupResource(), pod.Name, fmt.Errorf("SecurityContext.RunAsUser is forbidden"))
  80. }
  81. }
  82. }
  83. return nil
  84. }