Convert user/group * to match authenticated users only in ABAC

This commit is contained in:
Jordan Liggitt 2016-12-19 09:25:51 -05:00
parent 034571ce3c
commit 742ef34484
No known key found for this signature in database
GPG Key ID: 24E7ADF9A3B42012
12 changed files with 332 additions and 73 deletions

View File

@ -75,6 +75,7 @@ pkg/api/v1
pkg/api/v1/service
pkg/apimachinery
pkg/apis/abac/v0
pkg/apis/abac/v1beta1
pkg/apis/apps/install
pkg/apis/authentication.k8s.io/install
pkg/apis/authentication/install

View File

@ -19,6 +19,7 @@ go_library(
deps = [
"//pkg/apis/abac:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/conversion:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/runtime/schema:go_default_library",
@ -32,5 +33,6 @@ go_test(
deps = [
"//pkg/apis/abac:go_default_library",
"//pkg/apis/abac/v0:go_default_library",
"//pkg/auth/user:go_default_library",
],
)

View File

@ -18,6 +18,7 @@ package v0
import (
api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/runtime"
)
@ -32,9 +33,14 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
out.Spec.Resource = in.Resource
out.Spec.Readonly = in.Readonly
// In v0, unspecified user and group matches all subjects
// In v0, unspecified user and group matches all authenticated subjects
if len(in.User) == 0 && len(in.Group) == 0 {
out.Spec.User = "*"
out.Spec.Group = user.AllAuthenticated
}
// In v0, user or group of * matches all authenticated subjects
if in.User == "*" || in.Group == "*" {
out.Spec.Group = user.AllAuthenticated
out.Spec.User = ""
}
// In v0, leaving namespace empty matches all namespaces

View File

@ -22,9 +22,10 @@ import (
api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/apis/abac/v0"
"k8s.io/kubernetes/pkg/auth/user"
)
func TestConversion(t *testing.T) {
func TestV0Conversion(t *testing.T) {
testcases := map[string]struct {
old *v0.Policy
expected *api.Policy
@ -32,7 +33,7 @@ func TestConversion(t *testing.T) {
// a completely empty policy rule allows everything to all users
"empty": {
old: &v0.Policy{},
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
},
// specifying a user is preserved
@ -47,22 +48,32 @@ func TestConversion(t *testing.T) {
expected: &api.Policy{Spec: api.PolicySpec{Group: "mygroup", Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
},
// specifying * for user or group maps to all authenticated subjects
"* user": {
old: &v0.Policy{User: "*"},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
},
"* group": {
old: &v0.Policy{Group: "*"},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "*", Namespace: "*", Resource: "*", APIGroup: "*"}},
},
// specifying a namespace removes the * match on non-resource path
"namespace": {
old: &v0.Policy{Namespace: "myns"},
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "*", APIGroup: "*"}},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "*", APIGroup: "*"}},
},
// specifying a resource removes the * match on non-resource path
"resource": {
old: &v0.Policy{Resource: "myresource"},
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "", Namespace: "*", Resource: "myresource", APIGroup: "*"}},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "", Namespace: "*", Resource: "myresource", APIGroup: "*"}},
},
// specifying a namespace+resource removes the * match on non-resource path
"namespace+resource": {
old: &v0.Policy{Namespace: "myns", Resource: "myresource"},
expected: &api.Policy{Spec: api.PolicySpec{User: "*", Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "myresource", APIGroup: "*"}},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated, Readonly: false, NonResourcePath: "", Namespace: "myns", Resource: "myresource", APIGroup: "*"}},
},
}
for k, tc := range testcases {

View File

@ -5,19 +5,37 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"conversion.go",
"doc.go",
"register.go",
"types.go",
"zz_generated.conversion.go",
"zz_generated.deepcopy.go",
],
tags = ["automanaged"],
deps = [
"//pkg/apis/abac:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/conversion:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/runtime/schema:go_default_library",
],
)
go_test(
name = "go_default_xtest",
srcs = ["conversion_test.go"],
tags = ["automanaged"],
deps = [
"//pkg/apis/abac:go_default_library",
"//pkg/apis/abac/v1beta1:go_default_library",
"//pkg/auth/user:go_default_library",
],
)

View File

@ -0,0 +1,43 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/runtime"
)
func addConversionFuncs(scheme *runtime.Scheme) error {
return scheme.AddConversionFuncs(
func(in *Policy, out *api.Policy, s conversion.Scope) error {
// Begin by copying all fields
if err := autoConvert_v1beta1_Policy_To_abac_Policy(in, out, s); err != nil {
return err
}
// In v1beta1, * user or group maps to all authenticated subjects
if in.Spec.User == "*" || in.Spec.Group == "*" {
out.Spec.Group = user.AllAuthenticated
out.Spec.User = ""
}
return nil
},
)
}

View File

@ -0,0 +1,64 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1_test
import (
"reflect"
"testing"
api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/apis/abac/v1beta1"
"k8s.io/kubernetes/pkg/auth/user"
)
func TestV1Beta1Conversion(t *testing.T) {
testcases := map[string]struct {
old *v1beta1.Policy
expected *api.Policy
}{
// specifying a user is preserved
"user": {
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{User: "bob"}},
expected: &api.Policy{Spec: api.PolicySpec{User: "bob"}},
},
// specifying a group is preserved
"group": {
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{Group: "mygroup"}},
expected: &api.Policy{Spec: api.PolicySpec{Group: "mygroup"}},
},
// specifying * for user or group maps to all authenticated subjects
"* user": {
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{User: "*"}},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated}},
},
"* group": {
old: &v1beta1.Policy{Spec: v1beta1.PolicySpec{Group: "*"}},
expected: &api.Policy{Spec: api.PolicySpec{Group: user.AllAuthenticated}},
},
}
for k, tc := range testcases {
internal := &api.Policy{}
if err := api.Scheme.Convert(tc.old, internal, nil); err != nil {
t.Errorf("%s: unexpected error: %v", k, err)
}
if !reflect.DeepEqual(internal, tc.expected) {
t.Errorf("%s: expected\n\t%#v, got \n\t%#v", k, tc.expected, internal)
}
}
}

View File

@ -33,10 +33,14 @@ func init() {
// Programmer error.
panic(err)
}
if err := addConversionFuncs(api.Scheme); err != nil {
// Programmer error.
panic(err)
}
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addConversionFuncs)
AddToScheme = SchemeBuilder.AddToScheme
)

View File

@ -73,9 +73,11 @@ func TestAuthorizeV0(t *testing.T) {
t.Fatalf("unable to read policy file: %v", err)
}
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1"}
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3"}
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5"}
authenticatedGroup := []string{user.AllAuthenticated}
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1", Groups: authenticatedGroup}
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3", Groups: authenticatedGroup}
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5", Groups: authenticatedGroup}
testCases := []struct {
User user.DefaultInfo
@ -163,12 +165,14 @@ func TestAuthorizeV1beta1(t *testing.T) {
t.Fatalf("unable to read policy file: %v", err)
}
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1"}
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3"}
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5"}
uDebbie := user.DefaultInfo{Name: "debbie", UID: "uid6"}
uNoResource := user.DefaultInfo{Name: "noresource", UID: "uid7"}
uAPIGroup := user.DefaultInfo{Name: "apigroupuser", UID: "uid8"}
authenticatedGroup := []string{user.AllAuthenticated}
uScheduler := user.DefaultInfo{Name: "scheduler", UID: "uid1", Groups: authenticatedGroup}
uAlice := user.DefaultInfo{Name: "alice", UID: "uid3", Groups: authenticatedGroup}
uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5", Groups: authenticatedGroup}
uDebbie := user.DefaultInfo{Name: "debbie", UID: "uid6", Groups: authenticatedGroup}
uNoResource := user.DefaultInfo{Name: "noresource", UID: "uid7", Groups: authenticatedGroup}
uAPIGroup := user.DefaultInfo{Name: "apigroupuser", UID: "uid8", Groups: authenticatedGroup}
testCases := []struct {
User user.DefaultInfo
@ -263,16 +267,32 @@ func TestSubjectMatches(t *testing.T) {
Policy runtime.Object
ExpectMatch bool
}{
"v0 empty policy matches unauthed user": {
User: user.DefaultInfo{},
"v0 empty policy does not match unauthed user": {
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v0.Policy{
User: "",
Group: "",
},
ExpectMatch: true,
ExpectMatch: false,
},
"v0 * user policy does not match unauthed user": {
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v0.Policy{
User: "*",
Group: "",
},
ExpectMatch: false,
},
"v0 * group policy does not match unauthed user": {
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v0.Policy{
User: "",
Group: "*",
},
ExpectMatch: false,
},
"v0 empty policy matches authed user": {
User: user.DefaultInfo{Name: "Foo"},
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
Policy: &v0.Policy{
User: "",
Group: "",
@ -280,7 +300,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: true,
},
"v0 empty policy matches authed user with groups": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "",
Group: "",
@ -289,7 +309,7 @@ func TestSubjectMatches(t *testing.T) {
},
"v0 user policy does not match unauthed user": {
User: user.DefaultInfo{},
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v0.Policy{
User: "Foo",
Group: "",
@ -297,7 +317,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 user policy does not match different user": {
User: user.DefaultInfo{Name: "Bar"},
User: user.DefaultInfo{Name: "Bar", Groups: []string{user.AllAuthenticated}},
Policy: &v0.Policy{
User: "Foo",
Group: "",
@ -305,7 +325,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 user policy is case-sensitive": {
User: user.DefaultInfo{Name: "foo"},
User: user.DefaultInfo{Name: "foo", Groups: []string{user.AllAuthenticated}},
Policy: &v0.Policy{
User: "Foo",
Group: "",
@ -313,7 +333,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 user policy does not match substring": {
User: user.DefaultInfo{Name: "FooBar"},
User: user.DefaultInfo{Name: "FooBar", Groups: []string{user.AllAuthenticated}},
Policy: &v0.Policy{
User: "Foo",
Group: "",
@ -321,7 +341,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 user policy matches username": {
User: user.DefaultInfo{Name: "Foo"},
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
Policy: &v0.Policy{
User: "Foo",
Group: "",
@ -330,7 +350,7 @@ func TestSubjectMatches(t *testing.T) {
},
"v0 group policy does not match unauthed user": {
User: user.DefaultInfo{},
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v0.Policy{
User: "",
Group: "Foo",
@ -338,7 +358,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 group policy does not match user in different group": {
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B"}},
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "",
Group: "A",
@ -346,7 +366,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 group policy is case-sensitive": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "",
Group: "b",
@ -354,7 +374,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 group policy does not match substring": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "",
Group: "B",
@ -362,7 +382,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 group policy matches user in group": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "",
Group: "B",
@ -371,7 +391,7 @@ func TestSubjectMatches(t *testing.T) {
},
"v0 user and group policy requires user match": {
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "Foo",
Group: "B",
@ -379,7 +399,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 user and group policy requires group match": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "Foo",
Group: "D",
@ -387,7 +407,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v0 user and group policy matches": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v0.Policy{
User: "Foo",
Group: "B",
@ -396,7 +416,7 @@ func TestSubjectMatches(t *testing.T) {
},
"v1 empty policy does not match unauthed user": {
User: user.DefaultInfo{},
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -405,8 +425,28 @@ func TestSubjectMatches(t *testing.T) {
},
ExpectMatch: false,
},
"v1 * user policy does not match unauthed user": {
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "*",
Group: "",
},
},
ExpectMatch: false,
},
"v1 * group policy does not match unauthed user": {
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
Group: "*",
},
},
ExpectMatch: false,
},
"v1 empty policy does not match authed user": {
User: user.DefaultInfo{Name: "Foo"},
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -416,7 +456,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 empty policy does not match authed user with groups": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"a", "b", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -427,7 +467,7 @@ func TestSubjectMatches(t *testing.T) {
},
"v1 user policy does not match unauthed user": {
User: user.DefaultInfo{},
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -437,7 +477,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 user policy does not match different user": {
User: user.DefaultInfo{Name: "Bar"},
User: user.DefaultInfo{Name: "Bar", Groups: []string{user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -447,7 +487,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 user policy is case-sensitive": {
User: user.DefaultInfo{Name: "foo"},
User: user.DefaultInfo{Name: "foo", Groups: []string{user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -457,7 +497,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 user policy does not match substring": {
User: user.DefaultInfo{Name: "FooBar"},
User: user.DefaultInfo{Name: "FooBar", Groups: []string{user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -467,7 +507,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 user policy matches username": {
User: user.DefaultInfo{Name: "Foo"},
User: user.DefaultInfo{Name: "Foo", Groups: []string{user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -478,7 +518,7 @@ func TestSubjectMatches(t *testing.T) {
},
"v1 group policy does not match unauthed user": {
User: user.DefaultInfo{},
User: user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -488,7 +528,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 group policy does not match user in different group": {
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B"}},
User: user.DefaultInfo{Name: "FooBar", Groups: []string{"B", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -498,7 +538,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 group policy is case-sensitive": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -508,7 +548,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 group policy does not match substring": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "BBB", "C", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -518,7 +558,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 group policy matches user in group": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "",
@ -529,7 +569,7 @@ func TestSubjectMatches(t *testing.T) {
},
"v1 user and group policy requires user match": {
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Bar", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -539,7 +579,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 user and group policy requires group match": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -549,7 +589,7 @@ func TestSubjectMatches(t *testing.T) {
ExpectMatch: false,
},
"v1 user and group policy matches": {
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C"}},
User: user.DefaultInfo{Name: "Foo", Groups: []string{"A", "B", "C", user.AllAuthenticated}},
Policy: &v1beta1.Policy{
Spec: v1beta1.PolicySpec{
User: "Foo",
@ -600,20 +640,18 @@ func TestPolicy(t *testing.T) {
matches bool
name string
}{
// v0
{
policy: &v0.Policy{},
attr: authorizer.AttributesRecord{},
matches: true,
name: "v0 null",
},
// v0 mismatches
{
policy: &v0.Policy{
Readonly: true,
},
attr: authorizer.AttributesRecord{},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Verb: "create",
},
matches: false,
name: "v0 read-only mismatch",
},
@ -623,7 +661,8 @@ func TestPolicy(t *testing.T) {
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "bar",
Name: "bar",
Groups: []string{user.AllAuthenticated},
},
},
matches: false,
@ -634,6 +673,10 @@ func TestPolicy(t *testing.T) {
Resource: "foo",
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Resource: "bar",
ResourceRequest: true,
},
@ -648,7 +691,8 @@ func TestPolicy(t *testing.T) {
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Resource: "foo",
Namespace: "foo",
@ -660,8 +704,14 @@ func TestPolicy(t *testing.T) {
// v0 matches
{
policy: &v0.Policy{},
attr: authorizer.AttributesRecord{ResourceRequest: true},
policy: &v0.Policy{},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
ResourceRequest: true,
},
matches: true,
name: "v0 null resource",
},
@ -670,6 +720,10 @@ func TestPolicy(t *testing.T) {
Readonly: true,
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Verb: "get",
},
matches: true,
@ -681,7 +735,8 @@ func TestPolicy(t *testing.T) {
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
},
matches: true,
@ -692,6 +747,10 @@ func TestPolicy(t *testing.T) {
Resource: "foo",
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Resource: "foo",
ResourceRequest: true,
},
@ -703,6 +762,10 @@ func TestPolicy(t *testing.T) {
{
policy: &v1beta1.Policy{},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
ResourceRequest: true,
},
matches: false,
@ -716,7 +779,8 @@ func TestPolicy(t *testing.T) {
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "bar",
Name: "bar",
Groups: []string{user.AllAuthenticated},
},
ResourceRequest: true,
},
@ -731,6 +795,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
ResourceRequest: true,
},
matches: false,
@ -744,6 +812,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Resource: "bar",
ResourceRequest: true,
},
@ -760,7 +832,8 @@ func TestPolicy(t *testing.T) {
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Namespace: "bar",
Resource: "baz",
@ -777,6 +850,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Path: "/api2",
ResourceRequest: false,
},
@ -791,6 +868,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Path: "/api2/foo",
ResourceRequest: false,
},
@ -807,7 +888,8 @@ func TestPolicy(t *testing.T) {
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
ResourceRequest: true,
},
@ -821,6 +903,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
ResourceRequest: true,
},
matches: true,
@ -835,7 +921,7 @@ func TestPolicy(t *testing.T) {
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{"bar"},
Groups: []string{"bar", user.AllAuthenticated},
},
ResourceRequest: true,
},
@ -851,7 +937,7 @@ func TestPolicy(t *testing.T) {
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{"bar"},
Groups: []string{"bar", user.AllAuthenticated},
},
ResourceRequest: true,
},
@ -866,6 +952,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Verb: "get",
ResourceRequest: true,
},
@ -880,6 +970,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Resource: "foo",
ResourceRequest: true,
},
@ -896,7 +990,8 @@ func TestPolicy(t *testing.T) {
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Namespace: "bar",
Resource: "baz",
@ -913,6 +1008,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Path: "/api",
ResourceRequest: false,
},
@ -927,6 +1026,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Path: "/api",
ResourceRequest: false,
},
@ -941,6 +1044,10 @@ func TestPolicy(t *testing.T) {
},
},
attr: authorizer.AttributesRecord{
User: &user.DefaultInfo{
Name: "foo",
Groups: []string{user.AllAuthenticated},
},
Path: "/api/foo",
ResourceRequest: false,
},

View File

@ -1,4 +1,5 @@
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"*", "nonResourcePath": "*", "readonly": true}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group":"system:authenticated", "nonResourcePath": "*", "readonly": true}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"system:unauthenticated", "nonResourcePath": "*", "readonly": true}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"admin", "namespace": "*", "resource": "*", "apiGroup": "*" }}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"scheduler", "namespace": "*", "resource": "pods", "readonly": true }}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"scheduler", "namespace": "*", "resource": "bindings" }}

View File

@ -46,6 +46,7 @@ import (
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
"k8s.io/kubernetes/pkg/auth/group"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1"
apiserverauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
@ -67,7 +68,7 @@ func getTestTokenAuth() authenticator.Request {
tokenAuthenticator := tokentest.New()
tokenAuthenticator.Tokens[AliceToken] = &user.DefaultInfo{Name: "alice", UID: "1"}
tokenAuthenticator.Tokens[BobToken] = &user.DefaultInfo{Name: "bob", UID: "2"}
return bearertoken.New(tokenAuthenticator)
return group.NewGroupAdder(bearertoken.New(tokenAuthenticator), []string{user.AllAuthenticated})
}
func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) {

View File

@ -559,6 +559,7 @@ k8s.io/kubernetes/pkg/apimachinery,gmarek,1
k8s.io/kubernetes/pkg/apimachinery/announced,kargakis,1
k8s.io/kubernetes/pkg/apimachinery/registered,jlowdermilk,1
k8s.io/kubernetes/pkg/apis/abac/v0,liggitt,0
k8s.io/kubernetes/pkg/apis/abac/v1beta1,liggitt,0
k8s.io/kubernetes/pkg/apis/apps/validation,derekwaynecarr,1
k8s.io/kubernetes/pkg/apis/authorization/validation,erictune,0
k8s.io/kubernetes/pkg/apis/autoscaling/v1,yarntime,0

1 name owner auto-assigned
559 k8s.io/kubernetes/pkg/apimachinery/announced kargakis 1
560 k8s.io/kubernetes/pkg/apimachinery/registered jlowdermilk 1
561 k8s.io/kubernetes/pkg/apis/abac/v0 liggitt 0
562 k8s.io/kubernetes/pkg/apis/abac/v1beta1 liggitt 0
563 k8s.io/kubernetes/pkg/apis/apps/validation derekwaynecarr 1
564 k8s.io/kubernetes/pkg/apis/authorization/validation erictune 0
565 k8s.io/kubernetes/pkg/apis/autoscaling/v1 yarntime 0