Merge pull request #41184 from liggitt/subject-apigroup

Automatic merge from submit-queue (batch tested with PRs 41357, 41178, 41280, 41184, 41278)

Switch RBAC subject apiVersion to apiGroup in v1beta1

Referencing a subject from an RBAC role binding, the API group and kind of the subject is needed to fully-qualify the reference.

The version is not, and adds complexity around re-writing the reference when returning the binding from different versions of the API, and when reconciling subjects.

This PR:
* v1beta1: change the subject `apiVersion` field to `apiGroup` (to match roleRef)
* v1alpha1: convert apiVersion to apiGroup for backwards compatibility
* all versions: add defaulting for the three allowed subject kinds
* all versions: add validation to the field so we can count on the data in etcd being good until we decide to relax the apiGroup restriction

```release-note
RBAC `v1beta1` RoleBinding/ClusterRoleBinding subjects changed `apiVersion` to `apiGroup` to fully-qualify a subject. ServiceAccount subjects default to an apiGroup of `""`, User and Group subjects default to an apiGroup of `"rbac.authorization.k8s.io"`.
```

@deads2k @kubernetes/sig-auth-api-reviews @kubernetes/sig-auth-pr-reviews
This commit is contained in:
Kubernetes Submit Queue 2017-02-13 21:07:10 -08:00 committed by GitHub
commit 1f4e2efc5b
36 changed files with 356 additions and 173 deletions

View File

@ -42731,7 +42731,7 @@
],
"properties": {
"apiVersion": {
"description": "APIVersion holds the API group and version of the referenced object.",
"description": "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects.",
"type": "string"
},
"kind": {
@ -43102,8 +43102,8 @@
"name"
],
"properties": {
"apiVersion": {
"description": "APIVersion holds the API group and version of the referenced object.",
"apiGroup": {
"description": "APIGroup holds the API group of the referenced subject. Defaults to \"\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io\" for User and Group subjects.",
"type": "string"
},
"kind": {

View File

@ -2924,7 +2924,7 @@
},
"apiVersion": {
"type": "string",
"description": "APIVersion holds the API group and version of the referenced object."
"description": "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects."
},
"name": {
"type": "string",

View File

@ -2922,9 +2922,9 @@
"type": "string",
"description": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error."
},
"apiVersion": {
"apiGroup": {
"type": "string",
"description": "APIVersion holds the API group and version of the referenced object."
"description": "APIGroup holds the API group of the referenced subject. Defaults to \"\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io\" for User and Group subjects."
},
"name": {
"type": "string",

View File

@ -9,6 +9,6 @@ roleRef:
kind: ClusterRole
name: node-proxy
subjects:
- apiVersion: rbac/v1beta1
- apiGroup: rbac.authorization.k8s.io
kind: User
name: kube-apiserver

View File

@ -802,7 +802,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">apiVersion</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion holds the API group and version of the referenced object.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion holds the API group and version of the referenced subject. Defaults to "v1" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io/v1alpha1" for User and Group subjects.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
@ -1737,7 +1737,7 @@ Examples:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-01-25 20:39:16 UTC
Last updated 2017-02-13 18:31:15 UTC
</div>
</div>
</body>

View File

@ -1302,8 +1302,8 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">apiVersion</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIVersion holds the API group and version of the referenced object.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apiGroup</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
@ -1737,7 +1737,7 @@ Examples:<br>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2017-01-25 20:39:12 UTC
Last updated 2017-02-13 18:31:09 UTC
</div>
</div>
</body>

View File

@ -718,10 +718,10 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
},
Subjects: []rbacv1beta1.Subject{
{
Kind: "ServiceAccount",
APIVersion: "",
Name: "federation-controller-manager",
Namespace: "federation-system",
Kind: "ServiceAccount",
APIGroup: "",
Name: "federation-controller-manager",
Namespace: "federation-system",
},
},
RoleRef: rbacv1beta1.RoleRef{

View File

@ -590,6 +590,23 @@ func rbacFuncs(t apitesting.TestingCommon) []interface{} {
r.APIGroup = rbac.GroupName
}
},
func(r *rbac.Subject, c fuzz.Continue) {
switch c.Int31n(3) {
case 0:
r.Kind = rbac.ServiceAccountKind
r.APIGroup = ""
c.FuzzNoCustom(&r.Name)
c.FuzzNoCustom(&r.Namespace)
case 1:
r.Kind = rbac.UserKind
r.APIGroup = rbac.GroupName
c.FuzzNoCustom(&r.Name)
case 2:
r.Kind = rbac.GroupKind
r.APIGroup = rbac.GroupName
c.FuzzNoCustom(&r.Name)
}
},
}
}

View File

@ -220,14 +220,14 @@ func NewClusterBinding(clusterRoleName string) *ClusterRoleBindingBuilder {
func (r *ClusterRoleBindingBuilder) Groups(groups ...string) *ClusterRoleBindingBuilder {
for _, group := range groups {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: GroupKind, Name: group})
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: GroupKind, APIGroup: GroupName, Name: group})
}
return r
}
func (r *ClusterRoleBindingBuilder) Users(users ...string) *ClusterRoleBindingBuilder {
for _, user := range users {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: UserKind, Name: user})
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: UserKind, APIGroup: GroupName, Name: user})
}
return r
}

View File

@ -63,9 +63,10 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string
// APIVersion holds the API group and version of the referenced object. For non-object references such as "Group" and "User" this is
// expected to be API version of this API group. For example, "rbac/v1alpha1".
APIVersion string
// APIGroup holds the API group of the referenced subject.
// Defaults to "" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
APIGroup string
// Name of the object being referenced.
Name string
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty

View File

@ -18,6 +18,7 @@ package v1alpha1
import (
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime/schema"
api "k8s.io/kubernetes/pkg/apis/rbac"
)
@ -30,13 +31,51 @@ func Convert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *api.Subject, s c
return err
}
// specifically set the APIGroup for the three subjects recognized in v1alpha1
switch {
case in.Kind == ServiceAccountKind:
out.APIGroup = ""
case in.Kind == UserKind:
out.APIGroup = GroupName
case in.Kind == GroupKind:
out.APIGroup = GroupName
default:
// For unrecognized kinds, use the group portion of the APIVersion if we can get it
if gv, err := schema.ParseGroupVersion(in.APIVersion); err == nil {
out.APIGroup = gv.Group
}
}
// User * in v1alpha1 will only match all authenticated users
// This is only for compatibility with old RBAC bindings
// Special treatment for * should not be included in v1beta1
if out.Kind == UserKind && out.Name == "*" {
if out.Kind == UserKind && out.APIGroup == GroupName && out.Name == "*" {
out.Kind = GroupKind
out.Name = allAuthenticated
}
return nil
}
func Convert_rbac_Subject_To_v1alpha1_Subject(in *api.Subject, out *Subject, s conversion.Scope) error {
if err := autoConvert_rbac_Subject_To_v1alpha1_Subject(in, out, s); err != nil {
return err
}
switch {
case in.Kind == ServiceAccountKind && in.APIGroup == "":
// Make service accounts v1
out.APIVersion = "v1"
case in.Kind == UserKind && in.APIGroup == GroupName:
// users in the rbac API group get v1alpha
out.APIVersion = SchemeGroupVersion.String()
case in.Kind == GroupKind && in.APIGroup == GroupName:
// groups in the rbac API group get v1alpha
out.APIVersion = SchemeGroupVersion.String()
default:
// otherwise, they get an unspecified version of a group
out.APIVersion = schema.GroupVersion{Group: in.APIGroup}.String()
}
return nil
}

View File

@ -34,21 +34,63 @@ func TestConversion(t *testing.T) {
"specific user": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{{Kind: "User", Name: "bob"}},
Subjects: []v1alpha1.Subject{{Kind: "User", APIVersion: v1alpha1.SchemeGroupVersion.String(), Name: "bob"}},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{{Kind: "User", Name: "bob"}},
Subjects: []rbacapi.Subject{{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "bob"}},
},
},
"wildcard user matches authenticated": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{{Kind: "User", Name: "*"}},
Subjects: []v1alpha1.Subject{{Kind: "User", APIVersion: v1alpha1.SchemeGroupVersion.String(), Name: "*"}},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{{Kind: "Group", Name: "system:authenticated"}},
Subjects: []rbacapi.Subject{{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "system:authenticated"}},
},
},
"missing api group gets defaulted": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{
{Kind: "User", Name: "myuser"},
{Kind: "Group", Name: "mygroup"},
{Kind: "ServiceAccount", Name: "mysa", Namespace: "myns"},
},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{
{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "myuser"},
{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "mygroup"},
{Kind: "ServiceAccount", APIGroup: "", Name: "mysa", Namespace: "myns"},
},
},
},
"bad api group gets defaulted": {
old: &v1alpha1.RoleBinding{
RoleRef: v1alpha1.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []v1alpha1.Subject{
{Kind: "User", APIVersion: "rbac", Name: "myuser"},
{Kind: "Group", APIVersion: "rbac", Name: "mygroup"},
{Kind: "ServiceAccount", APIVersion: "rbac", Name: "mysa", Namespace: "myns"},
{Kind: "User", APIVersion: "rbac/v8", Name: "myuser"},
{Kind: "Group", APIVersion: "rbac/v8", Name: "mygroup"},
{Kind: "ServiceAccount", APIVersion: "rbac/v8", Name: "mysa", Namespace: "myns"},
},
},
expected: &rbacapi.RoleBinding{
RoleRef: rbacapi.RoleRef{Name: "foo", APIGroup: v1alpha1.GroupName},
Subjects: []rbacapi.Subject{
{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "myuser"},
{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "mygroup"},
{Kind: "ServiceAccount", APIGroup: "", Name: "mysa", Namespace: "myns"},
{Kind: "User", APIGroup: v1alpha1.GroupName, Name: "myuser"},
{Kind: "Group", APIGroup: v1alpha1.GroupName, Name: "mygroup"},
{Kind: "ServiceAccount", APIGroup: "", Name: "mysa", Namespace: "myns"},
},
},
},
}

View File

@ -25,6 +25,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
return scheme.AddDefaultingFuncs(
SetDefaults_ClusterRoleBinding,
SetDefaults_RoleBinding,
SetDefaults_Subject,
)
}
@ -38,3 +39,15 @@ func SetDefaults_RoleBinding(obj *RoleBinding) {
obj.RoleRef.APIGroup = GroupName
}
}
func SetDefaults_Subject(obj *Subject) {
if len(obj.APIVersion) == 0 {
switch obj.Kind {
case ServiceAccountKind:
obj.APIVersion = "v1"
case UserKind:
obj.APIVersion = SchemeGroupVersion.String()
case GroupKind:
obj.APIVersion = SchemeGroupVersion.String()
}
}
}

View File

@ -184,7 +184,10 @@ message Subject {
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
optional string kind = 1;
// APIVersion holds the API group and version of the referenced object.
// APIVersion holds the API group and version of the referenced subject.
// Defaults to "v1" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io/v1alpha1" for User and Group subjects.
// +k8s:conversion-gen=false
// +optional
optional string apiVersion = 2;

View File

@ -72,7 +72,10 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// APIVersion holds the API group and version of the referenced object.
// APIVersion holds the API group and version of the referenced subject.
// Defaults to "v1" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io/v1alpha1" for User and Group subjects.
// +k8s:conversion-gen=false
// +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt.name=apiVersion"`
// Name of the object being referenced.

View File

@ -136,7 +136,7 @@ func (RoleRef) SwaggerDoc() map[string]string {
var map_Subject = map[string]string{
"": "Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names.",
"kind": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error.",
"apiVersion": "APIVersion holds the API group and version of the referenced object.",
"apiVersion": "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects.",
"name": "Name of the object being referenced.",
"namespace": "Namespace of the referenced object. If the object kind is non-namespace, such as \"User\" or \"Group\", and this value is not empty the Authorizer should report an error.",
}

View File

@ -410,7 +410,7 @@ func Convert_rbac_RoleRef_To_v1alpha1_RoleRef(in *rbac.RoleRef, out *RoleRef, s
func autoConvert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
// INFO: in.APIVersion opted out of conversion generation
out.Name = in.Name
out.Namespace = in.Namespace
return nil
@ -418,12 +418,8 @@ func autoConvert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject
func autoConvert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
// WARNING: in.APIGroup requires manual conversion: does not exist in peer-type
out.Name = in.Name
out.Namespace = in.Namespace
return nil
}
func Convert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
return autoConvert_rbac_Subject_To_v1alpha1_Subject(in, out, s)
}

View File

@ -37,6 +37,10 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) {
SetDefaults_ClusterRoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
}
func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
@ -48,6 +52,10 @@ func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
func SetObjectDefaults_RoleBinding(in *RoleBinding) {
SetDefaults_RoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
}
func SetObjectDefaults_RoleBindingList(in *RoleBindingList) {

View File

@ -25,6 +25,7 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error {
return scheme.AddDefaultingFuncs(
SetDefaults_ClusterRoleBinding,
SetDefaults_RoleBinding,
SetDefaults_Subject,
)
}
@ -38,3 +39,15 @@ func SetDefaults_RoleBinding(obj *RoleBinding) {
obj.RoleRef.APIGroup = GroupName
}
}
func SetDefaults_Subject(obj *Subject) {
if len(obj.APIGroup) == 0 {
switch obj.Kind {
case ServiceAccountKind:
obj.APIGroup = ""
case UserKind:
obj.APIGroup = GroupName
case GroupKind:
obj.APIGroup = GroupName
}
}
}

View File

@ -644,8 +644,8 @@ func (m *Subject) MarshalTo(data []byte) (int, error) {
i += copy(data[i:], m.Kind)
data[i] = 0x12
i++
i = encodeVarintGenerated(data, i, uint64(len(m.APIVersion)))
i += copy(data[i:], m.APIVersion)
i = encodeVarintGenerated(data, i, uint64(len(m.APIGroup)))
i += copy(data[i:], m.APIGroup)
data[i] = 0x1a
i++
i = encodeVarintGenerated(data, i, uint64(len(m.Name)))
@ -869,7 +869,7 @@ func (m *Subject) Size() (n int) {
_ = l
l = len(m.Kind)
n += 1 + l + sovGenerated(uint64(l))
l = len(m.APIVersion)
l = len(m.APIGroup)
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Name)
n += 1 + l + sovGenerated(uint64(l))
@ -1033,7 +1033,7 @@ func (this *Subject) String() string {
}
s := strings.Join([]string{`&Subject{`,
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
`APIVersion:` + fmt.Sprintf("%v", this.APIVersion) + `,`,
`APIGroup:` + fmt.Sprintf("%v", this.APIGroup) + `,`,
`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
`Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`,
`}`,
@ -2548,7 +2548,7 @@ func (m *Subject) Unmarshal(data []byte) error {
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field APIVersion", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
@ -2573,7 +2573,7 @@ func (m *Subject) Unmarshal(data []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.APIVersion = string(data[iNdEx:postIndex])
m.APIGroup = string(data[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
@ -2760,58 +2760,57 @@ var (
)
var fileDescriptorGenerated = []byte{
// 845 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x54, 0x4d, 0x6f, 0x23, 0x45,
0x10, 0x75, 0x27, 0xb6, 0x62, 0x57, 0x88, 0x42, 0x1a, 0x09, 0x0d, 0x39, 0xd8, 0x91, 0x2f, 0x04,
0xb1, 0x3b, 0xb3, 0xc9, 0xae, 0x58, 0x24, 0xc4, 0x61, 0x87, 0x03, 0x8a, 0x58, 0x42, 0xd4, 0x88,
0x15, 0x5f, 0x42, 0xdb, 0x1e, 0xd7, 0x3a, 0x8d, 0xe7, 0x4b, 0xdd, 0x3d, 0x16, 0x2b, 0x38, 0x70,
0xe3, 0xca, 0x9f, 0xe0, 0xc6, 0x09, 0xae, 0x9c, 0x38, 0x05, 0x4e, 0x7b, 0xcc, 0xc9, 0x22, 0xe6,
0x87, 0x80, 0x66, 0xa6, 0xe7, 0xc3, 0xd8, 0x51, 0x4c, 0x90, 0x22, 0x21, 0xed, 0xc9, 0xee, 0xaa,
0xf7, 0xaa, 0xeb, 0x55, 0xf5, 0x3c, 0xb8, 0x3f, 0x7e, 0x53, 0xd9, 0x22, 0x72, 0xc6, 0xc9, 0x00,
0x65, 0x88, 0x1a, 0x95, 0x13, 0x8f, 0x47, 0x0e, 0x8f, 0x85, 0x72, 0xe4, 0x80, 0x7b, 0xce, 0xe4,
0x60, 0x80, 0x9a, 0x1f, 0x38, 0x23, 0x0c, 0x51, 0x72, 0x8d, 0x43, 0x3b, 0x96, 0x91, 0x8e, 0xe8,
0xab, 0x39, 0xd1, 0xae, 0x88, 0x76, 0x3c, 0x1e, 0xd9, 0x29, 0xd1, 0x4e, 0x89, 0xb6, 0x21, 0xee,
0xde, 0x1e, 0x09, 0x7d, 0x9a, 0x0c, 0x6c, 0x2f, 0x0a, 0x9c, 0x51, 0x34, 0x8a, 0x9c, 0x8c, 0x3f,
0x48, 0x9e, 0x64, 0xa7, 0xec, 0x90, 0xfd, 0xcb, 0xeb, 0xee, 0xde, 0x33, 0x0d, 0xf1, 0x58, 0x04,
0xdc, 0x3b, 0x15, 0x21, 0xca, 0xa7, 0x55, 0x4b, 0x01, 0x6a, 0xee, 0x4c, 0x16, 0xba, 0xd9, 0x75,
0x2e, 0x63, 0xc9, 0x24, 0xd4, 0x22, 0xc0, 0x05, 0xc2, 0x1b, 0x57, 0x11, 0x94, 0x77, 0x8a, 0x01,
0x5f, 0xe0, 0xdd, 0xbd, 0x8c, 0x97, 0x68, 0xe1, 0x3b, 0x22, 0xd4, 0x4a, 0xcb, 0x05, 0x52, 0x4d,
0x93, 0x42, 0x39, 0x41, 0x59, 0x09, 0xc2, 0xaf, 0x78, 0x10, 0xfb, 0xb8, 0x4c, 0xd3, 0xad, 0x4b,
0x57, 0xb3, 0x04, 0xdd, 0xff, 0x8d, 0xc0, 0xe6, 0x3b, 0x7e, 0xa2, 0x34, 0x4a, 0x16, 0xf9, 0x48,
0x1f, 0x43, 0x3b, 0x1d, 0xd6, 0x90, 0x6b, 0x6e, 0x91, 0x3d, 0xb2, 0xbf, 0x79, 0x78, 0xc7, 0x36,
0x2b, 0xab, 0xf7, 0x5e, 0x2d, 0x2d, 0x45, 0xdb, 0x93, 0x03, 0xfb, 0x83, 0xc1, 0x97, 0xe8, 0xe9,
0xf7, 0x51, 0x73, 0x97, 0x9e, 0x4d, 0x7b, 0x8d, 0xd9, 0xb4, 0x07, 0x55, 0x8c, 0x95, 0x55, 0xe9,
0xc7, 0xd0, 0x92, 0x89, 0x8f, 0xca, 0x5a, 0xdb, 0x5b, 0xdf, 0xdf, 0x3c, 0xbc, 0x6b, 0xaf, 0xf8,
0x22, 0xec, 0x93, 0xc8, 0x17, 0xde, 0x53, 0x96, 0xf8, 0xe8, 0x6e, 0x99, 0x1b, 0x5a, 0xe9, 0x49,
0xb1, 0xbc, 0x60, 0xff, 0xe7, 0x35, 0xa0, 0x35, 0x2d, 0xae, 0x08, 0x87, 0x22, 0x1c, 0xdd, 0x80,
0xa4, 0x2f, 0xa0, 0xad, 0x92, 0x2c, 0x51, 0xa8, 0xba, 0xb3, 0xb2, 0xaa, 0x0f, 0x73, 0xa2, 0xfb,
0xa2, 0xb9, 0xa1, 0x6d, 0x02, 0x8a, 0x95, 0x35, 0xe9, 0x67, 0xb0, 0x21, 0x23, 0x1f, 0x19, 0x3e,
0xb1, 0xd6, 0xe7, 0x05, 0x5c, 0x59, 0x9e, 0xe5, 0x3c, 0x77, 0xdb, 0x94, 0xdf, 0x30, 0x01, 0x56,
0x54, 0xec, 0xff, 0x40, 0xe0, 0x95, 0xc5, 0xa9, 0xb9, 0x89, 0xf0, 0x87, 0x28, 0xe9, 0x77, 0x04,
0xa8, 0xb7, 0x90, 0x35, 0x73, 0x7c, 0x6b, 0xe5, 0x36, 0x96, 0x5c, 0xb0, 0x6b, 0x3a, 0x5a, 0xb2,
0x32, 0xb6, 0xe4, 0xca, 0xfe, 0x39, 0x81, 0x97, 0x17, 0xa1, 0x0f, 0x85, 0xd2, 0xf4, 0xf3, 0x85,
0x0d, 0xdb, 0xab, 0x6d, 0x38, 0x65, 0x67, 0xfb, 0x2d, 0xa7, 0x5f, 0x44, 0x6a, 0xdb, 0x7d, 0x0c,
0x2d, 0xa1, 0x31, 0x28, 0x56, 0xfb, 0x9f, 0x44, 0x97, 0x0f, 0xf7, 0x28, 0xad, 0xc8, 0xf2, 0xc2,
0xfd, 0xdf, 0x09, 0x6c, 0xd7, 0xc0, 0x37, 0xa0, 0xe9, 0x93, 0x79, 0x4d, 0xf7, 0xae, 0xa5, 0x69,
0xb9, 0x98, 0xbf, 0x08, 0x40, 0xf5, 0xa9, 0xd2, 0x1e, 0xb4, 0x26, 0x28, 0x07, 0xca, 0x22, 0x7b,
0xeb, 0xfb, 0x1d, 0xb7, 0x93, 0xe2, 0x1f, 0xa5, 0x01, 0x96, 0xc7, 0xe9, 0xeb, 0xd0, 0xe1, 0xb1,
0x78, 0x57, 0x46, 0x49, 0x9c, 0xb7, 0xd3, 0x71, 0xb7, 0x66, 0xd3, 0x5e, 0xe7, 0xc1, 0xc9, 0x51,
0x1e, 0x64, 0x55, 0x3e, 0x05, 0x4b, 0x54, 0x51, 0x22, 0x3d, 0x54, 0xd6, 0x7a, 0x05, 0x66, 0x45,
0x90, 0x55, 0x79, 0x7a, 0x1f, 0xb6, 0x8a, 0xc3, 0x31, 0x0f, 0x50, 0x59, 0xcd, 0x8c, 0xb0, 0x33,
0x9b, 0xf6, 0xb6, 0x58, 0x3d, 0xc1, 0xe6, 0x71, 0xf4, 0x6d, 0xd8, 0x0e, 0xa3, 0xb0, 0x80, 0x7c,
0xc4, 0x1e, 0x2a, 0xab, 0x95, 0x51, 0x5f, 0x9a, 0x4d, 0x7b, 0xdb, 0xc7, 0xf3, 0x29, 0xf6, 0x4f,
0x6c, 0xff, 0x1b, 0xd8, 0xa9, 0x79, 0x95, 0xf9, 0x90, 0x46, 0x00, 0x71, 0x19, 0x34, 0x1b, 0xbd,
0x96, 0xf7, 0x95, 0x56, 0x54, 0xc5, 0x58, 0xad, 0x74, 0xff, 0x57, 0x02, 0xcd, 0xff, 0xbd, 0x95,
0xff, 0xb8, 0x06, 0x9b, 0xcf, 0x3d, 0x7c, 0x65, 0x0f, 0x4f, 0x0d, 0xe4, 0x66, 0x4d, 0xf1, 0xda,
0x06, 0x72, 0xb5, 0x1b, 0xfe, 0x42, 0xa0, 0x7d, 0x43, 0x36, 0xc8, 0xe6, 0x55, 0xdc, 0xfe, 0x77,
0x2a, 0x96, 0xb7, 0xff, 0x35, 0x14, 0xfb, 0xa1, 0xb7, 0xa0, 0x5d, 0x58, 0x57, 0xd6, 0x7c, 0xa7,
0x6a, 0xa6, 0x70, 0x37, 0x56, 0x22, 0xe8, 0x1e, 0x34, 0xc7, 0x22, 0x1c, 0x5a, 0x6b, 0x19, 0xf2,
0x05, 0x83, 0x6c, 0xbe, 0x27, 0xc2, 0x21, 0xcb, 0x32, 0x29, 0x22, 0xe4, 0x01, 0x66, 0x0f, 0xa8,
0x86, 0x48, 0x4d, 0x8b, 0x65, 0x99, 0xfe, 0x4f, 0x04, 0x36, 0xcc, 0xe3, 0x2b, 0xeb, 0x91, 0x4b,
0xeb, 0x1d, 0x02, 0xf0, 0x58, 0x3c, 0x42, 0xa9, 0x44, 0x14, 0x9a, 0x7b, 0xcb, 0xaf, 0xe4, 0xc1,
0xc9, 0x91, 0xc9, 0xb0, 0x1a, 0xea, 0xea, 0x1e, 0xa8, 0x03, 0x9d, 0xf4, 0x57, 0xc5, 0xdc, 0x43,
0xab, 0x99, 0xc1, 0x76, 0x0c, 0xac, 0x73, 0x5c, 0x24, 0x58, 0x85, 0x71, 0x5f, 0x3b, 0xbb, 0xe8,
0x36, 0x9e, 0x5d, 0x74, 0x1b, 0xe7, 0x17, 0xdd, 0xc6, 0xb7, 0xb3, 0x2e, 0x39, 0x9b, 0x75, 0xc9,
0xb3, 0x59, 0x97, 0xfc, 0x31, 0xeb, 0x92, 0xef, 0xff, 0xec, 0x36, 0x3e, 0xdd, 0x30, 0x73, 0xff,
0x3b, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x49, 0x60, 0xfe, 0x78, 0x0c, 0x00, 0x00,
// 830 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x54, 0xbf, 0x8f, 0xe3, 0x44,
0x14, 0xce, 0x64, 0x13, 0x6d, 0x3c, 0xcb, 0x2a, 0xec, 0x20, 0x21, 0x93, 0xc2, 0x89, 0xdc, 0xb0,
0x88, 0x3b, 0xfb, 0xf6, 0xee, 0xc4, 0x21, 0x21, 0x0a, 0x4c, 0x81, 0x4e, 0x1c, 0xcb, 0x69, 0x10,
0x88, 0x5f, 0x42, 0x37, 0x71, 0xe6, 0xbc, 0x43, 0xfc, 0x4b, 0x33, 0xe3, 0x88, 0x13, 0x14, 0x74,
0xb4, 0xfc, 0x13, 0x74, 0xd7, 0xd1, 0x52, 0x51, 0x2d, 0x54, 0x57, 0x6e, 0x15, 0xb1, 0xe6, 0x0f,
0x01, 0xd9, 0x1e, 0xff, 0x08, 0x4e, 0xd8, 0xb0, 0x48, 0x91, 0x90, 0xa8, 0x92, 0x79, 0xef, 0xfb,
0xde, 0xbc, 0xef, 0xbd, 0xf1, 0x07, 0xef, 0xcd, 0x5f, 0x17, 0x16, 0x8b, 0xec, 0x79, 0x32, 0xa5,
0x3c, 0xa4, 0x92, 0x0a, 0x3b, 0x9e, 0x7b, 0x36, 0x89, 0x99, 0xb0, 0xf9, 0x94, 0xb8, 0xf6, 0xe2,
0x64, 0x4a, 0x25, 0x39, 0xb1, 0x3d, 0x1a, 0x52, 0x4e, 0x24, 0x9d, 0x59, 0x31, 0x8f, 0x64, 0x84,
0x5e, 0x2e, 0x88, 0x56, 0x4d, 0xb4, 0xe2, 0xb9, 0x67, 0x65, 0x44, 0x2b, 0x23, 0x5a, 0x8a, 0x38,
0xba, 0xe9, 0x31, 0x79, 0x96, 0x4c, 0x2d, 0x37, 0x0a, 0x6c, 0x2f, 0xf2, 0x22, 0x3b, 0xe7, 0x4f,
0x93, 0xc7, 0xf9, 0x29, 0x3f, 0xe4, 0xff, 0x8a, 0xba, 0xa3, 0xbb, 0xaa, 0x21, 0x12, 0xb3, 0x80,
0xb8, 0x67, 0x2c, 0xa4, 0xfc, 0x49, 0xdd, 0x52, 0x40, 0x25, 0xb1, 0x17, 0xad, 0x6e, 0x46, 0xf6,
0x26, 0x16, 0x4f, 0x42, 0xc9, 0x02, 0xda, 0x22, 0xbc, 0x76, 0x15, 0x41, 0xb8, 0x67, 0x34, 0x20,
0x2d, 0xde, 0x9d, 0x4d, 0xbc, 0x44, 0x32, 0xdf, 0x66, 0xa1, 0x14, 0x92, 0xb7, 0x48, 0x0d, 0x4d,
0x82, 0xf2, 0x05, 0xe5, 0xb5, 0x20, 0xfa, 0x15, 0x09, 0x62, 0x9f, 0xae, 0xd3, 0x74, 0x63, 0xe3,
0x6a, 0xd6, 0xa0, 0xcd, 0x5f, 0x00, 0x3c, 0x78, 0xdb, 0x4f, 0x84, 0xa4, 0x1c, 0x47, 0x3e, 0x45,
0x8f, 0xe0, 0x20, 0x1b, 0xd6, 0x8c, 0x48, 0xa2, 0x83, 0x09, 0x38, 0x3e, 0xb8, 0x7d, 0xcb, 0x52,
0x2b, 0x6b, 0xf6, 0x5e, 0x2f, 0x2d, 0x43, 0x5b, 0x8b, 0x13, 0xeb, 0xfd, 0xe9, 0x97, 0xd4, 0x95,
0xef, 0x51, 0x49, 0x1c, 0x74, 0xbe, 0x1c, 0x77, 0xd2, 0xe5, 0x18, 0xd6, 0x31, 0x5c, 0x55, 0x45,
0x1f, 0xc3, 0x3e, 0x4f, 0x7c, 0x2a, 0xf4, 0xee, 0x64, 0xef, 0xf8, 0xe0, 0xf6, 0x1d, 0x6b, 0xcb,
0x17, 0x61, 0x3d, 0x8c, 0x7c, 0xe6, 0x3e, 0xc1, 0x89, 0x4f, 0x9d, 0x43, 0x75, 0x43, 0x3f, 0x3b,
0x09, 0x5c, 0x14, 0x34, 0x7f, 0xec, 0x42, 0xd4, 0xd0, 0xe2, 0xb0, 0x70, 0xc6, 0x42, 0x6f, 0x07,
0x92, 0xbe, 0x80, 0x03, 0x91, 0xe4, 0x89, 0x52, 0xd5, 0xad, 0xad, 0x55, 0x7d, 0x50, 0x10, 0x9d,
0xe7, 0xd5, 0x0d, 0x03, 0x15, 0x10, 0xb8, 0xaa, 0x89, 0x3e, 0x83, 0xfb, 0x3c, 0xf2, 0x29, 0xa6,
0x8f, 0xf5, 0xbd, 0x55, 0x01, 0x57, 0x96, 0xc7, 0x05, 0xcf, 0x19, 0xaa, 0xf2, 0xfb, 0x2a, 0x80,
0xcb, 0x8a, 0xe6, 0x0f, 0x00, 0xbe, 0xd4, 0x9e, 0x9a, 0x93, 0x30, 0x7f, 0x46, 0x39, 0xfa, 0x0e,
0x40, 0xe4, 0xb6, 0xb2, 0x6a, 0x8e, 0x6f, 0x6c, 0xdd, 0xc6, 0x9a, 0x0b, 0x46, 0xaa, 0xa3, 0x35,
0x2b, 0xc3, 0x6b, 0xae, 0x34, 0x2f, 0x00, 0x7c, 0xb1, 0x0d, 0x7d, 0xc0, 0x84, 0x44, 0x9f, 0xb7,
0x36, 0x6c, 0x6d, 0xb7, 0xe1, 0x8c, 0x9d, 0xef, 0xb7, 0x9a, 0x7e, 0x19, 0x69, 0x6c, 0xf7, 0x11,
0xec, 0x33, 0x49, 0x83, 0x72, 0xb5, 0xff, 0x4a, 0x74, 0xf5, 0x70, 0xef, 0x67, 0x15, 0x71, 0x51,
0xd8, 0xfc, 0x15, 0xc0, 0x61, 0x03, 0xbc, 0x03, 0x4d, 0x9f, 0xac, 0x6a, 0xba, 0x7b, 0x2d, 0x4d,
0xeb, 0xc5, 0xfc, 0x01, 0x20, 0xac, 0x3f, 0x55, 0x34, 0x86, 0xfd, 0x05, 0xe5, 0x53, 0xa1, 0x83,
0xc9, 0xde, 0xb1, 0xe6, 0x68, 0x19, 0xfe, 0xa3, 0x2c, 0x80, 0x8b, 0x38, 0x7a, 0x15, 0x6a, 0x24,
0x66, 0xef, 0xf0, 0x28, 0x89, 0x8b, 0x76, 0x34, 0xe7, 0x30, 0x5d, 0x8e, 0xb5, 0xb7, 0x1e, 0xde,
0x2f, 0x82, 0xb8, 0xce, 0x67, 0x60, 0x4e, 0x45, 0x94, 0x70, 0x97, 0x0a, 0x7d, 0xaf, 0x06, 0xe3,
0x32, 0x88, 0xeb, 0x3c, 0xba, 0x07, 0x0f, 0xcb, 0xc3, 0x29, 0x09, 0xa8, 0xd0, 0x7b, 0x39, 0xe1,
0x28, 0x5d, 0x8e, 0x0f, 0x71, 0x33, 0x81, 0x57, 0x71, 0xe8, 0x4d, 0x38, 0x0c, 0xa3, 0xb0, 0x84,
0x7c, 0x88, 0x1f, 0x08, 0xbd, 0x9f, 0x53, 0x5f, 0x48, 0x97, 0xe3, 0xe1, 0xe9, 0x6a, 0x0a, 0xff,
0x15, 0x6b, 0x7e, 0x03, 0x8f, 0x1a, 0x5e, 0xa5, 0x3e, 0x24, 0x0f, 0xc2, 0xb8, 0x0a, 0xaa, 0x8d,
0x5e, 0xcb, 0xfb, 0x2a, 0x2b, 0xaa, 0x63, 0xb8, 0x51, 0xda, 0xfc, 0x19, 0xc0, 0xde, 0x7f, 0xde,
0xca, 0x9f, 0x76, 0xe1, 0xc1, 0xff, 0x1e, 0xbe, 0xb5, 0x87, 0x67, 0x06, 0xb2, 0x5b, 0x53, 0xbc,
0xb6, 0x81, 0x5c, 0xed, 0x86, 0x3f, 0x01, 0x38, 0xd8, 0x91, 0x0d, 0xe2, 0x55, 0x15, 0x37, 0xff,
0x99, 0x8a, 0xf5, 0xed, 0x7f, 0x0d, 0xcb, 0xfd, 0xa0, 0x1b, 0x70, 0x50, 0x5a, 0x57, 0xde, 0xbc,
0x56, 0x37, 0x53, 0xba, 0x1b, 0xae, 0x10, 0x68, 0x02, 0x7b, 0x73, 0x16, 0xce, 0xf4, 0x6e, 0x8e,
0x7c, 0x4e, 0x21, 0x7b, 0xef, 0xb2, 0x70, 0x86, 0xf3, 0x4c, 0x86, 0x08, 0x49, 0x40, 0xf3, 0x07,
0xd4, 0x40, 0x64, 0xa6, 0x85, 0xf3, 0x8c, 0xf9, 0x14, 0xc0, 0x7d, 0xf5, 0xf8, 0xaa, 0x7a, 0x60,
0x63, 0xbd, 0x66, 0x7f, 0xdd, 0x6d, 0xfa, 0xfb, 0xfb, 0xdb, 0x91, 0x0d, 0xb5, 0xec, 0x57, 0xc4,
0xc4, 0xa5, 0x7a, 0x2f, 0x87, 0x1d, 0x29, 0x98, 0x76, 0x5a, 0x26, 0x70, 0x8d, 0x71, 0x5e, 0x39,
0xbf, 0x34, 0x3a, 0xcf, 0x2e, 0x8d, 0xce, 0xc5, 0xa5, 0xd1, 0xf9, 0x36, 0x35, 0xc0, 0x79, 0x6a,
0x80, 0x67, 0xa9, 0x01, 0x7e, 0x4b, 0x0d, 0xf0, 0xfd, 0xef, 0x46, 0xe7, 0xd3, 0x7d, 0x35, 0xf1,
0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x96, 0xa1, 0xd4, 0x72, 0x0c, 0x00, 0x00,
}

View File

@ -183,9 +183,11 @@ message Subject {
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
optional string kind = 1;
// APIVersion holds the API group and version of the referenced object.
// APIGroup holds the API group of the referenced subject.
// Defaults to "" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
// +optional
optional string apiVersion = 2;
optional string apiGroup = 2;
// Name of the object being referenced.
optional string name = 3;

View File

@ -540,7 +540,7 @@ func (x *Subject) CodecEncodeSelf(e *codec1978.Encoder) {
var yyq2 [4]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[1] = x.APIVersion != ""
yyq2[1] = x.APIGroup != ""
yyq2[3] = x.Namespace != ""
var yynn2 int
if yyr2 || yy2arr2 {
@ -581,7 +581,7 @@ func (x *Subject) CodecEncodeSelf(e *codec1978.Encoder) {
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
r.EncodeString(codecSelferC_UTF81234, string(x.APIGroup))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
@ -589,13 +589,13 @@ func (x *Subject) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
if yyq2[1] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("apiVersion"))
r.EncodeString(codecSelferC_UTF81234, string("apiGroup"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
r.EncodeString(codecSelferC_UTF81234, string(x.APIGroup))
}
}
}
@ -716,11 +716,11 @@ func (x *Subject) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
*((*string)(yyv4)) = r.DecodeString()
}
}
case "apiVersion":
case "apiGroup":
if r.TryDecodeAsNil() {
x.APIVersion = ""
x.APIGroup = ""
} else {
yyv6 := &x.APIVersion
yyv6 := &x.APIGroup
yym7 := z.DecBinary()
_ = yym7
if false {
@ -800,9 +800,9 @@ func (x *Subject) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.APIVersion = ""
x.APIGroup = ""
} else {
yyv15 := &x.APIVersion
yyv15 := &x.APIGroup
yym16 := z.DecBinary()
_ = yym16
if false {

View File

@ -71,9 +71,11 @@ type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// APIVersion holds the API group and version of the referenced object.
// APIGroup holds the API group of the referenced subject.
// Defaults to "" for ServiceAccount subjects.
// Defaults to "rbac.authorization.k8s.io" for User and Group subjects.
// +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt.name=apiVersion"`
APIGroup string `json:"apiGroup,omitempty" protobuf:"bytes,2,opt.name=apiGroup"`
// Name of the object being referenced.
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty

View File

@ -134,11 +134,11 @@ func (RoleRef) SwaggerDoc() map[string]string {
}
var map_Subject = map[string]string{
"": "Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names.",
"kind": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error.",
"apiVersion": "APIVersion holds the API group and version of the referenced object.",
"name": "Name of the object being referenced.",
"namespace": "Namespace of the referenced object. If the object kind is non-namespace, such as \"User\" or \"Group\", and this value is not empty the Authorizer should report an error.",
"": "Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names.",
"kind": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error.",
"apiGroup": "APIGroup holds the API group of the referenced subject. Defaults to \"\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io\" for User and Group subjects.",
"name": "Name of the object being referenced.",
"namespace": "Namespace of the referenced object. If the object kind is non-namespace, such as \"User\" or \"Group\", and this value is not empty the Authorizer should report an error.",
}
func (Subject) SwaggerDoc() map[string]string {

View File

@ -330,7 +330,7 @@ func Convert_rbac_RoleRef_To_v1beta1_RoleRef(in *rbac.RoleRef, out *RoleRef, s c
func autoConvert_v1beta1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
out.APIGroup = in.APIGroup
out.Name = in.Name
out.Namespace = in.Namespace
return nil
@ -342,7 +342,7 @@ func Convert_v1beta1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s c
func autoConvert_rbac_Subject_To_v1beta1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
out.APIGroup = in.APIGroup
out.Name = in.Name
out.Namespace = in.Namespace
return nil

View File

@ -37,6 +37,10 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) {
SetDefaults_ClusterRoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
}
func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
@ -48,6 +52,10 @@ func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
func SetObjectDefaults_RoleBinding(in *RoleBinding) {
SetDefaults_RoleBinding(in)
for i := range in.Subjects {
a := &in.Subjects[i]
SetDefaults_Subject(a)
}
}
func SetObjectDefaults_RoleBindingList(in *RoleBindingList) {

View File

@ -201,6 +201,9 @@ func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, msg))
}
}
if len(subject.APIGroup) > 0 {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("apiGroup"), subject.APIGroup, []string{""}))
}
if !isNamespaced && len(subject.Namespace) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
}
@ -210,12 +213,18 @@ func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath
if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "user name cannot be empty"))
}
if subject.APIGroup != rbac.GroupName {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("apiGroup"), subject.APIGroup, []string{rbac.GroupName}))
}
case rbac.GroupKind:
// TODO(ericchiang): What other restrictions on group name are there?
if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "group name cannot be empty"))
}
if subject.APIGroup != rbac.GroupName {
allErrs = append(allErrs, field.NotSupported(fldPath.Child("apiGroup"), subject.APIGroup, []string{rbac.GroupName}))
}
default:
allErrs = append(allErrs, field.NotSupported(fldPath.Child("kind"), subject.Kind, []string{rbac.ServiceAccountKind, rbac.UserKind, rbac.GroupKind}))

View File

@ -30,9 +30,9 @@ func TestValidateClusterRoleBinding(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Name: "master"},
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: "valid"},
Subjects: []rbac.Subject{
{Name: "validsaname", Namespace: "foo", Kind: rbac.ServiceAccountKind},
{Name: "valid@username", Kind: rbac.UserKind},
{Name: "valid@groupname", Kind: rbac.GroupKind},
{Name: "validsaname", APIGroup: "", Namespace: "foo", Kind: rbac.ServiceAccountKind},
{Name: "valid@username", APIGroup: rbac.GroupName, Kind: rbac.UserKind},
{Name: "valid@groupname", APIGroup: rbac.GroupName, Kind: rbac.GroupKind},
},
},
)
@ -145,9 +145,9 @@ func TestValidateRoleBinding(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "master"},
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "Role", Name: "valid"},
Subjects: []rbac.Subject{
{Name: "validsaname", Kind: rbac.ServiceAccountKind},
{Name: "valid@username", Kind: rbac.UserKind},
{Name: "valid@groupname", Kind: rbac.GroupKind},
{Name: "validsaname", APIGroup: "", Kind: rbac.ServiceAccountKind},
{Name: "valid@username", APIGroup: rbac.GroupName, Kind: rbac.UserKind},
{Name: "valid@groupname", APIGroup: rbac.GroupName, Kind: rbac.GroupKind},
},
},
)

View File

@ -11697,7 +11697,7 @@ func GetOpenAPIDefinitions(ref openapi.ReferenceCallback) map[string]openapi.Ope
},
"apiVersion": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion holds the API group and version of the referenced object.",
Description: "APIVersion holds the API group and version of the referenced subject. Defaults to \"v1\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io/v1alpha1\" for User and Group subjects.",
Type: []string{"string"},
Format: "",
},
@ -15314,9 +15314,9 @@ func GetOpenAPIDefinitions(ref openapi.ReferenceCallback) map[string]openapi.Ope
Format: "",
},
},
"apiVersion": {
"apiGroup": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion holds the API group and version of the referenced object.",
Description: "APIGroup holds the API group of the referenced subject. Defaults to \"\" for ServiceAccount subjects. Defaults to \"rbac.authorization.k8s.io\" for User and Group subjects.",
Type: []string{"string"},
Format: "",
},

View File

@ -117,16 +117,16 @@ func (s ClusterRoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, err
}
for _, user := range s.Users {
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{
Kind: rbac.UserKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1",
Name: user,
Kind: rbac.UserKind,
APIGroup: rbac.GroupName,
Name: user,
})
}
for _, group := range s.Groups {
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{
Kind: rbac.GroupKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1",
Name: group,
Kind: rbac.GroupKind,
APIGroup: rbac.GroupName,
Name: group,
})
}
for _, sa := range s.ServiceAccounts {
@ -136,6 +136,7 @@ func (s ClusterRoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, err
}
clusterRoleBinding.Subjects = append(clusterRoleBinding.Subjects, rbac.Subject{
Kind: rbac.ServiceAccountKind,
APIGroup: "",
Namespace: tokens[0],
Name: tokens[1],
})

View File

@ -132,16 +132,16 @@ func (s RoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, error) {
for _, user := range s.Users {
roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{
Kind: rbac.UserKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1",
Name: user,
Kind: rbac.UserKind,
APIGroup: rbac.GroupName,
Name: user,
})
}
for _, group := range s.Groups {
roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{
Kind: rbac.GroupKind,
APIVersion: "rbac.authorization.k8s.io/v1beta1",
Name: group,
Kind: rbac.GroupKind,
APIGroup: rbac.GroupName,
Name: group,
})
}
for _, sa := range s.ServiceAccounts {
@ -151,6 +151,7 @@ func (s RoleBindingGeneratorV1) StructuredGenerate() (runtime.Object, error) {
}
roleBinding.Subjects = append(roleBinding.Subjects, rbac.Subject{
Kind: rbac.ServiceAccountKind,
APIGroup: "",
Namespace: tokens[0],
Name: tokens[1],
})

View File

@ -12,7 +12,8 @@ items:
kind: ClusterRole
name: cluster-admin
subjects:
- kind: Group
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters
- apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
@ -26,9 +27,11 @@ items:
kind: ClusterRole
name: system:basic-user
subjects:
- kind: Group
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated
- kind: Group
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:unauthenticated
- apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
@ -42,9 +45,11 @@ items:
kind: ClusterRole
name: system:discovery
subjects:
- kind: Group
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated
- kind: Group
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:unauthenticated
- apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
@ -58,7 +63,8 @@ items:
kind: ClusterRole
name: system:kube-controller-manager
subjects:
- kind: User
- apiGroup: rbac.authorization.k8s.io
kind: User
name: system:kube-controller-manager
- apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
@ -72,7 +78,8 @@ items:
kind: ClusterRole
name: system:node
subjects:
- kind: Group
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes
- apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
@ -86,7 +93,8 @@ items:
kind: ClusterRole
name: system:node-proxier
subjects:
- kind: User
- apiGroup: rbac.authorization.k8s.io
kind: User
name: system:kube-proxy
kind: List
metadata: {}

View File

@ -64,6 +64,15 @@ func newClusterRoleBinding(roleName string, subjects ...string) *rbac.ClusterRol
for i, subject := range subjects {
split := strings.SplitN(subject, ":", 2)
r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1]
switch r.Subjects[i].Kind {
case rbac.ServiceAccountKind:
r.Subjects[i].APIGroup = ""
case rbac.UserKind, rbac.GroupKind:
r.Subjects[i].APIGroup = rbac.GroupName
default:
panic(fmt.Errorf("invalid kind %s", r.Subjects[i].Kind))
}
}
return r
}
@ -82,6 +91,15 @@ func newRoleBinding(namespace, roleName string, bindType uint16, subjects ...str
for i, subject := range subjects {
split := strings.SplitN(subject, ":", 2)
r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1]
switch r.Subjects[i].Kind {
case rbac.ServiceAccountKind:
r.Subjects[i].APIGroup = ""
case rbac.UserKind, rbac.GroupKind:
r.Subjects[i].APIGroup = rbac.GroupName
default:
panic(fmt.Errorf("invalid kind %s", r.Subjects[i].Kind))
}
}
return r
}

View File

@ -54,9 +54,9 @@ func NewSubjectAccessEvaluator(roles rbacregistryvalidation.RoleGetter, roleBind
// AllowedSubjects returns the subjects that can perform an action and any errors encountered while computing the list.
// It is possible to have both subjects and errors returned if some rolebindings couldn't be resolved, but others could be.
func (r *SubjectAccessEvaluator) AllowedSubjects(requestAttributes authorizer.Attributes) ([]rbac.Subject, error) {
subjects := []rbac.Subject{{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup}}
subjects := []rbac.Subject{{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup}}
if len(r.superUser) > 0 {
subjects = append(subjects, rbac.Subject{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: r.superUser})
subjects = append(subjects, rbac.Subject{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: r.superUser})
}
errorlist := []error{}

View File

@ -58,29 +58,29 @@ func TestSubjectLocator(t *testing.T) {
{
&defaultAttributes{"", "", "get", "Pods", "", "ns1", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"},
{Kind: rbac.UserKind, Name: "admin"},
{Kind: rbac.GroupKind, Name: "admins"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "admins"},
},
},
{
// cluster role matches star in namespace
&defaultAttributes{"", "", "*", "Pods", "", "*", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
},
},
{
// empty ns
&defaultAttributes{"", "", "*", "Pods", "", "", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
},
},
},
@ -104,32 +104,32 @@ func TestSubjectLocator(t *testing.T) {
{
&defaultAttributes{"", "", "get", "Pods", "", "ns1", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: "foo"},
{Kind: rbac.UserKind, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"},
{Kind: rbac.UserKind, Name: "admin"},
{Kind: rbac.GroupKind, Name: "admins"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "admins"},
},
},
{
// verb matchies correctly
&defaultAttributes{"", "", "create", "Pods", "", "ns1", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: "foo"},
{Kind: rbac.UserKind, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
},
},
{
// binding only works in correct ns
&defaultAttributes{"", "", "get", "Pods", "", "ns2", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIVersion: "v1alpha1", Name: "foo"},
{Kind: rbac.UserKind, Name: "super-admin"},
{Kind: rbac.GroupKind, Name: "super-admins"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
},
},
},
@ -144,7 +144,7 @@ func TestSubjectLocator(t *testing.T) {
t.Errorf("case %q %d: error %v", tt.name, i, err)
}
if !reflect.DeepEqual(actualSubjects, action.subjects) {
t.Errorf("case %q %d: expected %v actual %v", tt.name, i, action.subjects, actualSubjects)
t.Errorf("case %q %d: expected\n%v\nactual\n%v", tt.name, i, action.subjects, actualSubjects)
}
}
}

View File

@ -181,7 +181,7 @@ var (
"name": "write-jobs"
},
"subjects": [{
"apiVersion": "rbac/v1alpha1",
"apiGroup": "rbac.authorization.k8s.io",
"kind": "User",
"name": "admin"
}]