diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json
index 5c5acb0728f..cf342869f9e 100644
--- a/api/openapi-spec/swagger.json
+++ b/api/openapi-spec/swagger.json
@@ -80871,6 +80871,13 @@
"io.k8s.api.authentication.v1.TokenReviewSpec": {
"description": "TokenReviewSpec is a description of the token authentication request.",
"properties": {
+ "audiences": {
+ "description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
"token": {
"description": "Token is the opaque bearer token.",
"type": "string"
@@ -80880,6 +80887,13 @@
"io.k8s.api.authentication.v1.TokenReviewStatus": {
"description": "TokenReviewStatus is the result of the token authentication request.",
"properties": {
+ "audiences": {
+ "description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
"authenticated": {
"description": "Authenticated indicates that the token was associated with a known user.",
"type": "boolean"
@@ -80961,6 +80975,13 @@
"io.k8s.api.authentication.v1beta1.TokenReviewSpec": {
"description": "TokenReviewSpec is a description of the token authentication request.",
"properties": {
+ "audiences": {
+ "description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
"token": {
"description": "Token is the opaque bearer token.",
"type": "string"
@@ -80970,6 +80991,13 @@
"io.k8s.api.authentication.v1beta1.TokenReviewStatus": {
"description": "TokenReviewStatus is the result of the token authentication request.",
"properties": {
+ "audiences": {
+ "description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
"authenticated": {
"description": "Authenticated indicates that the token was associated with a known user.",
"type": "boolean"
diff --git a/api/swagger-spec/authentication.k8s.io_v1.json b/api/swagger-spec/authentication.k8s.io_v1.json
index 74e689e0cdc..efdcb2f2263 100644
--- a/api/swagger-spec/authentication.k8s.io_v1.json
+++ b/api/swagger-spec/authentication.k8s.io_v1.json
@@ -395,6 +395,13 @@
"token": {
"type": "string",
"description": "Token is the opaque bearer token."
+ },
+ "audiences": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver."
}
}
},
@@ -410,6 +417,13 @@
"$ref": "v1.UserInfo",
"description": "User is the UserInfo associated with the provided token."
},
+ "audiences": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server."
+ },
"error": {
"type": "string",
"description": "Error indicates that the token couldn't be checked"
diff --git a/api/swagger-spec/authentication.k8s.io_v1beta1.json b/api/swagger-spec/authentication.k8s.io_v1beta1.json
index ab5cf7822dc..a1d29689f5a 100644
--- a/api/swagger-spec/authentication.k8s.io_v1beta1.json
+++ b/api/swagger-spec/authentication.k8s.io_v1beta1.json
@@ -395,6 +395,13 @@
"token": {
"type": "string",
"description": "Token is the opaque bearer token."
+ },
+ "audiences": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver."
}
}
},
@@ -410,6 +417,13 @@
"$ref": "v1beta1.UserInfo",
"description": "User is the UserInfo associated with the provided token."
},
+ "audiences": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server."
+ },
"error": {
"type": "string",
"description": "Error indicates that the token couldn't be checked"
diff --git a/docs/api-reference/authentication.k8s.io/v1/definitions.html b/docs/api-reference/authentication.k8s.io/v1/definitions.html
index f7cf09b9e69..f2964687302 100755
--- a/docs/api-reference/authentication.k8s.io/v1/definitions.html
+++ b/docs/api-reference/authentication.k8s.io/v1/definitions.html
@@ -1053,6 +1053,13 @@ When an object is created, the system will populate this list with the current s
string |
|
+
+audiences |
+Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver. |
+false |
+string array |
+ |
+
@@ -1095,6 +1102,13 @@ When an object is created, the system will populate this list with the current s
|
+audiences |
+Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token’s audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is "true", the token is valid against the audience of the Kubernetes API server. |
+false |
+string array |
+ |
+
+
error |
Error indicates that the token couldn’t be checked |
false |
diff --git a/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html b/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html
index 4ab7aadb51c..4b383c273c5 100755
--- a/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html
+++ b/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html
@@ -567,6 +567,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
string |
|
+
+audiences |
+Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver. |
+false |
+string array |
+ |
+
@@ -1060,6 +1067,13 @@ When an object is created, the system will populate this list with the current s
|
+audiences |
+Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token’s audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is "true", the token is valid against the audience of the Kubernetes API server. |
+false |
+string array |
+ |
+
+
error |
Error indicates that the token couldn’t be checked |
false |
diff --git a/pkg/apis/authentication/types.go b/pkg/apis/authentication/types.go
index deb33cfc198..203bf22bb34 100644
--- a/pkg/apis/authentication/types.go
+++ b/pkg/apis/authentication/types.go
@@ -59,6 +59,12 @@ type TokenReview struct {
type TokenReviewSpec struct {
// Token is the opaque bearer token.
Token string
+ // Audiences is a list of the identifiers that the resource server presented
+ // with the token identifies as. Audience-aware token authenticators will
+ // verify that the token was intended for at least one of the audiences in
+ // this list. If no audiences are provided, the audience will default to the
+ // audience of the Kubernetes apiserver.
+ Audiences []string
}
// TokenReviewStatus is the result of the token authentication request.
@@ -68,6 +74,16 @@ type TokenReviewStatus struct {
Authenticated bool
// User is the UserInfo associated with the provided token.
User UserInfo
+ // Audiences are audience identifiers chosen by the authenticator that are
+ // compatible with both the TokenReview and token. An identifier is any
+ // identifier in the intersection of the TokenReviewSpec audiences and the
+ // token's audiences. A client of the TokenReview API that sets the
+ // spec.audiences field should validate that a compatible audience identifier
+ // is returned in the status.audiences field to ensure that the TokenReview
+ // server is audience aware. If a TokenReview returns an empty
+ // status.audience field where status.authenticated is "true", the token is
+ // valid against the audience of the Kubernetes API server.
+ Audiences []string
// Error indicates that the token couldn't be checked
Error string
}
diff --git a/pkg/apis/authentication/v1/zz_generated.conversion.go b/pkg/apis/authentication/v1/zz_generated.conversion.go
index afa00b1594f..8e95da3274b 100644
--- a/pkg/apis/authentication/v1/zz_generated.conversion.go
+++ b/pkg/apis/authentication/v1/zz_generated.conversion.go
@@ -263,6 +263,7 @@ func Convert_authentication_TokenReview_To_v1_TokenReview(in *authentication.Tok
func autoConvert_v1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1.TokenReviewSpec, out *authentication.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@@ -273,6 +274,7 @@ func Convert_v1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1.TokenRe
func autoConvert_authentication_TokenReviewSpec_To_v1_TokenReviewSpec(in *authentication.TokenReviewSpec, out *v1.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@@ -286,6 +288,7 @@ func autoConvert_v1_TokenReviewStatus_To_authentication_TokenReviewStatus(in *v1
if err := Convert_v1_UserInfo_To_authentication_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}
@@ -300,6 +303,7 @@ func autoConvert_authentication_TokenReviewStatus_To_v1_TokenReviewStatus(in *au
if err := Convert_authentication_UserInfo_To_v1_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}
diff --git a/pkg/apis/authentication/v1beta1/zz_generated.conversion.go b/pkg/apis/authentication/v1beta1/zz_generated.conversion.go
index 97437b18f1a..95d65c5dab3 100644
--- a/pkg/apis/authentication/v1beta1/zz_generated.conversion.go
+++ b/pkg/apis/authentication/v1beta1/zz_generated.conversion.go
@@ -113,6 +113,7 @@ func Convert_authentication_TokenReview_To_v1beta1_TokenReview(in *authenticatio
func autoConvert_v1beta1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1beta1.TokenReviewSpec, out *authentication.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@@ -123,6 +124,7 @@ func Convert_v1beta1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1bet
func autoConvert_authentication_TokenReviewSpec_To_v1beta1_TokenReviewSpec(in *authentication.TokenReviewSpec, out *v1beta1.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@@ -136,6 +138,7 @@ func autoConvert_v1beta1_TokenReviewStatus_To_authentication_TokenReviewStatus(i
if err := Convert_v1beta1_UserInfo_To_authentication_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}
@@ -150,6 +153,7 @@ func autoConvert_authentication_TokenReviewStatus_To_v1beta1_TokenReviewStatus(i
if err := Convert_authentication_UserInfo_To_v1beta1_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
+ out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}
diff --git a/pkg/apis/authentication/zz_generated.deepcopy.go b/pkg/apis/authentication/zz_generated.deepcopy.go
index 2a4cdd07abf..1f485500439 100644
--- a/pkg/apis/authentication/zz_generated.deepcopy.go
+++ b/pkg/apis/authentication/zz_generated.deepcopy.go
@@ -136,7 +136,7 @@ func (in *TokenReview) DeepCopyInto(out *TokenReview) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@@ -162,6 +162,11 @@ func (in *TokenReview) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenReviewSpec) DeepCopyInto(out *TokenReviewSpec) {
*out = *in
+ if in.Audiences != nil {
+ in, out := &in.Audiences, &out.Audiences
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
return
}
@@ -179,6 +184,11 @@ func (in *TokenReviewSpec) DeepCopy() *TokenReviewSpec {
func (in *TokenReviewStatus) DeepCopyInto(out *TokenReviewStatus) {
*out = *in
in.User.DeepCopyInto(&out.User)
+ if in.Audiences != nil {
+ in, out := &in.Audiences, &out.Audiences
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
return
}
diff --git a/pkg/kubeapiserver/authenticator/config.go b/pkg/kubeapiserver/authenticator/config.go
index 359af1afb92..b34e6b8958a 100644
--- a/pkg/kubeapiserver/authenticator/config.go
+++ b/pkg/kubeapiserver/authenticator/config.go
@@ -179,7 +179,7 @@ func (config Config) New() (authenticator.Request, *spec.SecurityDefinitions, er
tokenAuthenticators = append(tokenAuthenticators, oidcAuth)
}
if len(config.WebhookTokenAuthnConfigFile) > 0 {
- webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL)
+ webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL, config.APIAudiences)
if err != nil {
return nil, nil, err
}
@@ -318,8 +318,8 @@ func newAuthenticatorFromClientCAFile(clientCAFile string) (authenticator.Reques
return x509.New(opts, x509.CommonNameUserConversion), nil
}
-func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration) (authenticator.Token, error) {
- webhookTokenAuthenticator, err := webhook.New(webhookConfigFile)
+func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration, implicitAuds authenticator.Audiences) (authenticator.Token, error) {
+ webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, implicitAuds)
if err != nil {
return nil, err
}
diff --git a/pkg/master/master.go b/pkg/master/master.go
index 7dbc0b378d6..b2d25a12f70 100644
--- a/pkg/master/master.go
+++ b/pkg/master/master.go
@@ -335,7 +335,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
// handlers that we have.
restStorageProviders := []RESTStorageProvider{
auditregistrationrest.RESTStorageProvider{},
- authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator},
+ authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator, APIAudiences: c.GenericConfig.Authentication.APIAudiences},
authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
autoscalingrest.RESTStorageProvider{},
batchrest.RESTStorageProvider{},
diff --git a/pkg/registry/authentication/rest/storage_authentication.go b/pkg/registry/authentication/rest/storage_authentication.go
index 5dec4aeb077..9dc3cf1a8e4 100644
--- a/pkg/registry/authentication/rest/storage_authentication.go
+++ b/pkg/registry/authentication/rest/storage_authentication.go
@@ -31,6 +31,7 @@ import (
type RESTStorageProvider struct {
Authenticator authenticator.Request
+ APIAudiences authenticator.Audiences
}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
@@ -56,7 +57,7 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
storage := map[string]rest.Storage{}
// tokenreviews
- tokenReviewStorage := tokenreview.NewREST(p.Authenticator)
+ tokenReviewStorage := tokenreview.NewREST(p.Authenticator, p.APIAudiences)
storage["tokenreviews"] = tokenReviewStorage
return storage
@@ -65,7 +66,7 @@ func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorag
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
storage := map[string]rest.Storage{}
// tokenreviews
- tokenReviewStorage := tokenreview.NewREST(p.Authenticator)
+ tokenReviewStorage := tokenreview.NewREST(p.Authenticator, p.APIAudiences)
storage["tokenreviews"] = tokenReviewStorage
return storage
diff --git a/pkg/registry/authentication/tokenreview/BUILD b/pkg/registry/authentication/tokenreview/BUILD
index 7ef5901f8f3..4533e49e8b7 100644
--- a/pkg/registry/authentication/tokenreview/BUILD
+++ b/pkg/registry/authentication/tokenreview/BUILD
@@ -17,6 +17,7 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
+ "//vendor/k8s.io/klog:go_default_library",
],
)
diff --git a/pkg/registry/authentication/tokenreview/storage.go b/pkg/registry/authentication/tokenreview/storage.go
index 3150b2afd1b..d14ee1a90f7 100644
--- a/pkg/registry/authentication/tokenreview/storage.go
+++ b/pkg/registry/authentication/tokenreview/storage.go
@@ -18,6 +18,7 @@ package tokenreview
import (
"context"
+ "errors"
"fmt"
"net/http"
@@ -27,15 +28,22 @@ import (
"k8s.io/apiserver/pkg/authentication/authenticator"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest"
+ "k8s.io/klog"
"k8s.io/kubernetes/pkg/apis/authentication"
)
+var badAuthenticatorAuds = apierrors.NewInternalError(errors.New("error validating audiences"))
+
type REST struct {
tokenAuthenticator authenticator.Request
+ apiAudiences []string
}
-func NewREST(tokenAuthenticator authenticator.Request) *REST {
- return &REST{tokenAuthenticator: tokenAuthenticator}
+func NewREST(tokenAuthenticator authenticator.Request, apiAudiences []string) *REST {
+ return &REST{
+ tokenAuthenticator: tokenAuthenticator,
+ apiAudiences: apiAudiences,
+ }
}
func (r *REST) NamespaceScoped() bool {
@@ -68,14 +76,24 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
fakeReq := &http.Request{Header: http.Header{}}
fakeReq.Header.Add("Authorization", "Bearer "+tokenReview.Spec.Token)
+ auds := tokenReview.Spec.Audiences
+ if len(auds) == 0 {
+ auds = r.apiAudiences
+ }
+ if len(auds) > 0 {
+ fakeReq = fakeReq.WithContext(authenticator.WithAudiences(fakeReq.Context(), auds))
+ }
+
resp, ok, err := r.tokenAuthenticator.AuthenticateRequest(fakeReq)
tokenReview.Status.Authenticated = ok
if err != nil {
tokenReview.Status.Error = err.Error()
}
- // TODO(mikedanese): verify the response audience matches one of apiAuds if
- // non-empty
+ if len(auds) > 0 && resp != nil && len(authenticator.Audiences(auds).Intersect(resp.Audiences)) == 0 {
+ klog.Errorf("error validating audience. want=%q got=%q", auds, resp.Audiences)
+ return nil, badAuthenticatorAuds
+ }
if resp != nil && resp.User != nil {
tokenReview.Status.User = authentication.UserInfo{
@@ -87,6 +105,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
for k, v := range resp.User.GetExtra() {
tokenReview.Status.User.Extra[k] = authentication.ExtraValue(v)
}
+ tokenReview.Status.Audiences = resp.Audiences
}
return tokenReview, nil
diff --git a/staging/src/k8s.io/api/authentication/v1/generated.pb.go b/staging/src/k8s.io/api/authentication/v1/generated.pb.go
index dcea42283cb..4e7f28d8c97 100644
--- a/staging/src/k8s.io/api/authentication/v1/generated.pb.go
+++ b/staging/src/k8s.io/api/authentication/v1/generated.pb.go
@@ -355,6 +355,21 @@ func (m *TokenReviewSpec) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Token)))
i += copy(dAtA[i:], m.Token)
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ dAtA[i] = 0x12
+ i++
+ l = len(s)
+ for l >= 1<<7 {
+ dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+ l >>= 7
+ i++
+ }
+ dAtA[i] = uint8(l)
+ i++
+ i += copy(dAtA[i:], s)
+ }
+ }
return i, nil
}
@@ -393,6 +408,21 @@ func (m *TokenReviewStatus) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Error)))
i += copy(dAtA[i:], m.Error)
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ dAtA[i] = 0x22
+ i++
+ l = len(s)
+ for l >= 1<<7 {
+ dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+ l >>= 7
+ i++
+ }
+ dAtA[i] = uint8(l)
+ i++
+ i += copy(dAtA[i:], s)
+ }
+ }
return i, nil
}
@@ -561,6 +591,12 @@ func (m *TokenReviewSpec) Size() (n int) {
_ = l
l = len(m.Token)
n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
return n
}
@@ -572,6 +608,12 @@ func (m *TokenReviewStatus) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Error)
n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
return n
}
@@ -679,6 +721,7 @@ func (this *TokenReviewSpec) String() string {
}
s := strings.Join([]string{`&TokenReviewSpec{`,
`Token:` + fmt.Sprintf("%v", this.Token) + `,`,
+ `Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@@ -691,6 +734,7 @@ func (this *TokenReviewStatus) String() string {
`Authenticated:` + fmt.Sprintf("%v", this.Authenticated) + `,`,
`User:` + strings.Replace(strings.Replace(this.User.String(), "UserInfo", "UserInfo", 1), `&`, ``, 1) + `,`,
`Error:` + fmt.Sprintf("%v", this.Error) + `,`,
+ `Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@@ -1550,6 +1594,35 @@ func (m *TokenReviewSpec) Unmarshal(dAtA []byte) error {
}
m.Token = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -1679,6 +1752,35 @@ func (m *TokenReviewStatus) Unmarshal(dAtA []byte) error {
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -2070,61 +2172,62 @@ func init() {
}
var fileDescriptorGenerated = []byte{
- // 892 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcf, 0x8f, 0xdb, 0x44,
- 0x14, 0x8e, 0xf3, 0x63, 0xb5, 0x99, 0x74, 0x97, 0xdd, 0x29, 0x95, 0xa2, 0x05, 0xec, 0x60, 0x24,
- 0x14, 0x01, 0xb5, 0x9b, 0x08, 0x95, 0xaa, 0x48, 0x48, 0x6b, 0x36, 0x82, 0x08, 0x41, 0xab, 0x69,
- 0x77, 0x41, 0x9c, 0x98, 0xd8, 0x6f, 0xb3, 0x26, 0x78, 0x6c, 0xec, 0x71, 0x68, 0x6e, 0xfd, 0x13,
- 0x38, 0x82, 0xc4, 0x81, 0x3f, 0x02, 0x89, 0x23, 0xd7, 0x3d, 0x56, 0x9c, 0x7a, 0x40, 0x11, 0x6b,
- 0xfe, 0x05, 0x4e, 0x9c, 0xd0, 0x8c, 0x67, 0xe3, 0xfc, 0xd8, 0x4d, 0x73, 0xea, 0x2d, 0xf3, 0xde,
- 0xf7, 0xbe, 0x79, 0xef, 0x9b, 0x2f, 0xcf, 0xa8, 0x37, 0xba, 0x97, 0x58, 0x7e, 0x68, 0x8f, 0xd2,
- 0x01, 0xc4, 0x0c, 0x38, 0x24, 0xf6, 0x18, 0x98, 0x17, 0xc6, 0xb6, 0x4a, 0xd0, 0xc8, 0xb7, 0x69,
- 0xca, 0xcf, 0x80, 0x71, 0xdf, 0xa5, 0xdc, 0x0f, 0x99, 0x3d, 0xee, 0xd8, 0x43, 0x60, 0x10, 0x53,
- 0x0e, 0x9e, 0x15, 0xc5, 0x21, 0x0f, 0xf1, 0xeb, 0x39, 0xda, 0xa2, 0x91, 0x6f, 0x2d, 0xa2, 0xad,
- 0x71, 0xe7, 0xe0, 0xf6, 0xd0, 0xe7, 0x67, 0xe9, 0xc0, 0x72, 0xc3, 0xc0, 0x1e, 0x86, 0xc3, 0xd0,
- 0x96, 0x45, 0x83, 0xf4, 0x54, 0x9e, 0xe4, 0x41, 0xfe, 0xca, 0xc9, 0x0e, 0xde, 0x2f, 0xae, 0x0e,
- 0xa8, 0x7b, 0xe6, 0x33, 0x88, 0x27, 0x76, 0x34, 0x1a, 0x8a, 0x40, 0x62, 0x07, 0xc0, 0xe9, 0x15,
- 0x2d, 0x1c, 0xd8, 0xd7, 0x55, 0xc5, 0x29, 0xe3, 0x7e, 0x00, 0x2b, 0x05, 0x77, 0x5f, 0x54, 0x90,
- 0xb8, 0x67, 0x10, 0xd0, 0xe5, 0x3a, 0xf3, 0x4f, 0x0d, 0xbd, 0xea, 0x84, 0x29, 0xf3, 0x1e, 0x0c,
- 0xbe, 0x05, 0x97, 0x13, 0x38, 0x85, 0x18, 0x98, 0x0b, 0xb8, 0x85, 0xaa, 0x23, 0x9f, 0x79, 0x4d,
- 0xad, 0xa5, 0xb5, 0xeb, 0xce, 0x8d, 0xf3, 0xa9, 0x51, 0xca, 0xa6, 0x46, 0xf5, 0x33, 0x9f, 0x79,
- 0x44, 0x66, 0x70, 0x17, 0x21, 0xfa, 0xb0, 0x7f, 0x02, 0x71, 0xe2, 0x87, 0xac, 0x59, 0x96, 0x38,
- 0xac, 0x70, 0xe8, 0x70, 0x96, 0x21, 0x73, 0x28, 0xc1, 0xca, 0x68, 0x00, 0xcd, 0xca, 0x22, 0xeb,
- 0x17, 0x34, 0x00, 0x22, 0x33, 0xd8, 0x41, 0x95, 0xb4, 0x7f, 0xd4, 0xac, 0x4a, 0xc0, 0x1d, 0x05,
- 0xa8, 0x1c, 0xf7, 0x8f, 0xfe, 0x9b, 0x1a, 0x6f, 0x5e, 0x37, 0x24, 0x9f, 0x44, 0x90, 0x58, 0xc7,
- 0xfd, 0x23, 0x22, 0x8a, 0xcd, 0x0f, 0x10, 0xea, 0x3d, 0xe1, 0x31, 0x3d, 0xa1, 0xdf, 0xa5, 0x80,
- 0x0d, 0x54, 0xf3, 0x39, 0x04, 0x49, 0x53, 0x6b, 0x55, 0xda, 0x75, 0xa7, 0x9e, 0x4d, 0x8d, 0x5a,
- 0x5f, 0x04, 0x48, 0x1e, 0xbf, 0xbf, 0xfd, 0xd3, 0xaf, 0x46, 0xe9, 0xe9, 0x5f, 0xad, 0x92, 0xf9,
- 0x4b, 0x19, 0xdd, 0x78, 0x1c, 0x8e, 0x80, 0x11, 0xf8, 0x3e, 0x85, 0x84, 0xe3, 0x6f, 0xd0, 0xb6,
- 0x78, 0x22, 0x8f, 0x72, 0x2a, 0x95, 0x68, 0x74, 0xef, 0x58, 0x85, 0x3b, 0x66, 0x4d, 0x58, 0xd1,
- 0x68, 0x28, 0x02, 0x89, 0x25, 0xd0, 0xd6, 0xb8, 0x63, 0xe5, 0x72, 0x7e, 0x0e, 0x9c, 0x16, 0x9a,
- 0x14, 0x31, 0x32, 0x63, 0xc5, 0x0f, 0x51, 0x35, 0x89, 0xc0, 0x95, 0xfa, 0x35, 0xba, 0x96, 0xb5,
- 0xce, 0x7b, 0xd6, 0x7c, 0x6f, 0x8f, 0x22, 0x70, 0x0b, 0x05, 0xc5, 0x89, 0x48, 0x26, 0xfc, 0x15,
- 0xda, 0x4a, 0x38, 0xe5, 0x69, 0x22, 0x55, 0x5e, 0xec, 0xf8, 0x45, 0x9c, 0xb2, 0xce, 0xd9, 0x55,
- 0xac, 0x5b, 0xf9, 0x99, 0x28, 0x3e, 0xf3, 0x5f, 0x0d, 0xed, 0x2d, 0xb7, 0x80, 0xdf, 0x45, 0x75,
- 0x9a, 0x7a, 0xbe, 0x30, 0xcd, 0xa5, 0xc4, 0x3b, 0xd9, 0xd4, 0xa8, 0x1f, 0x5e, 0x06, 0x49, 0x91,
- 0xc7, 0x0c, 0xed, 0x0e, 0x16, 0xdc, 0xa6, 0x7a, 0xec, 0xae, 0xef, 0xf1, 0x2a, 0x87, 0x3a, 0x38,
- 0x9b, 0x1a, 0xbb, 0x8b, 0x19, 0xb2, 0xc4, 0x8e, 0x3f, 0x46, 0xfb, 0xf0, 0x24, 0xf2, 0x63, 0xc9,
- 0xf4, 0x08, 0xdc, 0x90, 0x79, 0x89, 0xf4, 0x56, 0xc5, 0xb9, 0x95, 0x4d, 0x8d, 0xfd, 0xde, 0x72,
- 0x92, 0xac, 0xe2, 0xcd, 0xdf, 0x34, 0x84, 0x57, 0x55, 0xc2, 0x6f, 0xa1, 0x1a, 0x17, 0x51, 0xf5,
- 0x17, 0xd9, 0x51, 0xa2, 0xd5, 0x72, 0x68, 0x9e, 0xc3, 0x13, 0x74, 0xb3, 0x20, 0x7c, 0xec, 0x07,
- 0x90, 0x70, 0x1a, 0x44, 0xea, 0xb5, 0xdf, 0xd9, 0xcc, 0x4b, 0xa2, 0xcc, 0x79, 0x4d, 0xd1, 0xdf,
- 0xec, 0xad, 0xd2, 0x91, 0xab, 0xee, 0x30, 0x7f, 0x2e, 0xa3, 0x86, 0x6a, 0x7b, 0xec, 0xc3, 0x0f,
- 0x2f, 0xc1, 0xcb, 0x0f, 0x16, 0xbc, 0x7c, 0x7b, 0x23, 0xdf, 0x89, 0xd6, 0xae, 0xb5, 0xf2, 0x97,
- 0x4b, 0x56, 0xb6, 0x37, 0xa7, 0x5c, 0xef, 0xe4, 0xbb, 0xe8, 0x95, 0xa5, 0xfb, 0x37, 0x7a, 0x4e,
- 0xf3, 0x0f, 0x0d, 0xed, 0xaf, 0xdc, 0x82, 0x3f, 0x44, 0x3b, 0x73, 0xcd, 0x40, 0xbe, 0x34, 0xb7,
- 0x9d, 0x5b, 0x8a, 0x62, 0xe7, 0x70, 0x3e, 0x49, 0x16, 0xb1, 0xf8, 0x53, 0x54, 0x4d, 0x13, 0x88,
- 0x95, 0x68, 0x6f, 0xaf, 0x9f, 0xf0, 0x38, 0x81, 0xb8, 0xcf, 0x4e, 0xc3, 0x42, 0x2d, 0x11, 0x21,
- 0x92, 0x41, 0x4c, 0x00, 0x71, 0x1c, 0xc6, 0x6a, 0xbb, 0xce, 0x26, 0xe8, 0x89, 0x20, 0xc9, 0x73,
- 0xe6, 0xef, 0x65, 0xb4, 0x7d, 0xc9, 0x82, 0xdf, 0x43, 0xdb, 0xa2, 0x52, 0xae, 0xe4, 0x7c, 0xec,
- 0x3d, 0x55, 0x24, 0x31, 0x22, 0x4e, 0x66, 0x08, 0xfc, 0x06, 0xaa, 0xa4, 0xbe, 0xa7, 0x36, 0x7d,
- 0x63, 0x6e, 0x35, 0x13, 0x11, 0xc7, 0x26, 0xda, 0x1a, 0xc6, 0x61, 0x1a, 0x89, 0xc7, 0x12, 0x5b,
- 0x00, 0x09, 0xdd, 0x3f, 0x91, 0x11, 0xa2, 0x32, 0xf8, 0x04, 0xd5, 0x40, 0x6c, 0xe6, 0x66, 0xb5,
- 0x55, 0x69, 0x37, 0xba, 0x9d, 0xcd, 0xa6, 0xb5, 0xe4, 0x36, 0xef, 0x31, 0x1e, 0x4f, 0xe6, 0xa6,
- 0x12, 0x31, 0x92, 0xd3, 0x1d, 0x0c, 0xd4, 0xc6, 0x97, 0x18, 0xbc, 0x87, 0x2a, 0x23, 0x98, 0xe4,
- 0x13, 0x11, 0xf1, 0x13, 0x7f, 0x84, 0x6a, 0x63, 0xf1, 0x31, 0x50, 0x2a, 0xb7, 0xd7, 0xdf, 0x5b,
- 0x7c, 0x3c, 0x48, 0x5e, 0x76, 0xbf, 0x7c, 0x4f, 0x73, 0xda, 0xe7, 0x17, 0x7a, 0xe9, 0xd9, 0x85,
- 0x5e, 0x7a, 0x7e, 0xa1, 0x97, 0x9e, 0x66, 0xba, 0x76, 0x9e, 0xe9, 0xda, 0xb3, 0x4c, 0xd7, 0x9e,
- 0x67, 0xba, 0xf6, 0x77, 0xa6, 0x6b, 0x3f, 0xfe, 0xa3, 0x97, 0xbe, 0x2e, 0x8f, 0x3b, 0xff, 0x07,
- 0x00, 0x00, 0xff, 0xff, 0x5e, 0x8d, 0x94, 0x78, 0x88, 0x08, 0x00, 0x00,
+ // 900 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcf, 0x6f, 0xe3, 0x44,
+ 0x14, 0x8e, 0xf3, 0xa3, 0x4a, 0x26, 0xdb, 0xd2, 0xce, 0xb2, 0x52, 0x54, 0xc0, 0x2e, 0x41, 0x42,
+ 0x15, 0xb0, 0xf6, 0x26, 0x42, 0xb0, 0x5a, 0x24, 0xa4, 0x9a, 0x46, 0x10, 0x21, 0xd8, 0xd5, 0xec,
+ 0xb6, 0x20, 0x4e, 0x4c, 0xec, 0xd7, 0xc4, 0x04, 0x8f, 0x8d, 0x3d, 0x0e, 0x9b, 0xdb, 0xfe, 0x09,
+ 0x1c, 0x41, 0xe2, 0xc0, 0x1f, 0x81, 0xc4, 0xbf, 0xd0, 0xe3, 0x8a, 0xd3, 0x1e, 0x50, 0x44, 0xcd,
+ 0x95, 0x23, 0x27, 0x4e, 0x68, 0xc6, 0xd3, 0x38, 0x4e, 0xda, 0x34, 0x27, 0x6e, 0x9e, 0xf7, 0xbe,
+ 0xf7, 0xbd, 0x37, 0xdf, 0x7c, 0x9e, 0x41, 0xbd, 0xf1, 0xfd, 0xd8, 0xf4, 0x02, 0x6b, 0x9c, 0x0c,
+ 0x20, 0x62, 0xc0, 0x21, 0xb6, 0x26, 0xc0, 0xdc, 0x20, 0xb2, 0x54, 0x82, 0x86, 0x9e, 0x45, 0x13,
+ 0x3e, 0x02, 0xc6, 0x3d, 0x87, 0x72, 0x2f, 0x60, 0xd6, 0xa4, 0x63, 0x0d, 0x81, 0x41, 0x44, 0x39,
+ 0xb8, 0x66, 0x18, 0x05, 0x3c, 0xc0, 0xaf, 0x66, 0x68, 0x93, 0x86, 0x9e, 0x59, 0x44, 0x9b, 0x93,
+ 0xce, 0xfe, 0xdd, 0xa1, 0xc7, 0x47, 0xc9, 0xc0, 0x74, 0x02, 0xdf, 0x1a, 0x06, 0xc3, 0xc0, 0x92,
+ 0x45, 0x83, 0xe4, 0x4c, 0xae, 0xe4, 0x42, 0x7e, 0x65, 0x64, 0xfb, 0xef, 0xe6, 0xad, 0x7d, 0xea,
+ 0x8c, 0x3c, 0x06, 0xd1, 0xd4, 0x0a, 0xc7, 0x43, 0x11, 0x88, 0x2d, 0x1f, 0x38, 0xbd, 0x62, 0x84,
+ 0x7d, 0xeb, 0xba, 0xaa, 0x28, 0x61, 0xdc, 0xf3, 0x61, 0xa5, 0xe0, 0xbd, 0x9b, 0x0a, 0x62, 0x67,
+ 0x04, 0x3e, 0x5d, 0xae, 0x6b, 0xff, 0xae, 0xa1, 0x97, 0xed, 0x20, 0x61, 0xee, 0xc3, 0xc1, 0x37,
+ 0xe0, 0x70, 0x02, 0x67, 0x10, 0x01, 0x73, 0x00, 0x1f, 0xa0, 0xea, 0xd8, 0x63, 0x6e, 0x4b, 0x3b,
+ 0xd0, 0x0e, 0x1b, 0xf6, 0xad, 0xf3, 0x99, 0x51, 0x4a, 0x67, 0x46, 0xf5, 0x53, 0x8f, 0xb9, 0x44,
+ 0x66, 0x70, 0x17, 0x21, 0xfa, 0xa8, 0x7f, 0x0a, 0x51, 0xec, 0x05, 0xac, 0x55, 0x96, 0x38, 0xac,
+ 0x70, 0xe8, 0x68, 0x9e, 0x21, 0x0b, 0x28, 0xc1, 0xca, 0xa8, 0x0f, 0xad, 0x4a, 0x91, 0xf5, 0x73,
+ 0xea, 0x03, 0x91, 0x19, 0x6c, 0xa3, 0x4a, 0xd2, 0x3f, 0x6e, 0x55, 0x25, 0xe0, 0x9e, 0x02, 0x54,
+ 0x4e, 0xfa, 0xc7, 0xff, 0xce, 0x8c, 0xd7, 0xaf, 0xdb, 0x24, 0x9f, 0x86, 0x10, 0x9b, 0x27, 0xfd,
+ 0x63, 0x22, 0x8a, 0xdb, 0xef, 0x23, 0xd4, 0x7b, 0xca, 0x23, 0x7a, 0x4a, 0xbf, 0x4d, 0x00, 0x1b,
+ 0xa8, 0xe6, 0x71, 0xf0, 0xe3, 0x96, 0x76, 0x50, 0x39, 0x6c, 0xd8, 0x8d, 0x74, 0x66, 0xd4, 0xfa,
+ 0x22, 0x40, 0xb2, 0xf8, 0x83, 0xfa, 0x8f, 0xbf, 0x18, 0xa5, 0x67, 0x7f, 0x1c, 0x94, 0xda, 0x3f,
+ 0x97, 0xd1, 0xad, 0x27, 0xc1, 0x18, 0x18, 0x81, 0xef, 0x12, 0x88, 0x39, 0xfe, 0x1a, 0xd5, 0xc5,
+ 0x11, 0xb9, 0x94, 0x53, 0xa9, 0x44, 0xb3, 0x7b, 0xcf, 0xcc, 0xdd, 0x31, 0x1f, 0xc2, 0x0c, 0xc7,
+ 0x43, 0x11, 0x88, 0x4d, 0x81, 0x36, 0x27, 0x1d, 0x33, 0x93, 0xf3, 0x33, 0xe0, 0x34, 0xd7, 0x24,
+ 0x8f, 0x91, 0x39, 0x2b, 0x7e, 0x84, 0xaa, 0x71, 0x08, 0x8e, 0xd4, 0xaf, 0xd9, 0x35, 0xcd, 0x75,
+ 0xde, 0x33, 0x17, 0x67, 0x7b, 0x1c, 0x82, 0x93, 0x2b, 0x28, 0x56, 0x44, 0x32, 0xe1, 0x2f, 0xd1,
+ 0x56, 0xcc, 0x29, 0x4f, 0x62, 0xa9, 0x72, 0x71, 0xe2, 0x9b, 0x38, 0x65, 0x9d, 0xbd, 0xa3, 0x58,
+ 0xb7, 0xb2, 0x35, 0x51, 0x7c, 0xed, 0x7f, 0x34, 0xb4, 0xbb, 0x3c, 0x02, 0x7e, 0x1b, 0x35, 0x68,
+ 0xe2, 0x7a, 0xc2, 0x34, 0x97, 0x12, 0x6f, 0xa7, 0x33, 0xa3, 0x71, 0x74, 0x19, 0x24, 0x79, 0x1e,
+ 0x33, 0xb4, 0x33, 0x28, 0xb8, 0x4d, 0xcd, 0xd8, 0x5d, 0x3f, 0xe3, 0x55, 0x0e, 0xb5, 0x71, 0x3a,
+ 0x33, 0x76, 0x8a, 0x19, 0xb2, 0xc4, 0x8e, 0x3f, 0x42, 0x7b, 0xf0, 0x34, 0xf4, 0x22, 0xc9, 0xf4,
+ 0x18, 0x9c, 0x80, 0xb9, 0xb1, 0xf4, 0x56, 0xc5, 0xbe, 0x93, 0xce, 0x8c, 0xbd, 0xde, 0x72, 0x92,
+ 0xac, 0xe2, 0xdb, 0xbf, 0x6a, 0x08, 0xaf, 0xaa, 0x84, 0xdf, 0x40, 0x35, 0x2e, 0xa2, 0xea, 0x17,
+ 0xd9, 0x56, 0xa2, 0xd5, 0x32, 0x68, 0x96, 0xc3, 0x53, 0x74, 0x3b, 0x27, 0x7c, 0xe2, 0xf9, 0x10,
+ 0x73, 0xea, 0x87, 0xea, 0xb4, 0xdf, 0xda, 0xcc, 0x4b, 0xa2, 0xcc, 0x7e, 0x45, 0xd1, 0xdf, 0xee,
+ 0xad, 0xd2, 0x91, 0xab, 0x7a, 0xb4, 0x7f, 0x2a, 0xa3, 0xa6, 0x1a, 0x7b, 0xe2, 0xc1, 0xf7, 0xff,
+ 0x83, 0x97, 0x1f, 0x16, 0xbc, 0x7c, 0x77, 0x23, 0xdf, 0x89, 0xd1, 0xae, 0xb5, 0xf2, 0x17, 0x4b,
+ 0x56, 0xb6, 0x36, 0xa7, 0x5c, 0xef, 0x64, 0x07, 0xbd, 0xb4, 0xd4, 0x7f, 0xb3, 0xe3, 0x2c, 0x98,
+ 0xbd, 0xbc, 0xde, 0xec, 0xed, 0xbf, 0x35, 0xb4, 0xb7, 0x32, 0x12, 0xfe, 0x00, 0x6d, 0x2f, 0x4c,
+ 0x0e, 0xd9, 0x0d, 0x5b, 0xb7, 0xef, 0xa8, 0x7e, 0xdb, 0x47, 0x8b, 0x49, 0x52, 0xc4, 0xe2, 0x4f,
+ 0x50, 0x35, 0x89, 0x21, 0x52, 0x0a, 0xbf, 0xb9, 0x5e, 0x8e, 0x93, 0x18, 0xa2, 0x3e, 0x3b, 0x0b,
+ 0x72, 0x69, 0x45, 0x84, 0x48, 0x06, 0xb1, 0x5d, 0x88, 0xa2, 0x20, 0x52, 0x57, 0xf1, 0x7c, 0xbb,
+ 0x3d, 0x11, 0x24, 0x59, 0xae, 0xb8, 0xdd, 0xea, 0x0d, 0xdb, 0xfd, 0xad, 0x8c, 0xea, 0x97, 0x2d,
+ 0xf1, 0x3b, 0xa8, 0x2e, 0xda, 0xc8, 0xcb, 0x3e, 0x13, 0x74, 0x57, 0x75, 0x90, 0x18, 0x11, 0x27,
+ 0x73, 0x04, 0x7e, 0x0d, 0x55, 0x12, 0xcf, 0x55, 0x6f, 0x48, 0x73, 0xe1, 0xd2, 0x27, 0x22, 0x8e,
+ 0xdb, 0x68, 0x6b, 0x18, 0x05, 0x49, 0x28, 0x6c, 0x20, 0x66, 0x40, 0xe2, 0x44, 0x3f, 0x96, 0x11,
+ 0xa2, 0x32, 0xf8, 0x14, 0xd5, 0x40, 0xdc, 0xf9, 0x72, 0xcc, 0x66, 0xb7, 0xb3, 0x99, 0x34, 0xa6,
+ 0x7c, 0x27, 0x7a, 0x8c, 0x47, 0xd3, 0x05, 0x09, 0x44, 0x8c, 0x64, 0x74, 0xfb, 0x03, 0xf5, 0x96,
+ 0x48, 0x0c, 0xde, 0x45, 0x95, 0x31, 0x4c, 0xb3, 0x1d, 0x11, 0xf1, 0x89, 0x3f, 0x44, 0xb5, 0x89,
+ 0x78, 0x66, 0xd4, 0x91, 0x1c, 0xae, 0xef, 0x9b, 0x3f, 0x4b, 0x24, 0x2b, 0x7b, 0x50, 0xbe, 0xaf,
+ 0xd9, 0x87, 0xe7, 0x17, 0x7a, 0xe9, 0xf9, 0x85, 0x5e, 0x7a, 0x71, 0xa1, 0x97, 0x9e, 0xa5, 0xba,
+ 0x76, 0x9e, 0xea, 0xda, 0xf3, 0x54, 0xd7, 0x5e, 0xa4, 0xba, 0xf6, 0x67, 0xaa, 0x6b, 0x3f, 0xfc,
+ 0xa5, 0x97, 0xbe, 0x2a, 0x4f, 0x3a, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x04, 0x81, 0x6f,
+ 0xe2, 0x08, 0x00, 0x00,
}
diff --git a/staging/src/k8s.io/api/authentication/v1/generated.proto b/staging/src/k8s.io/api/authentication/v1/generated.proto
index 10c792171d2..b69636a814d 100644
--- a/staging/src/k8s.io/api/authentication/v1/generated.proto
+++ b/staging/src/k8s.io/api/authentication/v1/generated.proto
@@ -118,6 +118,14 @@ message TokenReviewSpec {
// Token is the opaque bearer token.
// +optional
optional string token = 1;
+
+ // Audiences is a list of the identifiers that the resource server presented
+ // with the token identifies as. Audience-aware token authenticators will
+ // verify that the token was intended for at least one of the audiences in
+ // this list. If no audiences are provided, the audience will default to the
+ // audience of the Kubernetes apiserver.
+ // +optional
+ repeated string audiences = 2;
}
// TokenReviewStatus is the result of the token authentication request.
@@ -130,6 +138,18 @@ message TokenReviewStatus {
// +optional
optional UserInfo user = 2;
+ // Audiences are audience identifiers chosen by the authenticator that are
+ // compatible with both the TokenReview and token. An identifier is any
+ // identifier in the intersection of the TokenReviewSpec audiences and the
+ // token's audiences. A client of the TokenReview API that sets the
+ // spec.audiences field should validate that a compatible audience identifier
+ // is returned in the status.audiences field to ensure that the TokenReview
+ // server is audience aware. If a TokenReview returns an empty
+ // status.audience field where status.authenticated is "true", the token is
+ // valid against the audience of the Kubernetes API server.
+ // +optional
+ repeated string audiences = 4;
+
// Error indicates that the token couldn't be checked
// +optional
optional string error = 3;
diff --git a/staging/src/k8s.io/api/authentication/v1/types.go b/staging/src/k8s.io/api/authentication/v1/types.go
index 723457a3dd2..d348c6fd405 100644
--- a/staging/src/k8s.io/api/authentication/v1/types.go
+++ b/staging/src/k8s.io/api/authentication/v1/types.go
@@ -64,6 +64,13 @@ type TokenReviewSpec struct {
// Token is the opaque bearer token.
// +optional
Token string `json:"token,omitempty" protobuf:"bytes,1,opt,name=token"`
+ // Audiences is a list of the identifiers that the resource server presented
+ // with the token identifies as. Audience-aware token authenticators will
+ // verify that the token was intended for at least one of the audiences in
+ // this list. If no audiences are provided, the audience will default to the
+ // audience of the Kubernetes apiserver.
+ // +optional
+ Audiences []string `json:"audiences,omitempty" protobuf:"bytes,2,rep,name=audiences"`
}
// TokenReviewStatus is the result of the token authentication request.
@@ -74,6 +81,17 @@ type TokenReviewStatus struct {
// User is the UserInfo associated with the provided token.
// +optional
User UserInfo `json:"user,omitempty" protobuf:"bytes,2,opt,name=user"`
+ // Audiences are audience identifiers chosen by the authenticator that are
+ // compatible with both the TokenReview and token. An identifier is any
+ // identifier in the intersection of the TokenReviewSpec audiences and the
+ // token's audiences. A client of the TokenReview API that sets the
+ // spec.audiences field should validate that a compatible audience identifier
+ // is returned in the status.audiences field to ensure that the TokenReview
+ // server is audience aware. If a TokenReview returns an empty
+ // status.audience field where status.authenticated is "true", the token is
+ // valid against the audience of the Kubernetes API server.
+ // +optional
+ Audiences []string `json:"audiences,omitempty" protobuf:"bytes,4,rep,name=audiences"`
// Error indicates that the token couldn't be checked
// +optional
Error string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"`
diff --git a/staging/src/k8s.io/api/authentication/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/authentication/v1/types_swagger_doc_generated.go
index 6632a5dd5b2..f2c9b95c71f 100644
--- a/staging/src/k8s.io/api/authentication/v1/types_swagger_doc_generated.go
+++ b/staging/src/k8s.io/api/authentication/v1/types_swagger_doc_generated.go
@@ -79,8 +79,9 @@ func (TokenReview) SwaggerDoc() map[string]string {
}
var map_TokenReviewSpec = map[string]string{
- "": "TokenReviewSpec is a description of the token authentication request.",
- "token": "Token is the opaque bearer token.",
+ "": "TokenReviewSpec is a description of the token authentication request.",
+ "token": "Token is the opaque bearer token.",
+ "audiences": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
}
func (TokenReviewSpec) SwaggerDoc() map[string]string {
@@ -91,6 +92,7 @@ var map_TokenReviewStatus = map[string]string{
"": "TokenReviewStatus is the result of the token authentication request.",
"authenticated": "Authenticated indicates that the token was associated with a known user.",
"user": "User is the UserInfo associated with the provided token.",
+ "audiences": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
"error": "Error indicates that the token couldn't be checked",
}
diff --git a/staging/src/k8s.io/api/authentication/v1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/authentication/v1/zz_generated.deepcopy.go
index f36c253b2e7..aca99c42b76 100644
--- a/staging/src/k8s.io/api/authentication/v1/zz_generated.deepcopy.go
+++ b/staging/src/k8s.io/api/authentication/v1/zz_generated.deepcopy.go
@@ -141,7 +141,7 @@ func (in *TokenReview) DeepCopyInto(out *TokenReview) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@@ -167,6 +167,11 @@ func (in *TokenReview) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenReviewSpec) DeepCopyInto(out *TokenReviewSpec) {
*out = *in
+ if in.Audiences != nil {
+ in, out := &in.Audiences, &out.Audiences
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
return
}
@@ -184,6 +189,11 @@ func (in *TokenReviewSpec) DeepCopy() *TokenReviewSpec {
func (in *TokenReviewStatus) DeepCopyInto(out *TokenReviewStatus) {
*out = *in
in.User.DeepCopyInto(&out.User)
+ if in.Audiences != nil {
+ in, out := &in.Audiences, &out.Audiences
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
return
}
diff --git a/staging/src/k8s.io/api/authentication/v1beta1/generated.pb.go b/staging/src/k8s.io/api/authentication/v1beta1/generated.pb.go
index 55886b47818..5f34e76a9c3 100644
--- a/staging/src/k8s.io/api/authentication/v1beta1/generated.pb.go
+++ b/staging/src/k8s.io/api/authentication/v1beta1/generated.pb.go
@@ -175,6 +175,21 @@ func (m *TokenReviewSpec) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Token)))
i += copy(dAtA[i:], m.Token)
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ dAtA[i] = 0x12
+ i++
+ l = len(s)
+ for l >= 1<<7 {
+ dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+ l >>= 7
+ i++
+ }
+ dAtA[i] = uint8(l)
+ i++
+ i += copy(dAtA[i:], s)
+ }
+ }
return i, nil
}
@@ -213,6 +228,21 @@ func (m *TokenReviewStatus) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Error)))
i += copy(dAtA[i:], m.Error)
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ dAtA[i] = 0x22
+ i++
+ l = len(s)
+ for l >= 1<<7 {
+ dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
+ l >>= 7
+ i++
+ }
+ dAtA[i] = uint8(l)
+ i++
+ i += copy(dAtA[i:], s)
+ }
+ }
return i, nil
}
@@ -326,6 +356,12 @@ func (m *TokenReviewSpec) Size() (n int) {
_ = l
l = len(m.Token)
n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
return n
}
@@ -337,6 +373,12 @@ func (m *TokenReviewStatus) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Error)
n += 1 + l + sovGenerated(uint64(l))
+ if len(m.Audiences) > 0 {
+ for _, s := range m.Audiences {
+ l = len(s)
+ n += 1 + l + sovGenerated(uint64(l))
+ }
+ }
return n
}
@@ -396,6 +438,7 @@ func (this *TokenReviewSpec) String() string {
}
s := strings.Join([]string{`&TokenReviewSpec{`,
`Token:` + fmt.Sprintf("%v", this.Token) + `,`,
+ `Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@@ -408,6 +451,7 @@ func (this *TokenReviewStatus) String() string {
`Authenticated:` + fmt.Sprintf("%v", this.Authenticated) + `,`,
`User:` + strings.Replace(strings.Replace(this.User.String(), "UserInfo", "UserInfo", 1), `&`, ``, 1) + `,`,
`Error:` + fmt.Sprintf("%v", this.Error) + `,`,
+ `Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@@ -720,6 +764,35 @@ func (m *TokenReviewSpec) Unmarshal(dAtA []byte) error {
}
m.Token = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -849,6 +922,35 @@ func (m *TokenReviewStatus) Unmarshal(dAtA []byte) error {
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowGenerated
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= (uint64(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthGenerated
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
+ iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@@ -1240,45 +1342,47 @@ func init() {
}
var fileDescriptorGenerated = []byte{
- // 635 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcf, 0x4f, 0xd4, 0x40,
- 0x14, 0x6e, 0xf7, 0x07, 0xee, 0xce, 0x8a, 0xe2, 0x24, 0x26, 0x9b, 0x4d, 0xec, 0xae, 0xeb, 0x85,
- 0x44, 0x99, 0x0a, 0x21, 0x48, 0xf0, 0x64, 0x95, 0x18, 0x4c, 0x88, 0xc9, 0x08, 0x1e, 0xd4, 0x83,
- 0xb3, 0xdd, 0x47, 0xb7, 0xae, 0xed, 0x34, 0xd3, 0x69, 0x95, 0x1b, 0x7f, 0x82, 0x47, 0x8f, 0x26,
- 0xfe, 0x25, 0x26, 0x1e, 0x38, 0x72, 0xe4, 0x60, 0x88, 0xd4, 0x7f, 0xc4, 0xcc, 0x74, 0x64, 0x17,
- 0x88, 0x01, 0x6e, 0xf3, 0xbe, 0xf7, 0xbe, 0x6f, 0xde, 0xf7, 0x66, 0x1e, 0x7a, 0x31, 0x5e, 0x4d,
- 0x49, 0xc8, 0xdd, 0x71, 0x36, 0x00, 0x11, 0x83, 0x84, 0xd4, 0xcd, 0x21, 0x1e, 0x72, 0xe1, 0x9a,
- 0x04, 0x4b, 0x42, 0x97, 0x65, 0x72, 0x04, 0xb1, 0x0c, 0x7d, 0x26, 0x43, 0x1e, 0xbb, 0xf9, 0xe2,
- 0x00, 0x24, 0x5b, 0x74, 0x03, 0x88, 0x41, 0x30, 0x09, 0x43, 0x92, 0x08, 0x2e, 0x39, 0xbe, 0x5b,
- 0x52, 0x08, 0x4b, 0x42, 0x72, 0x9a, 0x42, 0x0c, 0xa5, 0xb3, 0x10, 0x84, 0x72, 0x94, 0x0d, 0x88,
- 0xcf, 0x23, 0x37, 0xe0, 0x01, 0x77, 0x35, 0x73, 0x90, 0xed, 0xe8, 0x48, 0x07, 0xfa, 0x54, 0x2a,
- 0x76, 0x96, 0x27, 0x4d, 0x44, 0xcc, 0x1f, 0x85, 0x31, 0x88, 0x5d, 0x37, 0x19, 0x07, 0x0a, 0x48,
- 0xdd, 0x08, 0x24, 0x73, 0xf3, 0x73, 0x7d, 0x74, 0xdc, 0xff, 0xb1, 0x44, 0x16, 0xcb, 0x30, 0x82,
- 0x73, 0x84, 0x95, 0x8b, 0x08, 0xa9, 0x3f, 0x82, 0x88, 0x9d, 0xe5, 0xf5, 0x1f, 0x21, 0xb4, 0xfe,
- 0x59, 0x0a, 0xf6, 0x9a, 0x7d, 0xcc, 0x00, 0x77, 0x51, 0x3d, 0x94, 0x10, 0xa5, 0x6d, 0xbb, 0x57,
- 0x9d, 0x6f, 0x7a, 0xcd, 0xe2, 0xa8, 0x5b, 0xdf, 0x50, 0x00, 0x2d, 0xf1, 0xb5, 0xc6, 0xd7, 0x6f,
- 0x5d, 0x6b, 0xef, 0x57, 0xcf, 0xea, 0x7f, 0xaf, 0xa0, 0xd6, 0x16, 0x1f, 0x43, 0x4c, 0x21, 0x0f,
- 0xe1, 0x13, 0x7e, 0x8f, 0x1a, 0xca, 0xcc, 0x90, 0x49, 0xd6, 0xb6, 0x7b, 0xf6, 0x7c, 0x6b, 0xe9,
- 0x21, 0x99, 0x0c, 0xf3, 0xa4, 0x27, 0x92, 0x8c, 0x03, 0x05, 0xa4, 0x44, 0x55, 0x93, 0x7c, 0x91,
- 0xbc, 0x1c, 0x7c, 0x00, 0x5f, 0x6e, 0x82, 0x64, 0x1e, 0xde, 0x3f, 0xea, 0x5a, 0xc5, 0x51, 0x17,
- 0x4d, 0x30, 0x7a, 0xa2, 0x8a, 0xb7, 0x50, 0x2d, 0x4d, 0xc0, 0x6f, 0x57, 0xb4, 0xfa, 0x12, 0xb9,
- 0xf0, 0xa9, 0xc8, 0x54, 0x7f, 0xaf, 0x12, 0xf0, 0xbd, 0xeb, 0x46, 0xbf, 0xa6, 0x22, 0xaa, 0xd5,
- 0xf0, 0x3b, 0x34, 0x93, 0x4a, 0x26, 0xb3, 0xb4, 0x5d, 0xd5, 0xba, 0xcb, 0x57, 0xd4, 0xd5, 0x5c,
- 0xef, 0x86, 0x51, 0x9e, 0x29, 0x63, 0x6a, 0x34, 0xfb, 0x2b, 0xe8, 0xe6, 0x99, 0x26, 0xf0, 0x3d,
- 0x54, 0x97, 0x0a, 0xd2, 0x53, 0x6a, 0x7a, 0xb3, 0x86, 0x59, 0x2f, 0xeb, 0xca, 0x5c, 0xff, 0xa7,
- 0x8d, 0x6e, 0x9d, 0xbb, 0x05, 0x3f, 0x46, 0xb3, 0x53, 0x1d, 0xc1, 0x50, 0x4b, 0x34, 0xbc, 0xdb,
- 0x46, 0x62, 0xf6, 0xc9, 0x74, 0x92, 0x9e, 0xae, 0xc5, 0x9b, 0xa8, 0x96, 0xa5, 0x20, 0xcc, 0xf8,
- 0xee, 0x5f, 0xc2, 0xe6, 0x76, 0x0a, 0x62, 0x23, 0xde, 0xe1, 0x93, 0xb9, 0x29, 0x84, 0x6a, 0x19,
- 0x65, 0x03, 0x84, 0xe0, 0x42, 0x8f, 0x6d, 0xca, 0xc6, 0xba, 0x02, 0x69, 0x99, 0xeb, 0xff, 0xa8,
- 0xa0, 0xc6, 0x3f, 0x15, 0xfc, 0x00, 0x35, 0x14, 0x33, 0x66, 0x11, 0x18, 0xef, 0x73, 0x86, 0xa4,
- 0x6b, 0x14, 0x4e, 0x4f, 0x2a, 0xf0, 0x1d, 0x54, 0xcd, 0xc2, 0xa1, 0xee, 0xb6, 0xe9, 0xb5, 0x4c,
- 0x61, 0x75, 0x7b, 0xe3, 0x19, 0x55, 0x38, 0xee, 0xa3, 0x99, 0x40, 0xf0, 0x2c, 0x51, 0xcf, 0xa6,
- 0xbe, 0x2a, 0x52, 0xc3, 0x7f, 0xae, 0x11, 0x6a, 0x32, 0xf8, 0x2d, 0xaa, 0x83, 0xfa, 0xdb, 0xed,
- 0x5a, 0xaf, 0x3a, 0xdf, 0x5a, 0x5a, 0xb9, 0x82, 0x65, 0xa2, 0x97, 0x62, 0x3d, 0x96, 0x62, 0x77,
- 0xca, 0x9a, 0xc2, 0x68, 0xa9, 0xd9, 0x09, 0xcc, 0xe2, 0xe8, 0x1a, 0x3c, 0x87, 0xaa, 0x63, 0xd8,
- 0x2d, 0x6d, 0x51, 0x75, 0xc4, 0x4f, 0x51, 0x3d, 0x57, 0x3b, 0x65, 0xe6, 0xbd, 0x70, 0x89, 0xcb,
- 0x27, 0x8b, 0x48, 0x4b, 0xee, 0x5a, 0x65, 0xd5, 0xf6, 0x16, 0xf6, 0x8f, 0x1d, 0xeb, 0xe0, 0xd8,
- 0xb1, 0x0e, 0x8f, 0x1d, 0x6b, 0xaf, 0x70, 0xec, 0xfd, 0xc2, 0xb1, 0x0f, 0x0a, 0xc7, 0x3e, 0x2c,
- 0x1c, 0xfb, 0x77, 0xe1, 0xd8, 0x5f, 0xfe, 0x38, 0xd6, 0x9b, 0x6b, 0x46, 0xe4, 0x6f, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x39, 0x00, 0xe7, 0xfa, 0x0e, 0x05, 0x00, 0x00,
+ // 663 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcd, 0x4e, 0x14, 0x4d,
+ 0x14, 0xed, 0x9e, 0x1f, 0xbe, 0x99, 0x9a, 0x6f, 0x14, 0x2b, 0x31, 0x99, 0x4c, 0x62, 0x0f, 0x8e,
+ 0x1b, 0x12, 0xa4, 0x5a, 0x08, 0x41, 0x82, 0x2b, 0x5a, 0x89, 0xc1, 0x84, 0x98, 0x94, 0xe0, 0x42,
+ 0x5d, 0x58, 0xd3, 0x73, 0xe9, 0x69, 0xc7, 0xfe, 0x49, 0x55, 0xf5, 0x28, 0x3b, 0x1e, 0xc1, 0xa5,
+ 0x4b, 0x13, 0x9f, 0xc4, 0x1d, 0x4b, 0x96, 0x2c, 0xcc, 0x44, 0xda, 0x27, 0xf0, 0x0d, 0x4c, 0x55,
+ 0x17, 0xcc, 0x00, 0x31, 0xc0, 0xae, 0xeb, 0xdc, 0x7b, 0xce, 0x3d, 0xf7, 0x54, 0x17, 0x7a, 0x31,
+ 0x5c, 0x13, 0x24, 0x4c, 0xdc, 0x61, 0xd6, 0x03, 0x1e, 0x83, 0x04, 0xe1, 0x8e, 0x20, 0xee, 0x27,
+ 0xdc, 0x35, 0x05, 0x96, 0x86, 0x2e, 0xcb, 0xe4, 0x00, 0x62, 0x19, 0xfa, 0x4c, 0x86, 0x49, 0xec,
+ 0x8e, 0x96, 0x7a, 0x20, 0xd9, 0x92, 0x1b, 0x40, 0x0c, 0x9c, 0x49, 0xe8, 0x93, 0x94, 0x27, 0x32,
+ 0xc1, 0xf7, 0x0b, 0x0a, 0x61, 0x69, 0x48, 0xce, 0x53, 0x88, 0xa1, 0xb4, 0x17, 0x83, 0x50, 0x0e,
+ 0xb2, 0x1e, 0xf1, 0x93, 0xc8, 0x0d, 0x92, 0x20, 0x71, 0x35, 0xb3, 0x97, 0xed, 0xe9, 0x93, 0x3e,
+ 0xe8, 0xaf, 0x42, 0xb1, 0xbd, 0x32, 0x31, 0x11, 0x31, 0x7f, 0x10, 0xc6, 0xc0, 0xf7, 0xdd, 0x74,
+ 0x18, 0x28, 0x40, 0xb8, 0x11, 0x48, 0xe6, 0x8e, 0x2e, 0xf9, 0x68, 0xbb, 0xff, 0x62, 0xf1, 0x2c,
+ 0x96, 0x61, 0x04, 0x97, 0x08, 0xab, 0x57, 0x11, 0x84, 0x3f, 0x80, 0x88, 0x5d, 0xe4, 0x75, 0x1f,
+ 0x23, 0xb4, 0xf9, 0x59, 0x72, 0xf6, 0x9a, 0x7d, 0xcc, 0x00, 0x77, 0x50, 0x35, 0x94, 0x10, 0x89,
+ 0x96, 0x3d, 0x57, 0x9e, 0xaf, 0x7b, 0xf5, 0x7c, 0xdc, 0xa9, 0x6e, 0x29, 0x80, 0x16, 0xf8, 0x7a,
+ 0xed, 0xeb, 0xb7, 0x8e, 0x75, 0xf0, 0x73, 0xce, 0xea, 0x7e, 0x2f, 0xa1, 0xc6, 0x4e, 0x32, 0x84,
+ 0x98, 0xc2, 0x28, 0x84, 0x4f, 0xf8, 0x3d, 0xaa, 0xa9, 0x65, 0xfa, 0x4c, 0xb2, 0x96, 0x3d, 0x67,
+ 0xcf, 0x37, 0x96, 0x1f, 0x91, 0x49, 0x98, 0x67, 0x9e, 0x48, 0x3a, 0x0c, 0x14, 0x20, 0x88, 0xea,
+ 0x26, 0xa3, 0x25, 0xf2, 0xb2, 0xf7, 0x01, 0x7c, 0xb9, 0x0d, 0x92, 0x79, 0xf8, 0x70, 0xdc, 0xb1,
+ 0xf2, 0x71, 0x07, 0x4d, 0x30, 0x7a, 0xa6, 0x8a, 0x77, 0x50, 0x45, 0xa4, 0xe0, 0xb7, 0x4a, 0x5a,
+ 0x7d, 0x99, 0x5c, 0x79, 0x55, 0x64, 0xca, 0xdf, 0xab, 0x14, 0x7c, 0xef, 0x7f, 0xa3, 0x5f, 0x51,
+ 0x27, 0xaa, 0xd5, 0xf0, 0x3b, 0x34, 0x23, 0x24, 0x93, 0x99, 0x68, 0x95, 0xb5, 0xee, 0xca, 0x0d,
+ 0x75, 0x35, 0xd7, 0xbb, 0x65, 0x94, 0x67, 0x8a, 0x33, 0x35, 0x9a, 0x5d, 0x1f, 0xdd, 0xbe, 0x60,
+ 0x02, 0x3f, 0x40, 0x55, 0xa9, 0x20, 0x9d, 0x52, 0xdd, 0x6b, 0x1a, 0x66, 0xb5, 0xe8, 0x2b, 0x6a,
+ 0x78, 0x01, 0xd5, 0x59, 0xd6, 0x0f, 0x21, 0xf6, 0x41, 0xb4, 0x4a, 0xfa, 0x32, 0x9a, 0xf9, 0xb8,
+ 0x53, 0xdf, 0x38, 0x05, 0xe9, 0xa4, 0xde, 0xfd, 0x63, 0xa3, 0x3b, 0x97, 0x2c, 0xe1, 0x27, 0xa8,
+ 0x39, 0x65, 0x1f, 0xfa, 0x7a, 0x5e, 0xcd, 0xbb, 0x6b, 0xe6, 0x35, 0x37, 0xa6, 0x8b, 0xf4, 0x7c,
+ 0x2f, 0xde, 0x46, 0x95, 0x4c, 0x00, 0x37, 0x59, 0x2f, 0x5c, 0x23, 0x93, 0x5d, 0x01, 0x7c, 0x2b,
+ 0xde, 0x4b, 0x26, 0x21, 0x2b, 0x84, 0x6a, 0x19, 0xb5, 0x33, 0x70, 0x9e, 0x70, 0x9d, 0xf1, 0xd4,
+ 0xce, 0x9b, 0x0a, 0xa4, 0x45, 0xed, 0xfc, 0xce, 0x95, 0x2b, 0x76, 0xfe, 0x51, 0x42, 0xb5, 0xd3,
+ 0x91, 0xf8, 0x21, 0xaa, 0xa9, 0x31, 0x31, 0x8b, 0xc0, 0xa4, 0x3a, 0x6b, 0x26, 0xe8, 0x1e, 0x85,
+ 0xd3, 0xb3, 0x0e, 0x7c, 0x0f, 0x95, 0xb3, 0xb0, 0xaf, 0x57, 0xab, 0x7b, 0x0d, 0xd3, 0x58, 0xde,
+ 0xdd, 0x7a, 0x46, 0x15, 0x8e, 0xbb, 0x68, 0x26, 0xe0, 0x49, 0x96, 0xaa, 0x1f, 0x42, 0x79, 0x40,
+ 0xea, 0x5a, 0x9f, 0x6b, 0x84, 0x9a, 0x0a, 0x7e, 0x8b, 0xaa, 0xa0, 0x5e, 0x8d, 0xb6, 0xd9, 0x58,
+ 0x5e, 0xbd, 0x41, 0x3e, 0x44, 0x3f, 0xb7, 0xcd, 0x58, 0xf2, 0xfd, 0xa9, 0x1c, 0x14, 0x46, 0x0b,
+ 0xcd, 0x76, 0x60, 0x9e, 0xa4, 0xee, 0xc1, 0xb3, 0xa8, 0x3c, 0x84, 0xfd, 0x62, 0x2d, 0xaa, 0x3e,
+ 0xf1, 0x53, 0x54, 0x1d, 0xa9, 0xd7, 0x6a, 0x2e, 0x67, 0xf1, 0x1a, 0xc3, 0x27, 0x4f, 0x9c, 0x16,
+ 0xdc, 0xf5, 0xd2, 0x9a, 0xed, 0x2d, 0x1e, 0x9e, 0x38, 0xd6, 0xd1, 0x89, 0x63, 0x1d, 0x9f, 0x38,
+ 0xd6, 0x41, 0xee, 0xd8, 0x87, 0xb9, 0x63, 0x1f, 0xe5, 0x8e, 0x7d, 0x9c, 0x3b, 0xf6, 0xaf, 0xdc,
+ 0xb1, 0xbf, 0xfc, 0x76, 0xac, 0x37, 0xff, 0x19, 0x91, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf7,
+ 0xd6, 0x32, 0x28, 0x68, 0x05, 0x00, 0x00,
}
diff --git a/staging/src/k8s.io/api/authentication/v1beta1/generated.proto b/staging/src/k8s.io/api/authentication/v1beta1/generated.proto
index a057bc591cf..caf2a6a53af 100644
--- a/staging/src/k8s.io/api/authentication/v1beta1/generated.proto
+++ b/staging/src/k8s.io/api/authentication/v1beta1/generated.proto
@@ -57,6 +57,14 @@ message TokenReviewSpec {
// Token is the opaque bearer token.
// +optional
optional string token = 1;
+
+ // Audiences is a list of the identifiers that the resource server presented
+ // with the token identifies as. Audience-aware token authenticators will
+ // verify that the token was intended for at least one of the audiences in
+ // this list. If no audiences are provided, the audience will default to the
+ // audience of the Kubernetes apiserver.
+ // +optional
+ repeated string audiences = 2;
}
// TokenReviewStatus is the result of the token authentication request.
@@ -69,6 +77,18 @@ message TokenReviewStatus {
// +optional
optional UserInfo user = 2;
+ // Audiences are audience identifiers chosen by the authenticator that are
+ // compatible with both the TokenReview and token. An identifier is any
+ // identifier in the intersection of the TokenReviewSpec audiences and the
+ // token's audiences. A client of the TokenReview API that sets the
+ // spec.audiences field should validate that a compatible audience identifier
+ // is returned in the status.audiences field to ensure that the TokenReview
+ // server is audience aware. If a TokenReview returns an empty
+ // status.audience field where status.authenticated is "true", the token is
+ // valid against the audience of the Kubernetes API server.
+ // +optional
+ repeated string audiences = 4;
+
// Error indicates that the token couldn't be checked
// +optional
optional string error = 3;
diff --git a/staging/src/k8s.io/api/authentication/v1beta1/types.go b/staging/src/k8s.io/api/authentication/v1beta1/types.go
index a90949dc37d..0b6cba822a2 100644
--- a/staging/src/k8s.io/api/authentication/v1beta1/types.go
+++ b/staging/src/k8s.io/api/authentication/v1beta1/types.go
@@ -48,6 +48,13 @@ type TokenReviewSpec struct {
// Token is the opaque bearer token.
// +optional
Token string `json:"token,omitempty" protobuf:"bytes,1,opt,name=token"`
+ // Audiences is a list of the identifiers that the resource server presented
+ // with the token identifies as. Audience-aware token authenticators will
+ // verify that the token was intended for at least one of the audiences in
+ // this list. If no audiences are provided, the audience will default to the
+ // audience of the Kubernetes apiserver.
+ // +optional
+ Audiences []string `json:"audiences,omitempty" protobuf:"bytes,2,rep,name=audiences"`
}
// TokenReviewStatus is the result of the token authentication request.
@@ -58,6 +65,17 @@ type TokenReviewStatus struct {
// User is the UserInfo associated with the provided token.
// +optional
User UserInfo `json:"user,omitempty" protobuf:"bytes,2,opt,name=user"`
+ // Audiences are audience identifiers chosen by the authenticator that are
+ // compatible with both the TokenReview and token. An identifier is any
+ // identifier in the intersection of the TokenReviewSpec audiences and the
+ // token's audiences. A client of the TokenReview API that sets the
+ // spec.audiences field should validate that a compatible audience identifier
+ // is returned in the status.audiences field to ensure that the TokenReview
+ // server is audience aware. If a TokenReview returns an empty
+ // status.audience field where status.authenticated is "true", the token is
+ // valid against the audience of the Kubernetes API server.
+ // +optional
+ Audiences []string `json:"audiences,omitempty" protobuf:"bytes,4,rep,name=audiences"`
// Error indicates that the token couldn't be checked
// +optional
Error string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"`
diff --git a/staging/src/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go
index 968999d1ebe..8c9acfb5b24 100644
--- a/staging/src/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go
+++ b/staging/src/k8s.io/api/authentication/v1beta1/types_swagger_doc_generated.go
@@ -38,8 +38,9 @@ func (TokenReview) SwaggerDoc() map[string]string {
}
var map_TokenReviewSpec = map[string]string{
- "": "TokenReviewSpec is a description of the token authentication request.",
- "token": "Token is the opaque bearer token.",
+ "": "TokenReviewSpec is a description of the token authentication request.",
+ "token": "Token is the opaque bearer token.",
+ "audiences": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
}
func (TokenReviewSpec) SwaggerDoc() map[string]string {
@@ -50,6 +51,7 @@ var map_TokenReviewStatus = map[string]string{
"": "TokenReviewStatus is the result of the token authentication request.",
"authenticated": "Authenticated indicates that the token was associated with a known user.",
"user": "User is the UserInfo associated with the provided token.",
+ "audiences": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
"error": "Error indicates that the token couldn't be checked",
}
diff --git a/staging/src/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go
index 3a5f6d5a936..a5d82a8100a 100644
--- a/staging/src/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go
+++ b/staging/src/k8s.io/api/authentication/v1beta1/zz_generated.deepcopy.go
@@ -49,7 +49,7 @@ func (in *TokenReview) DeepCopyInto(out *TokenReview) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@@ -75,6 +75,11 @@ func (in *TokenReview) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenReviewSpec) DeepCopyInto(out *TokenReviewSpec) {
*out = *in
+ if in.Audiences != nil {
+ in, out := &in.Audiences, &out.Audiences
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
return
}
@@ -92,6 +97,11 @@ func (in *TokenReviewSpec) DeepCopy() *TokenReviewSpec {
func (in *TokenReviewStatus) DeepCopyInto(out *TokenReviewStatus) {
*out = *in
in.User.DeepCopyInto(&out.User)
+ if in.Audiences != nil {
+ in, out := &in.Audiences, &out.Audiences
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
return
}
diff --git a/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go b/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go
index 74e583a2af4..67958c3639b 100644
--- a/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go
+++ b/staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory/delegating.go
@@ -51,6 +51,8 @@ type DelegatingAuthenticatorConfig struct {
// ClientCAFile is the CA bundle file used to authenticate client certificates
ClientCAFile string
+ APIAudiences authenticator.Audiences
+
RequestHeaderConfig *RequestHeaderConfig
}
@@ -86,7 +88,7 @@ func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.Secur
}
if c.TokenAccessReviewClient != nil {
- tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient)
+ tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.APIAudiences)
if err != nil {
return nil, nil, err
}
diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go
index 3f1e1f92ed7..cf0a83b5d97 100644
--- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go
+++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go
@@ -21,8 +21,6 @@ import (
"context"
"time"
- "k8s.io/klog"
-
authentication "k8s.io/api/authentication/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -31,6 +29,7 @@ import (
"k8s.io/apiserver/pkg/util/webhook"
"k8s.io/client-go/kubernetes/scheme"
authenticationclient "k8s.io/client-go/kubernetes/typed/authentication/v1beta1"
+ "k8s.io/klog"
)
var (
@@ -45,38 +44,58 @@ var _ authenticator.Token = (*WebhookTokenAuthenticator)(nil)
type WebhookTokenAuthenticator struct {
tokenReview authenticationclient.TokenReviewInterface
initialBackoff time.Duration
+ implicitAuds authenticator.Audiences
}
// NewFromInterface creates a webhook authenticator using the given tokenReview
// client. It is recommend to wrap this authenticator with the token cache
// authenticator implemented in
// k8s.io/apiserver/pkg/authentication/token/cache.
-func NewFromInterface(tokenReview authenticationclient.TokenReviewInterface) (*WebhookTokenAuthenticator, error) {
- return newWithBackoff(tokenReview, retryBackoff)
+func NewFromInterface(tokenReview authenticationclient.TokenReviewInterface, implicitAuds authenticator.Audiences) (*WebhookTokenAuthenticator, error) {
+ return newWithBackoff(tokenReview, retryBackoff, implicitAuds)
}
-// New creates a new WebhookTokenAuthenticator from the provided kubeconfig file.
-func New(kubeConfigFile string) (*WebhookTokenAuthenticator, error) {
+// New creates a new WebhookTokenAuthenticator from the provided kubeconfig
+// file. It is recommend to wrap this authenticator with the token cache
+// authenticator implemented in
+// k8s.io/apiserver/pkg/authentication/token/cache.
+func New(kubeConfigFile string, implicitAuds authenticator.Audiences) (*WebhookTokenAuthenticator, error) {
tokenReview, err := tokenReviewInterfaceFromKubeconfig(kubeConfigFile)
if err != nil {
return nil, err
}
- return newWithBackoff(tokenReview, retryBackoff)
+ return newWithBackoff(tokenReview, retryBackoff, implicitAuds)
}
// newWithBackoff allows tests to skip the sleep.
-func newWithBackoff(tokenReview authenticationclient.TokenReviewInterface, initialBackoff time.Duration) (*WebhookTokenAuthenticator, error) {
- return &WebhookTokenAuthenticator{tokenReview, initialBackoff}, nil
+func newWithBackoff(tokenReview authenticationclient.TokenReviewInterface, initialBackoff time.Duration, implicitAuds authenticator.Audiences) (*WebhookTokenAuthenticator, error) {
+ return &WebhookTokenAuthenticator{tokenReview, initialBackoff, implicitAuds}, nil
}
// AuthenticateToken implements the authenticator.Token interface.
func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) {
+ // We take implicit audiences of the API server at WebhookTokenAuthenticator
+ // construction time. The outline of how we validate audience here is:
+ //
+ // * if the ctx is not audience limited, don't do any audience validation.
+ // * if ctx is audience-limited, add the audiences to the tokenreview spec
+ // * if the tokenreview returns with audiences in the status that intersect
+ // with the audiences in the ctx, copy into the response and return success
+ // * if the tokenreview returns without an audience in the status, ensure
+ // the ctx audiences intersect with the implicit audiences, and set the
+ // intersection in the response.
+ // * otherwise return unauthenticated.
+ wantAuds, checkAuds := authenticator.AudiencesFrom(ctx)
r := &authentication.TokenReview{
- Spec: authentication.TokenReviewSpec{Token: token},
+ Spec: authentication.TokenReviewSpec{
+ Token: token,
+ Audiences: wantAuds,
+ },
}
var (
result *authentication.TokenReview
err error
+ auds authenticator.Audiences
)
webhook.WithExponentialBackoff(w.initialBackoff, func() error {
result, err = w.tokenReview.Create(r)
@@ -87,6 +106,18 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token
klog.Errorf("Failed to make webhook authenticator request: %v", err)
return nil, false, err
}
+
+ if checkAuds {
+ gotAuds := w.implicitAuds
+ if len(result.Status.Audiences) > 0 {
+ gotAuds = result.Status.Audiences
+ }
+ auds = wantAuds.Intersect(gotAuds)
+ if len(auds) == 0 {
+ return nil, false, nil
+ }
+ }
+
r.Status = result.Status
if !r.Status.Authenticated {
return nil, false, nil
@@ -107,6 +138,7 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token
Groups: r.Status.User.Groups,
Extra: extra,
},
+ Audiences: auds,
}, true, nil
}
diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go
index 2544e2429d1..8c8855a894d 100644
--- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go
+++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook_test.go
@@ -39,6 +39,8 @@ import (
"k8s.io/client-go/tools/clientcmd/api/v1"
)
+var apiAuds = authenticator.Audiences{"api"}
+
// Service mocks a remote authentication service.
type Service interface {
// Review looks at the TokenReviewSpec and provides an authentication
@@ -105,6 +107,7 @@ func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error
type status struct {
Authenticated bool `json:"authenticated"`
User userInfo `json:"user"`
+ Audiences []string `json:"audiences"`
}
var extra map[string][]string
@@ -130,6 +133,7 @@ func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error
Groups: review.Status.User.Groups,
Extra: extra,
},
+ review.Status.Audiences,
},
}
w.Header().Set("Content-Type", "application/json")
@@ -168,7 +172,7 @@ func (m *mockService) HTTPStatusCode() int { return m.statusCode }
// newTokenAuthenticator creates a temporary kubeconfig file from the provided
// arguments and attempts to load a new WebhookTokenAuthenticator from it.
-func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration) (authenticator.Token, error) {
+func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration, implicitAuds authenticator.Audiences) (authenticator.Token, error) {
tempfile, err := ioutil.TempFile("", "")
if err != nil {
return nil, err
@@ -196,7 +200,7 @@ func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, c
return nil, err
}
- authn, err := newWithBackoff(c, 0)
+ authn, err := newWithBackoff(c, 0, implicitAuds)
if err != nil {
return nil, err
}
@@ -257,7 +261,7 @@ func TestTLSConfig(t *testing.T) {
}
defer server.Close()
- wh, err := newTokenAuthenticator(server.URL, tt.clientCert, tt.clientKey, tt.clientCA, 0)
+ wh, err := newTokenAuthenticator(server.URL, tt.clientCert, tt.clientKey, tt.clientCA, 0, nil)
if err != nil {
t.Errorf("%s: failed to create client: %v", tt.test, err)
return
@@ -312,23 +316,21 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
}
defer s.Close()
- wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 0)
- if err != nil {
- t.Fatal(err)
- }
-
expTypeMeta := metav1.TypeMeta{
APIVersion: "authentication.k8s.io/v1beta1",
Kind: "TokenReview",
}
tests := []struct {
+ description string
+ implicitAuds, reqAuds authenticator.Audiences
serverResponse v1beta1.TokenReviewStatus
expectedAuthenticated bool
expectedUser *user.DefaultInfo
+ expectedAuds authenticator.Audiences
}{
- // Successful response should pass through all user info.
{
+ description: "successful response should pass through all user info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
@@ -341,6 +343,7 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
},
},
{
+ description: "successful response should pass through all user info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
@@ -358,8 +361,8 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
Extra: map[string][]string{"foo": {"bar", "baz"}},
},
},
- // Unauthenticated shouldn't even include extra provided info.
{
+ description: "unauthenticated shouldn't even include extra provided info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: false,
User: v1beta1.UserInfo{
@@ -372,37 +375,151 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
expectedUser: nil,
},
{
+ description: "unauthenticated shouldn't even include extra provided info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: false,
},
expectedAuthenticated: false,
expectedUser: nil,
},
+ {
+ description: "good audience",
+ implicitAuds: apiAuds,
+ reqAuds: apiAuds,
+ serverResponse: v1beta1.TokenReviewStatus{
+ Authenticated: true,
+ User: v1beta1.UserInfo{
+ Username: "somebody",
+ },
+ },
+ expectedAuthenticated: true,
+ expectedUser: &user.DefaultInfo{
+ Name: "somebody",
+ },
+ expectedAuds: apiAuds,
+ },
+ {
+ description: "good audience",
+ implicitAuds: append(apiAuds, "other"),
+ reqAuds: apiAuds,
+ serverResponse: v1beta1.TokenReviewStatus{
+ Authenticated: true,
+ User: v1beta1.UserInfo{
+ Username: "somebody",
+ },
+ },
+ expectedAuthenticated: true,
+ expectedUser: &user.DefaultInfo{
+ Name: "somebody",
+ },
+ expectedAuds: apiAuds,
+ },
+ {
+ description: "bad audiences",
+ implicitAuds: apiAuds,
+ reqAuds: authenticator.Audiences{"other"},
+ serverResponse: v1beta1.TokenReviewStatus{
+ Authenticated: false,
+ },
+ expectedAuthenticated: false,
+ },
+ {
+ description: "bad audiences",
+ implicitAuds: apiAuds,
+ reqAuds: authenticator.Audiences{"other"},
+ // webhook authenticator hasn't been upgraded to support audience.
+ serverResponse: v1beta1.TokenReviewStatus{
+ Authenticated: true,
+ User: v1beta1.UserInfo{
+ Username: "somebody",
+ },
+ },
+ expectedAuthenticated: false,
+ },
+ {
+ description: "audience aware backend",
+ implicitAuds: apiAuds,
+ reqAuds: apiAuds,
+ serverResponse: v1beta1.TokenReviewStatus{
+ Authenticated: true,
+ User: v1beta1.UserInfo{
+ Username: "somebody",
+ },
+ Audiences: []string(apiAuds),
+ },
+ expectedAuthenticated: true,
+ expectedUser: &user.DefaultInfo{
+ Name: "somebody",
+ },
+ expectedAuds: apiAuds,
+ },
+ {
+ description: "audience aware backend",
+ serverResponse: v1beta1.TokenReviewStatus{
+ Authenticated: true,
+ User: v1beta1.UserInfo{
+ Username: "somebody",
+ },
+ Audiences: []string(apiAuds),
+ },
+ expectedAuthenticated: true,
+ expectedUser: &user.DefaultInfo{
+ Name: "somebody",
+ },
+ },
+ {
+ description: "audience aware backend",
+ implicitAuds: apiAuds,
+ reqAuds: apiAuds,
+ serverResponse: v1beta1.TokenReviewStatus{
+ Authenticated: true,
+ User: v1beta1.UserInfo{
+ Username: "somebody",
+ },
+ Audiences: []string{"other"},
+ },
+ expectedAuthenticated: false,
+ },
}
token := "my-s3cr3t-t0ken"
- for i, tt := range tests {
- serv.response = tt.serverResponse
- resp, authenticated, err := wh.AuthenticateToken(context.Background(), token)
- if err != nil {
- t.Errorf("case %d: authentication failed: %v", i, err)
- continue
- }
- if serv.lastRequest.Spec.Token != token {
- t.Errorf("case %d: Server did not see correct token. Got %q, expected %q.",
- i, serv.lastRequest.Spec.Token, token)
- }
- if !reflect.DeepEqual(serv.lastRequest.TypeMeta, expTypeMeta) {
- t.Errorf("case %d: Server did not see correct TypeMeta. Got %v, expected %v",
- i, serv.lastRequest.TypeMeta, expTypeMeta)
- }
- if authenticated != tt.expectedAuthenticated {
- t.Errorf("case %d: Plugin returned incorrect authentication response. Got %t, expected %t.",
- i, authenticated, tt.expectedAuthenticated)
- }
- if resp != nil && tt.expectedUser != nil && !reflect.DeepEqual(resp.User, tt.expectedUser) {
- t.Errorf("case %d: Plugin returned incorrect user. Got %#v, expected %#v",
- i, resp.User, tt.expectedUser)
- }
+ for _, tt := range tests {
+ t.Run(tt.description, func(t *testing.T) {
+ wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 0, tt.implicitAuds)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ ctx := context.Background()
+ if tt.reqAuds != nil {
+ ctx = authenticator.WithAudiences(ctx, tt.reqAuds)
+ }
+
+ serv.response = tt.serverResponse
+ resp, authenticated, err := wh.AuthenticateToken(ctx, token)
+ if err != nil {
+ t.Fatalf("authentication failed: %v", err)
+ }
+ if serv.lastRequest.Spec.Token != token {
+ t.Errorf("Server did not see correct token. Got %q, expected %q.",
+ serv.lastRequest.Spec.Token, token)
+ }
+ if !reflect.DeepEqual(serv.lastRequest.TypeMeta, expTypeMeta) {
+ t.Errorf("Server did not see correct TypeMeta. Got %v, expected %v",
+ serv.lastRequest.TypeMeta, expTypeMeta)
+ }
+ if authenticated != tt.expectedAuthenticated {
+ t.Errorf("Plugin returned incorrect authentication response. Got %t, expected %t.",
+ authenticated, tt.expectedAuthenticated)
+ }
+ if resp != nil && tt.expectedUser != nil && !reflect.DeepEqual(resp.User, tt.expectedUser) {
+ t.Errorf("Plugin returned incorrect user. Got %#v, expected %#v",
+ resp.User, tt.expectedUser)
+ }
+ if resp != nil && tt.expectedAuds != nil && !reflect.DeepEqual(resp.Audiences, tt.expectedAuds) {
+ t.Errorf("Plugin returned incorrect audiences. Got %#v, expected %#v",
+ resp.Audiences, tt.expectedAuds)
+ }
+ })
}
}
@@ -440,7 +557,7 @@ func TestWebhookCacheAndRetry(t *testing.T) {
defer s.Close()
// Create an authenticator that caches successful responses "forever" (100 days).
- wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 2400*time.Hour)
+ wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 2400*time.Hour, nil)
if err != nil {
t.Fatal(err)
}
diff --git a/test/integration/auth/auth_test.go b/test/integration/auth/auth_test.go
index 89ece409cf8..364f1d264d9 100644
--- a/test/integration/auth/auth_test.go
+++ b/test/integration/auth/auth_test.go
@@ -85,7 +85,7 @@ func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) {
if err := json.NewEncoder(kubecfgFile).Encode(config); err != nil {
return nil, err
}
- webhookTokenAuth, err := webhook.New(kubecfgFile.Name())
+ webhookTokenAuth, err := webhook.New(kubecfgFile.Name(), nil)
if err != nil {
return nil, err
}