aboutsummaryrefslogtreecommitdiff
path: root/vendor/k8s.io/kubernetes/pkg/serviceaccount
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/k8s.io/kubernetes/pkg/serviceaccount')
-rw-r--r--vendor/k8s.io/kubernetes/pkg/serviceaccount/claims.go186
-rw-r--r--vendor/k8s.io/kubernetes/pkg/serviceaccount/jwt.go212
-rw-r--r--vendor/k8s.io/kubernetes/pkg/serviceaccount/legacy.go135
-rw-r--r--vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go74
4 files changed, 0 insertions, 607 deletions
diff --git a/vendor/k8s.io/kubernetes/pkg/serviceaccount/claims.go b/vendor/k8s.io/kubernetes/pkg/serviceaccount/claims.go
deleted file mode 100644
index c3ed29c4c..000000000
--- a/vendor/k8s.io/kubernetes/pkg/serviceaccount/claims.go
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
-Copyright 2018 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package serviceaccount
-
-import (
- "errors"
- "fmt"
- "time"
-
- "github.com/golang/glog"
- apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount"
- "k8s.io/kubernetes/pkg/apis/core"
-
- "gopkg.in/square/go-jose.v2/jwt"
-)
-
-// time.Now stubbed out to allow testing
-var now = time.Now
-
-type privateClaims struct {
- Kubernetes kubernetes `json:"kubernetes.io,omitempty"`
-}
-
-type kubernetes struct {
- Namespace string `json:"namespace,omitempty"`
- Svcacct ref `json:"serviceaccount,omitempty"`
- Pod *ref `json:"pod,omitempty"`
- Secret *ref `json:"secret,omitempty"`
-}
-
-type ref struct {
- Name string `json:"name,omitempty"`
- UID string `json:"uid,omitempty"`
-}
-
-func Claims(sa core.ServiceAccount, pod *core.Pod, secret *core.Secret, expirationSeconds int64, audience []string) (*jwt.Claims, interface{}) {
- now := now()
- sc := &jwt.Claims{
- Subject: apiserverserviceaccount.MakeUsername(sa.Namespace, sa.Name),
- Audience: jwt.Audience(audience),
- IssuedAt: jwt.NewNumericDate(now),
- NotBefore: jwt.NewNumericDate(now),
- Expiry: jwt.NewNumericDate(now.Add(time.Duration(expirationSeconds) * time.Second)),
- }
- pc := &privateClaims{
- Kubernetes: kubernetes{
- Namespace: sa.Namespace,
- Svcacct: ref{
- Name: sa.Name,
- UID: string(sa.UID),
- },
- },
- }
- switch {
- case pod != nil:
- pc.Kubernetes.Pod = &ref{
- Name: pod.Name,
- UID: string(pod.UID),
- }
- case secret != nil:
- pc.Kubernetes.Secret = &ref{
- Name: secret.Name,
- UID: string(secret.UID),
- }
- }
- return sc, pc
-}
-
-func NewValidator(audiences []string, getter ServiceAccountTokenGetter) Validator {
- return &validator{
- auds: audiences,
- getter: getter,
- }
-}
-
-type validator struct {
- auds []string
- getter ServiceAccountTokenGetter
-}
-
-var _ = Validator(&validator{})
-
-func (v *validator) Validate(_ string, public *jwt.Claims, privateObj interface{}) (string, string, string, error) {
- private, ok := privateObj.(*privateClaims)
- if !ok {
- glog.Errorf("jwt validator expected private claim of type *privateClaims but got: %T", privateObj)
- return "", "", "", errors.New("Token could not be validated.")
- }
- err := public.Validate(jwt.Expected{
- Time: now(),
- })
- switch {
- case err == nil:
- case err == jwt.ErrExpired:
- return "", "", "", errors.New("Token has expired.")
- default:
- glog.Errorf("unexpected validation error: %T", err)
- return "", "", "", errors.New("Token could not be validated.")
- }
-
- var audValid bool
-
- for _, aud := range v.auds {
- audValid = public.Audience.Contains(aud)
- if audValid {
- break
- }
- }
-
- if !audValid {
- return "", "", "", errors.New("Token is invalid for this audience.")
- }
-
- namespace := private.Kubernetes.Namespace
- saref := private.Kubernetes.Svcacct
- podref := private.Kubernetes.Pod
- secref := private.Kubernetes.Secret
- // Make sure service account still exists (name and UID)
- serviceAccount, err := v.getter.GetServiceAccount(namespace, saref.Name)
- if err != nil {
- glog.V(4).Infof("Could not retrieve service account %s/%s: %v", namespace, saref.Name, err)
- return "", "", "", err
- }
- if serviceAccount.DeletionTimestamp != nil {
- glog.V(4).Infof("Service account has been deleted %s/%s", namespace, saref.Name)
- return "", "", "", fmt.Errorf("ServiceAccount %s/%s has been deleted", namespace, saref.Name)
- }
- if string(serviceAccount.UID) != saref.UID {
- glog.V(4).Infof("Service account UID no longer matches %s/%s: %q != %q", namespace, saref.Name, string(serviceAccount.UID), saref.UID)
- return "", "", "", fmt.Errorf("ServiceAccount UID (%s) does not match claim (%s)", serviceAccount.UID, saref.UID)
- }
-
- if secref != nil {
- // Make sure token hasn't been invalidated by deletion of the secret
- secret, err := v.getter.GetSecret(namespace, secref.Name)
- if err != nil {
- glog.V(4).Infof("Could not retrieve bound secret %s/%s for service account %s/%s: %v", namespace, secref.Name, namespace, saref.Name, err)
- return "", "", "", errors.New("Token has been invalidated")
- }
- if secret.DeletionTimestamp != nil {
- glog.V(4).Infof("Bound secret is deleted and awaiting removal: %s/%s for service account %s/%s", namespace, secref.Name, namespace, saref.Name)
- return "", "", "", errors.New("Token has been invalidated")
- }
- if string(secref.UID) != secref.UID {
- glog.V(4).Infof("Secret UID no longer matches %s/%s: %q != %q", namespace, secref.Name, string(serviceAccount.UID), secref.UID)
- return "", "", "", fmt.Errorf("Secret UID (%s) does not match claim (%s)", secret.UID, secref.UID)
- }
- }
-
- if podref != nil {
- // Make sure token hasn't been invalidated by deletion of the pod
- pod, err := v.getter.GetPod(namespace, podref.Name)
- if err != nil {
- glog.V(4).Infof("Could not retrieve bound secret %s/%s for service account %s/%s: %v", namespace, podref.Name, namespace, saref.Name, err)
- return "", "", "", errors.New("Token has been invalidated")
- }
- if pod.DeletionTimestamp != nil {
- glog.V(4).Infof("Bound pod is deleted and awaiting removal: %s/%s for service account %s/%s", namespace, podref.Name, namespace, saref.Name)
- return "", "", "", errors.New("Token has been invalidated")
- }
- if string(podref.UID) != podref.UID {
- glog.V(4).Infof("Pod UID no longer matches %s/%s: %q != %q", namespace, podref.Name, string(serviceAccount.UID), podref.UID)
- return "", "", "", fmt.Errorf("Pod UID (%s) does not match claim (%s)", pod.UID, podref.UID)
- }
- }
-
- return private.Kubernetes.Namespace, private.Kubernetes.Svcacct.Name, private.Kubernetes.Svcacct.UID, nil
-}
-
-func (v *validator) NewPrivateClaims() interface{} {
- return &privateClaims{}
-}
diff --git a/vendor/k8s.io/kubernetes/pkg/serviceaccount/jwt.go b/vendor/k8s.io/kubernetes/pkg/serviceaccount/jwt.go
deleted file mode 100644
index 01c369a31..000000000
--- a/vendor/k8s.io/kubernetes/pkg/serviceaccount/jwt.go
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
-Copyright 2014 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package serviceaccount
-
-import (
- "crypto/ecdsa"
- "crypto/elliptic"
- "crypto/rsa"
- "encoding/base64"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
-
- "k8s.io/api/core/v1"
- utilerrors "k8s.io/apimachinery/pkg/util/errors"
- "k8s.io/apiserver/pkg/authentication/authenticator"
- "k8s.io/apiserver/pkg/authentication/user"
-
- jose "gopkg.in/square/go-jose.v2"
- "gopkg.in/square/go-jose.v2/jwt"
-)
-
-// ServiceAccountTokenGetter defines functions to retrieve a named service account and secret
-type ServiceAccountTokenGetter interface {
- GetServiceAccount(namespace, name string) (*v1.ServiceAccount, error)
- GetPod(namespace, name string) (*v1.Pod, error)
- GetSecret(namespace, name string) (*v1.Secret, error)
-}
-
-type TokenGenerator interface {
- // GenerateToken generates a token which will identify the given
- // ServiceAccount. privateClaims is an interface that will be
- // serialized into the JWT payload JSON encoding at the root level of
- // the payload object. Public claims take precedent over private
- // claims i.e. if both claims and privateClaims have an "exp" field,
- // the value in claims will be used.
- GenerateToken(claims *jwt.Claims, privateClaims interface{}) (string, error)
-}
-
-// JWTTokenGenerator returns a TokenGenerator that generates signed JWT tokens, using the given privateKey.
-// privateKey is a PEM-encoded byte array of a private RSA key.
-// JWTTokenAuthenticator()
-func JWTTokenGenerator(iss string, privateKey interface{}) TokenGenerator {
- return &jwtTokenGenerator{
- iss: iss,
- privateKey: privateKey,
- }
-}
-
-type jwtTokenGenerator struct {
- iss string
- privateKey interface{}
-}
-
-func (j *jwtTokenGenerator) GenerateToken(claims *jwt.Claims, privateClaims interface{}) (string, error) {
- var alg jose.SignatureAlgorithm
- switch privateKey := j.privateKey.(type) {
- case *rsa.PrivateKey:
- alg = jose.RS256
- case *ecdsa.PrivateKey:
- switch privateKey.Curve {
- case elliptic.P256():
- alg = jose.ES256
- case elliptic.P384():
- alg = jose.ES384
- case elliptic.P521():
- alg = jose.ES512
- default:
- return "", fmt.Errorf("unknown private key curve, must be 256, 384, or 521")
- }
- default:
- return "", fmt.Errorf("unknown private key type %T, must be *rsa.PrivateKey or *ecdsa.PrivateKey", j.privateKey)
- }
-
- signer, err := jose.NewSigner(
- jose.SigningKey{
- Algorithm: alg,
- Key: j.privateKey,
- },
- nil,
- )
- if err != nil {
- return "", err
- }
-
- // claims are applied in reverse precedence
- return jwt.Signed(signer).
- Claims(privateClaims).
- Claims(claims).
- Claims(&jwt.Claims{
- Issuer: j.iss,
- }).
- CompactSerialize()
-}
-
-// JWTTokenAuthenticator authenticates tokens as JWT tokens produced by JWTTokenGenerator
-// Token signatures are verified using each of the given public keys until one works (allowing key rotation)
-// If lookup is true, the service account and secret referenced as claims inside the token are retrieved and verified with the provided ServiceAccountTokenGetter
-func JWTTokenAuthenticator(iss string, keys []interface{}, validator Validator) authenticator.Token {
- return &jwtTokenAuthenticator{
- iss: iss,
- keys: keys,
- validator: validator,
- }
-}
-
-type jwtTokenAuthenticator struct {
- iss string
- keys []interface{}
- validator Validator
-}
-
-// Validator is called by the JWT token authentictaor to apply domain specific
-// validation to a token and extract user information.
-type Validator interface {
- // Validate validates a token and returns user information or an error.
- // Validator can assume that the issuer and signature of a token are already
- // verified when this function is called.
- Validate(tokenData string, public *jwt.Claims, private interface{}) (namespace, name, uid string, err error)
- // NewPrivateClaims returns a struct that the authenticator should
- // deserialize the JWT payload into. The authenticator may then pass this
- // struct back to the Validator as the 'private' argument to a Validate()
- // call. This struct should contain fields for any private claims that the
- // Validator requires to validate the JWT.
- NewPrivateClaims() interface{}
-}
-
-var errMismatchedSigningMethod = errors.New("invalid signing method")
-
-func (j *jwtTokenAuthenticator) AuthenticateToken(tokenData string) (user.Info, bool, error) {
- if !j.hasCorrectIssuer(tokenData) {
- return nil, false, nil
- }
-
- tok, err := jwt.ParseSigned(tokenData)
- if err != nil {
- return nil, false, nil
- }
-
- public := &jwt.Claims{}
- private := j.validator.NewPrivateClaims()
-
- var (
- found bool
- errlist []error
- )
- for _, key := range j.keys {
- if err := tok.Claims(key, public, private); err != nil {
- errlist = append(errlist, err)
- continue
- }
- found = true
- break
- }
-
- if !found {
- return nil, false, utilerrors.NewAggregate(errlist)
- }
-
- // If we get here, we have a token with a recognized signature and
- // issuer string.
- ns, name, uid, err := j.validator.Validate(tokenData, public, private)
- if err != nil {
- return nil, false, err
- }
-
- return UserInfo(ns, name, uid), true, nil
-}
-
-// hasCorrectIssuer returns true if tokenData is a valid JWT in compact
-// serialization format and the "iss" claim matches the iss field of this token
-// authenticator, and otherwise returns false.
-//
-// Note: go-jose currently does not allow access to unverified JWS payloads.
-// See https://github.com/square/go-jose/issues/169
-func (j *jwtTokenAuthenticator) hasCorrectIssuer(tokenData string) bool {
- parts := strings.Split(tokenData, ".")
- if len(parts) != 3 {
- return false
- }
- payload, err := base64.RawURLEncoding.DecodeString(parts[1])
- if err != nil {
- return false
- }
- claims := struct {
- // WARNING: this JWT is not verified. Do not trust these claims.
- Issuer string `json:"iss"`
- }{}
- if err := json.Unmarshal(payload, &claims); err != nil {
- return false
- }
- if claims.Issuer != j.iss {
- return false
- }
- return true
-
-}
diff --git a/vendor/k8s.io/kubernetes/pkg/serviceaccount/legacy.go b/vendor/k8s.io/kubernetes/pkg/serviceaccount/legacy.go
deleted file mode 100644
index 5055db7cb..000000000
--- a/vendor/k8s.io/kubernetes/pkg/serviceaccount/legacy.go
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-Copyright 2018 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package serviceaccount
-
-import (
- "bytes"
- "errors"
- "fmt"
-
- "k8s.io/api/core/v1"
- apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount"
-
- "github.com/golang/glog"
- "gopkg.in/square/go-jose.v2/jwt"
-)
-
-func LegacyClaims(serviceAccount v1.ServiceAccount, secret v1.Secret) (*jwt.Claims, interface{}) {
- return &jwt.Claims{
- Subject: apiserverserviceaccount.MakeUsername(serviceAccount.Namespace, serviceAccount.Name),
- }, &legacyPrivateClaims{
- Namespace: serviceAccount.Namespace,
- ServiceAccountName: serviceAccount.Name,
- ServiceAccountUID: string(serviceAccount.UID),
- SecretName: secret.Name,
- }
-}
-
-const LegacyIssuer = "kubernetes/serviceaccount"
-
-type legacyPrivateClaims struct {
- ServiceAccountName string `json:"kubernetes.io/serviceaccount/service-account.name"`
- ServiceAccountUID string `json:"kubernetes.io/serviceaccount/service-account.uid"`
- SecretName string `json:"kubernetes.io/serviceaccount/secret.name"`
- Namespace string `json:"kubernetes.io/serviceaccount/namespace"`
-}
-
-func NewLegacyValidator(lookup bool, getter ServiceAccountTokenGetter) Validator {
- return &legacyValidator{
- lookup: lookup,
- getter: getter,
- }
-}
-
-type legacyValidator struct {
- lookup bool
- getter ServiceAccountTokenGetter
-}
-
-var _ = Validator(&legacyValidator{})
-
-func (v *legacyValidator) Validate(tokenData string, public *jwt.Claims, privateObj interface{}) (string, string, string, error) {
- private, ok := privateObj.(*legacyPrivateClaims)
- if !ok {
- glog.Errorf("jwt validator expected private claim of type *legacyPrivateClaims but got: %T", privateObj)
- return "", "", "", errors.New("Token could not be validated.")
- }
-
- // Make sure the claims we need exist
- if len(public.Subject) == 0 {
- return "", "", "", errors.New("sub claim is missing")
- }
- namespace := private.Namespace
- if len(namespace) == 0 {
- return "", "", "", errors.New("namespace claim is missing")
- }
- secretName := private.SecretName
- if len(secretName) == 0 {
- return "", "", "", errors.New("secretName claim is missing")
- }
- serviceAccountName := private.ServiceAccountName
- if len(serviceAccountName) == 0 {
- return "", "", "", errors.New("serviceAccountName claim is missing")
- }
- serviceAccountUID := private.ServiceAccountUID
- if len(serviceAccountUID) == 0 {
- return "", "", "", errors.New("serviceAccountUID claim is missing")
- }
-
- subjectNamespace, subjectName, err := apiserverserviceaccount.SplitUsername(public.Subject)
- if err != nil || subjectNamespace != namespace || subjectName != serviceAccountName {
- return "", "", "", errors.New("sub claim is invalid")
- }
-
- if v.lookup {
- // Make sure token hasn't been invalidated by deletion of the secret
- secret, err := v.getter.GetSecret(namespace, secretName)
- if err != nil {
- glog.V(4).Infof("Could not retrieve token %s/%s for service account %s/%s: %v", namespace, secretName, namespace, serviceAccountName, err)
- return "", "", "", errors.New("Token has been invalidated")
- }
- if secret.DeletionTimestamp != nil {
- glog.V(4).Infof("Token is deleted and awaiting removal: %s/%s for service account %s/%s", namespace, secretName, namespace, serviceAccountName)
- return "", "", "", errors.New("Token has been invalidated")
- }
- if bytes.Compare(secret.Data[v1.ServiceAccountTokenKey], []byte(tokenData)) != 0 {
- glog.V(4).Infof("Token contents no longer matches %s/%s for service account %s/%s", namespace, secretName, namespace, serviceAccountName)
- return "", "", "", errors.New("Token does not match server's copy")
- }
-
- // Make sure service account still exists (name and UID)
- serviceAccount, err := v.getter.GetServiceAccount(namespace, serviceAccountName)
- if err != nil {
- glog.V(4).Infof("Could not retrieve service account %s/%s: %v", namespace, serviceAccountName, err)
- return "", "", "", err
- }
- if serviceAccount.DeletionTimestamp != nil {
- glog.V(4).Infof("Service account has been deleted %s/%s", namespace, serviceAccountName)
- return "", "", "", fmt.Errorf("ServiceAccount %s/%s has been deleted", namespace, serviceAccountName)
- }
- if string(serviceAccount.UID) != serviceAccountUID {
- glog.V(4).Infof("Service account UID no longer matches %s/%s: %q != %q", namespace, serviceAccountName, string(serviceAccount.UID), serviceAccountUID)
- return "", "", "", fmt.Errorf("ServiceAccount UID (%s) does not match claim (%s)", serviceAccount.UID, serviceAccountUID)
- }
- }
-
- return private.Namespace, private.ServiceAccountName, private.ServiceAccountUID, nil
-}
-
-func (v *legacyValidator) NewPrivateClaims() interface{} {
- return &legacyPrivateClaims{}
-}
diff --git a/vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go b/vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go
deleted file mode 100644
index 0503c1513..000000000
--- a/vendor/k8s.io/kubernetes/pkg/serviceaccount/util.go
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-Copyright 2014 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package serviceaccount
-
-import (
- "k8s.io/api/core/v1"
- apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount"
- "k8s.io/apiserver/pkg/authentication/user"
- api "k8s.io/kubernetes/pkg/apis/core"
-)
-
-// UserInfo returns a user.Info interface for the given namespace, service account name and UID
-func UserInfo(namespace, name, uid string) user.Info {
- return &user.DefaultInfo{
- Name: apiserverserviceaccount.MakeUsername(namespace, name),
- UID: uid,
- Groups: apiserverserviceaccount.MakeGroupNames(namespace),
- }
-}
-
-// IsServiceAccountToken returns true if the secret is a valid api token for the service account
-func IsServiceAccountToken(secret *v1.Secret, sa *v1.ServiceAccount) bool {
- if secret.Type != v1.SecretTypeServiceAccountToken {
- return false
- }
-
- name := secret.Annotations[v1.ServiceAccountNameKey]
- uid := secret.Annotations[v1.ServiceAccountUIDKey]
- if name != sa.Name {
- // Name must match
- return false
- }
- if len(uid) > 0 && uid != string(sa.UID) {
- // If UID is specified, it must match
- return false
- }
-
- return true
-}
-
-// TODO: remove the duplicate code
-// InternalIsServiceAccountToken returns true if the secret is a valid api token for the service account
-func InternalIsServiceAccountToken(secret *api.Secret, sa *api.ServiceAccount) bool {
- if secret.Type != api.SecretTypeServiceAccountToken {
- return false
- }
-
- name := secret.Annotations[api.ServiceAccountNameKey]
- uid := secret.Annotations[api.ServiceAccountUIDKey]
- if name != sa.Name {
- // Name must match
- return false
- }
- if len(uid) > 0 && uid != string(sa.UID) {
- // If UID is specified, it must match
- return false
- }
-
- return true
-}