func (r *RBACAuthorizer) Authorize(attr authorizer.Attributes) error { if r.superUser != "" && attr.GetUserName() == r.superUser { return nil } userInfo := &user.DefaultInfo{ Name: attr.GetUserName(), Groups: attr.GetGroups(), } ctx := api.WithNamespace(api.WithUser(api.NewContext(), userInfo), attr.GetNamespace()) // Frame the authorization request as a privilege escalation check. var requestedRule rbac.PolicyRule if attr.IsResourceRequest() { requestedRule = rbac.PolicyRule{ Verbs: []string{attr.GetVerb()}, APIGroups: []string{attr.GetAPIGroup()}, // TODO(ericchiang): add api version here too? Resources: []string{attr.GetResource()}, ResourceNames: []string{attr.GetName()}, } } else { requestedRule = rbac.PolicyRule{ NonResourceURLs: []string{attr.GetPath()}, } } return validation.ConfirmNoEscalation(ctx, r.authorizationRuleResolver, []rbac.PolicyRule{requestedRule}) }
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { if u, ok := api.UserFrom(ctx); ok { if s.superUser != "" && u.GetName() == s.superUser { return s.StandardStorage.Create(ctx, obj) } // system:masters is special because the API server uses it for privileged loopback connections // therefore we know that a member of system:masters can always do anything for _, group := range u.GetGroups() { if group == user.SystemPrivilegedGroup { return s.StandardStorage.Create(ctx, obj) } } } clusterRoleBinding := obj.(*rbac.ClusterRoleBinding) rules, err := s.ruleResolver.GetRoleReferenceRules(ctx, clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace) if err != nil { return nil, err } if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err) } return s.StandardStorage.Create(ctx, obj) }
func (r *RBACAuthorizer) Authorize(attr authorizer.Attributes) (bool, string, error) { if r.superUser != "" && attr.GetUser() != nil && attr.GetUser().GetName() == r.superUser { return true, "", nil } ctx := api.WithNamespace(api.WithUser(api.NewContext(), attr.GetUser()), attr.GetNamespace()) // Frame the authorization request as a privilege escalation check. var requestedRule rbac.PolicyRule if attr.IsResourceRequest() { requestedRule = rbac.PolicyRule{ Verbs: []string{attr.GetVerb()}, APIGroups: []string{attr.GetAPIGroup()}, // TODO(ericchiang): add api version here too? Resources: []string{attr.GetResource()}, ResourceNames: []string{attr.GetName()}, } } else { requestedRule = rbac.PolicyRule{ Verbs: []string{attr.GetVerb()}, NonResourceURLs: []string{attr.GetPath()}, } } // TODO(nhlfr): Try to find more lightweight way to check attributes than escalation checks. err := validation.ConfirmNoEscalation(ctx, r.authorizationRuleResolver, []rbac.PolicyRule{requestedRule}) if err != nil { return false, err.Error(), nil } return true, "", nil }
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { if rbacregistry.EscalationAllowed(ctx, s.superUser) { return s.StandardStorage.Create(ctx, obj) } clusterRole := obj.(*rbac.ClusterRole) rules := clusterRole.Rules if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, clusterRole.Name, err) } return s.StandardStorage.Create(ctx, obj) }
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { if user, ok := api.UserFrom(ctx); ok { if s.superUser != "" && user.GetName() == s.superUser { return s.StandardStorage.Create(ctx, obj) } } clusterRole := obj.(*rbac.ClusterRole) rules := clusterRole.Rules if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, clusterRole.Name, err) } return s.StandardStorage.Create(ctx, obj) }
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { if rbacregistry.EscalationAllowed(ctx) { return s.StandardStorage.Create(ctx, obj) } clusterRoleBinding := obj.(*rbac.ClusterRoleBinding) rules, err := s.ruleResolver.GetRoleReferenceRules(clusterRoleBinding.RoleRef, clusterRoleBinding.Namespace) if err != nil { return nil, err } if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err) } return s.StandardStorage.Create(ctx, obj) }
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) { if rbacregistry.EscalationAllowed(ctx, s.superUser) { return s.StandardStorage.Update(ctx, name, obj) } nonEscalatingInfo := wrapUpdatedObjectInfo(obj, func(ctx api.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) { clusterRole := obj.(*rbac.ClusterRole) rules := clusterRole.Rules if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, clusterRole.Name, err) } return obj, nil }) return s.StandardStorage.Update(ctx, name, nonEscalatingInfo) }
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { if user, ok := api.UserFrom(ctx); ok { if s.superUser != "" && user.GetName() == s.superUser { return s.StandardStorage.Create(ctx, obj) } } roleBinding := obj.(*rbac.RoleBinding) rules, err := s.ruleResolver.GetRoleReferenceRules(ctx, roleBinding.RoleRef, roleBinding.Namespace) if err != nil { return nil, err } if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, roleBinding.Name, err) } return s.StandardStorage.Create(ctx, obj) }
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) { if user, ok := api.UserFrom(ctx); ok { if s.superUser != "" && user.GetName() == s.superUser { return s.StandardStorage.Update(ctx, name, obj) } } nonEscalatingInfo := wrapUpdatedObjectInfo(obj, func(ctx api.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) { role := obj.(*rbac.Role) rules := role.Rules if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, role.Name, err) } return obj, nil }) return s.StandardStorage.Update(ctx, name, nonEscalatingInfo) }
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) { if rbacregistry.EscalationAllowed(ctx, s.superUser) { return s.StandardStorage.Update(ctx, name, obj) } nonEscalatingInfo := wrapUpdatedObjectInfo(obj, func(ctx api.Context, obj runtime.Object, oldObj runtime.Object) (runtime.Object, error) { roleBinding := obj.(*rbac.RoleBinding) rules, err := s.ruleResolver.GetRoleReferenceRules(roleBinding.RoleRef, roleBinding.Namespace) if err != nil { return nil, err } if err := validation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil { return nil, errors.NewForbidden(groupResource, roleBinding.Name, err) } return obj, nil }) return s.StandardStorage.Update(ctx, name, nonEscalatingInfo) }