remove rbac super user

pull/6/head
deads2k 2016-12-05 11:28:59 -05:00
parent 5e41d0904f
commit 2923d09091
15 changed files with 35 additions and 82 deletions

View File

@ -100,7 +100,6 @@ func Run(s *options.ServerRunOptions) error {
ApplyOptions(s.GenericServerRunOptions). // apply the options selected
ApplyInsecureServingOptions(s.InsecureServing).
ApplyAuthenticationOptions(s.Authentication).
ApplyRBACSuperUser(s.Authorization.RBACSuperUser).
ApplySecureServingOptions(s.SecureServing)
if err != nil {
return fmt.Errorf("failed to configure https: %s", err)

View File

@ -82,7 +82,6 @@ func Run(s *options.ServerRunOptions) error {
ApplyOptions(s.GenericServerRunOptions). // apply the options selected
ApplyInsecureServingOptions(s.InsecureServing).
ApplyAuthenticationOptions(s.Authentication).
ApplyRBACSuperUser(s.Authorization.RBACSuperUser).
ApplySecureServingOptions(s.SecureServing)
if err != nil {
return fmt.Errorf("failed to configure https: %s", err)

View File

@ -173,7 +173,6 @@ func NewAuthorizerFromAuthorizationConfig(config AuthorizationConfig) (authorize
config.InformerFactory.RoleBindings().Lister(),
config.InformerFactory.ClusterRoles().Lister(),
config.InformerFactory.ClusterRoleBindings().Lister(),
config.RBACSuperUser,
)
authorizers = append(authorizers, rbacAuthorizer)
default:

View File

@ -100,8 +100,6 @@ type Config struct {
SupportsBasicAuth bool
Authorizer authorizer.Authorizer
AdmissionControl admission.Interface
// TODO(ericchiang): Determine if policy escalation checks should be an admission controller.
AuthorizerRBACSuperUser string
// LoopbackClientConfig is a config for a privileged loopback connection to the API server
LoopbackClientConfig *restclient.Config
@ -311,11 +309,6 @@ func (c *Config) ApplyAuthenticationOptions(o *options.BuiltInAuthenticationOpti
return c
}
func (c *Config) ApplyRBACSuperUser(rbacSuperUser string) *Config {
c.AuthorizerRBACSuperUser = rbacSuperUser
return c
}
// ApplyOptions applies the run options to the method receiver and returns self
func (c *Config) ApplyOptions(options *options.ServerRunOptions) *Config {
if len(options.AuditLogPath) != 0 {

View File

@ -36,7 +36,6 @@ type BuiltInAuthorizationOptions struct {
WebhookConfigFile string
WebhookCacheAuthorizedTTL time.Duration
WebhookCacheUnauthorizedTTL time.Duration
RBACSuperUser string
}
func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions {
@ -72,9 +71,10 @@ func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
"authorization-webhook-cache-unauthorized-ttl", s.WebhookCacheUnauthorizedTTL,
"The duration to cache 'unauthorized' responses from the webhook authorizer. Default is 30s.")
fs.StringVar(&s.RBACSuperUser, "authorization-rbac-super-user", s.RBACSuperUser, ""+
fs.String("authorization-rbac-super-user", "", ""+
"If specified, a username which avoids RBAC authorization checks and role binding "+
"privilege escalation checks, to be used with --authorization-mode=RBAC.")
fs.MarkDeprecated("authorization-rbac-super-user", "Removed during alpha to beta. The 'system:masters' group has privileged access.")
}
@ -90,7 +90,6 @@ func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory info
WebhookConfigFile: s.WebhookConfigFile,
WebhookCacheAuthorizedTTL: s.WebhookCacheAuthorizedTTL,
WebhookCacheUnauthorizedTTL: s.WebhookCacheUnauthorizedTTL,
RBACSuperUser: s.RBACSuperUser,
InformerFactory: informerFactory,
}
}

View File

@ -253,7 +253,7 @@ func (c completedConfig) New() (*Master, error) {
certificatesrest.RESTStorageProvider{},
extensionsrest.RESTStorageProvider{ResourceInterface: thirdparty.NewThirdPartyResourceServer(s, c.StorageFactory)},
policyrest.RESTStorageProvider{},
rbacrest.RESTStorageProvider{AuthorizerRBACSuperUser: c.GenericConfig.AuthorizerRBACSuperUser},
rbacrest.RESTStorageProvider{},
storagerest.RESTStorageProvider{},
}
m.InstallAPIs(c.Config.GenericConfig.APIResourceConfigSource, restOptionsFactory.NewFor, restStorageProviders...)

View File

@ -33,17 +33,14 @@ type Storage struct {
rest.StandardStorage
ruleResolver validation.AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser string
}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver, superUser string) *Storage {
return &Storage{s, ruleResolver, superUser}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver) *Storage {
return &Storage{s, ruleResolver}
}
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Create(ctx, obj)
}
@ -56,7 +53,7 @@ func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, e
}
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Update(ctx, name, obj)
}

View File

@ -33,17 +33,14 @@ type Storage struct {
rest.StandardStorage
ruleResolver validation.AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser string
}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver, superUser string) *Storage {
return &Storage{s, ruleResolver, superUser}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver) *Storage {
return &Storage{s, ruleResolver}
}
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Create(ctx, obj)
}
@ -59,7 +56,7 @@ func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, e
}
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Update(ctx, name, obj)
}

View File

@ -21,7 +21,7 @@ import (
"k8s.io/kubernetes/pkg/auth/user"
)
func EscalationAllowed(ctx api.Context, superUser string) bool {
func EscalationAllowed(ctx api.Context) bool {
u, ok := api.UserFrom(ctx)
if !ok {
// the only way to be without a user is to either have no authenticators by explicitly saying that's your preference
@ -29,10 +29,6 @@ func EscalationAllowed(ctx api.Context, superUser string) bool {
return true
}
// check to see if this subject is allowed to escalate
if len(superUser) != 0 && u.GetName() == superUser {
return true
}
// 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() {

View File

@ -46,9 +46,7 @@ import (
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
)
type RESTStorageProvider struct {
AuthorizerRBACSuperUser string
}
type RESTStorageProvider struct{}
var _ genericapiserver.PostStartHookProvider = RESTStorageProvider{}
@ -83,19 +81,19 @@ func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource genericapis
storage := map[string]rest.Storage{}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("roles")) {
rolesStorage := roleetcd.NewREST(restOptionsGetter(rbac.Resource("roles")))
storage["roles"] = rolepolicybased.NewStorage(rolesStorage, newRuleValidator(), p.AuthorizerRBACSuperUser)
storage["roles"] = rolepolicybased.NewStorage(rolesStorage, newRuleValidator())
}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("rolebindings")) {
roleBindingsStorage := rolebindingetcd.NewREST(restOptionsGetter(rbac.Resource("rolebindings")))
storage["rolebindings"] = rolebindingpolicybased.NewStorage(roleBindingsStorage, newRuleValidator(), p.AuthorizerRBACSuperUser)
storage["rolebindings"] = rolebindingpolicybased.NewStorage(roleBindingsStorage, newRuleValidator())
}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("clusterroles")) {
clusterRolesStorage := clusterroleetcd.NewREST(restOptionsGetter(rbac.Resource("clusterroles")))
storage["clusterroles"] = clusterrolepolicybased.NewStorage(clusterRolesStorage, newRuleValidator(), p.AuthorizerRBACSuperUser)
storage["clusterroles"] = clusterrolepolicybased.NewStorage(clusterRolesStorage, newRuleValidator())
}
if apiResourceConfigSource.ResourceEnabled(version.WithResource("clusterrolebindings")) {
clusterRoleBindingsStorage := clusterrolebindingetcd.NewREST(restOptionsGetter(rbac.Resource("clusterrolebindings")))
storage["clusterrolebindings"] = clusterrolebindingpolicybased.NewStorage(clusterRoleBindingsStorage, newRuleValidator(), p.AuthorizerRBACSuperUser)
storage["clusterrolebindings"] = clusterrolebindingpolicybased.NewStorage(clusterRoleBindingsStorage, newRuleValidator())
}
return storage
}

View File

@ -33,17 +33,14 @@ type Storage struct {
rest.StandardStorage
ruleResolver validation.AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser string
}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver, superUser string) *Storage {
return &Storage{s, ruleResolver, superUser}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver) *Storage {
return &Storage{s, ruleResolver}
}
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Create(ctx, obj)
}
@ -56,7 +53,7 @@ func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, e
}
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Update(ctx, name, obj)
}

View File

@ -33,17 +33,14 @@ type Storage struct {
rest.StandardStorage
ruleResolver validation.AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser string
}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver, superUser string) *Storage {
return &Storage{s, ruleResolver, superUser}
func NewStorage(s rest.StandardStorage, ruleResolver validation.AuthorizationRuleResolver) *Storage {
return &Storage{s, ruleResolver}
}
func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Create(ctx, obj)
}
@ -59,7 +56,7 @@ func (s *Storage) Create(ctx api.Context, obj runtime.Object) (runtime.Object, e
}
func (s *Storage) Update(ctx api.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
if rbacregistry.EscalationAllowed(ctx, s.superUser) {
if rbacregistry.EscalationAllowed(ctx) {
return s.StandardStorage.Update(ctx, name, obj)
}

View File

@ -33,16 +33,10 @@ type RequestToRuleMapper interface {
}
type RBACAuthorizer struct {
superUser string
authorizationRuleResolver RequestToRuleMapper
}
func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (bool, string, error) {
if r.superUser != "" && requestAttributes.GetUser() != nil && requestAttributes.GetUser().GetName() == r.superUser {
return true, "", nil
}
rules, ruleResolutionError := r.authorizationRuleResolver.RulesFor(requestAttributes.GetUser(), requestAttributes.GetNamespace())
if RulesAllow(requestAttributes, rules...) {
return true, "", nil
@ -51,9 +45,8 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (boo
return false, "", ruleResolutionError
}
func New(roles validation.RoleGetter, roleBindings validation.RoleBindingLister, clusterRoles validation.ClusterRoleGetter, clusterRoleBindings validation.ClusterRoleBindingLister, superUser string) *RBACAuthorizer {
func New(roles validation.RoleGetter, roleBindings validation.RoleBindingLister, clusterRoles validation.ClusterRoleGetter, clusterRoleBindings validation.ClusterRoleBindingLister) *RBACAuthorizer {
authorizer := &RBACAuthorizer{
superUser: superUser,
authorizationRuleResolver: validation.NewDefaultRuleResolver(
roles, roleBindings, clusterRoles, clusterRoleBindings,
),

View File

@ -122,8 +122,6 @@ func TestAuthorizer(t *testing.T) {
clusterRoles []*rbac.ClusterRole
clusterRoleBindings []*rbac.ClusterRoleBinding
superUser string
shouldPass []authorizer.Attributes
shouldFail []authorizer.Attributes
}{
@ -222,7 +220,7 @@ func TestAuthorizer(t *testing.T) {
}
for i, tt := range tests {
ruleResolver, _ := validation.NewTestRuleResolver(tt.roles, tt.roleBindings, tt.clusterRoles, tt.clusterRoleBindings)
a := RBACAuthorizer{tt.superUser, ruleResolver}
a := RBACAuthorizer{ruleResolver}
for _, attr := range tt.shouldPass {
if authorized, _, _ := a.Authorize(attr); !authorized {
t.Errorf("case %d: incorrectly restricted %s", i, attr)

View File

@ -19,7 +19,6 @@ limitations under the License.
package auth
import (
"errors"
"fmt"
"io"
"io/ioutil"
@ -38,7 +37,6 @@ import (
"k8s.io/kubernetes/pkg/auth/authenticator"
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/user"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/transport"
@ -53,18 +51,13 @@ import (
"k8s.io/kubernetes/pkg/registry/rbac/rolebinding"
rolebindingetcd "k8s.io/kubernetes/pkg/registry/rbac/rolebinding/etcd"
"k8s.io/kubernetes/pkg/watch"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/anytoken"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
"k8s.io/kubernetes/test/integration/framework"
)
func newFakeAuthenticator() authenticator.Request {
return bearertoken.New(authenticator.TokenFunc(func(token string) (user.Info, bool, error) {
if token == "" {
return nil, false, errors.New("no bearer token found")
}
// Set the bearer token as the user name.
return &user.DefaultInfo{Name: token, UID: token}, true, nil
}))
return bearertoken.New(anytoken.AnyTokenAuthenticator{})
}
func clientForUser(user string) *http.Client {
@ -82,7 +75,7 @@ func clientsetForUser(user string, config *restclient.Config) clientset.Interfac
return clientset.NewForConfigOrDie(&configCopy)
}
func newRBACAuthorizer(t *testing.T, superUser string, config *master.Config) authorizer.Authorizer {
func newRBACAuthorizer(t *testing.T, config *master.Config) authorizer.Authorizer {
newRESTOptions := func(resource string) generic.RESTOptions {
storageConfig, err := config.StorageFactory.NewConfig(rbacapi.Resource(resource))
if err != nil {
@ -95,7 +88,7 @@ func newRBACAuthorizer(t *testing.T, superUser string, config *master.Config) au
roleBindingRegistry := rolebinding.AuthorizerAdapter{Registry: rolebinding.NewRegistry(rolebindingetcd.NewREST(newRESTOptions("rolebindings")))}
clusterRoleRegistry := clusterrole.AuthorizerAdapter{Registry: clusterrole.NewRegistry(clusterroleetcd.NewREST(newRESTOptions("clusterroles")))}
clusterRoleBindingRegistry := clusterrolebinding.AuthorizerAdapter{Registry: clusterrolebinding.NewRegistry(clusterrolebindingetcd.NewREST(newRESTOptions("clusterrolebindings")))}
return rbac.New(roleRegistry, roleBindingRegistry, clusterRoleRegistry, clusterRoleBindingRegistry, superUser)
return rbac.New(roleRegistry, roleBindingRegistry, clusterRoleRegistry, clusterRoleBindingRegistry)
}
// bootstrapRoles are a set of RBAC roles which will be populated before the test.
@ -240,7 +233,7 @@ var (
)
func TestRBAC(t *testing.T) {
superUser := "admin"
superUser := "admin/system:masters"
tests := []struct {
bootstrapRoles bootstrapRoles
@ -339,9 +332,8 @@ func TestRBAC(t *testing.T) {
for i, tc := range tests {
// Create an API Server.
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(t, superUser, masterConfig)
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(t, masterConfig)
masterConfig.GenericConfig.Authenticator = newFakeAuthenticator()
masterConfig.GenericConfig.AuthorizerRBACSuperUser = superUser
_, s := framework.RunAMaster(masterConfig)
defer s.Close()
@ -435,12 +427,11 @@ func TestRBAC(t *testing.T) {
}
func TestBootstrapping(t *testing.T) {
superUser := "admin"
superUser := "admin/system:masters"
masterConfig := framework.NewIntegrationTestMasterConfig()
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(t, superUser, masterConfig)
masterConfig.GenericConfig.Authorizer = newRBACAuthorizer(t, masterConfig)
masterConfig.GenericConfig.Authenticator = newFakeAuthenticator()
masterConfig.GenericConfig.AuthorizerRBACSuperUser = superUser
_, s := framework.RunAMaster(masterConfig)
defer s.Close()