Authenticating

This page provides an overview of authenticating.

Users in Kubernetes

All Kubernetes clusters have two categories of users: service accounts managedby Kubernetes, and normal users.

Normal users are assumed to be managed by an outside, independent service. Anadmin distributing private keys, a user store like Keystone or Google Accounts,even a file with a list of usernames and passwords. In this regard, Kubernetesdoes not have objects which represent normal user accounts. Normal userscannot be added to a cluster through an API call.

In contrast, service accounts are users managed by the Kubernetes API. They arebound to specific namespaces, and created automatically by the API server ormanually through API calls. Service accounts are tied to a set of credentialsstored as Secrets, which are mounted into pods allowing in-cluster processesto talk to the Kubernetes API.

API requests are tied to either a normal user or a service account, or are treatedas anonymous requests. This means every process inside or outside the cluster, froma human user typing kubectl on a workstation, to kubelets on nodes, to membersof the control plane, must authenticate when making requests to the API server,or be treated as an anonymous user.

Authentication strategies

Kubernetes uses client certificates, bearer tokens, an authenticating proxy, or HTTP basic auth toauthenticate API requests through authentication plugins. As HTTP requests aremade to the API server, plugins attempt to associate the following attributeswith the request:

  • Username: a string which identifies the end user. Common values might be kube-admin or jane@example.com.
  • UID: a string which identifies the end user and attempts to be more consistent and unique than username.
  • Groups: a set of strings which associate users with a set of commonly grouped users.
  • Extra fields: a map of strings to list of strings which holds additional information authorizers may find useful.

All values are opaque to the authentication system and only hold significancewhen interpreted by an authorizer.

You can enable multiple authentication methods at once. You should usually use at least two methods:

  • service account tokens for service accounts
  • at least one other method for user authentication.

When multiple authenticator modules are enabled, the first moduleto successfully authenticate the request short-circuits evaluation.The API server does not guarantee the order authenticators run in.

The system:authenticated group is included in the list of groups for all authenticated users.

Integrations with other authentication protocols (LDAP, SAML, Kerberos, alternate x509 schemes, etc)can be accomplished using an authenticating proxy or theauthentication webhook.

X509 Client Certs

Client certificate authentication is enabled by passing the —client-ca-file=SOMEFILEoption to API server. The referenced file must contain one or more certificate authoritiesto use to validate client certificates presented to the API server. If a client certificateis presented and verified, the common name of the subject is used as the user name for therequest. As of Kubernetes 1.4, client certificates can also indicate a user’s group membershipsusing the certificate’s organization fields. To include multiple group memberships for a user,include multiple organization fields in the certificate.

For example, using the openssl command line tool to generate a certificate signing request:

  1. openssl req -new -key jbeda.pem -out jbeda-csr.pem -subj "/CN=jbeda/O=app1/O=app2"

This would create a CSR for the username “jbeda”, belonging to two groups, “app1” and “app2”.

See Managing Certificates for how to generate a client cert.

Static Token File

The API server reads bearer tokens from a file when given the —token-auth-file=SOMEFILE option on the command line. Currently, tokens last indefinitely, and the token list cannot bechanged without restarting API server.

The token file is a csv file with a minimum of 3 columns: token, user name, user uid,followed by optional group names.

Note:

If you have more than one group the column must be double quoted e.g.

  1. token,user,uid,"group1,group2,group3"

Putting a Bearer Token in a Request

When using bearer token authentication from an http client, the APIserver expects an Authorization header with a value of BearerTHETOKEN. The bearer token must be a character sequence that can beput in an HTTP header value using no more than the encoding andquoting facilities of HTTP. For example: if the bearer token is31ada4fd-adec-460c-809a-9e56ceb75269 then it would appear in an HTTPheader as shown below.

  1. Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269

Bootstrap Tokens

This feature is currently in beta.

To allow for streamlined bootstrapping for new clusters, Kubernetes includes adynamically-managed Bearer token type called a Bootstrap Token. These tokensare stored as Secrets in the kube-system namespace, where they can bedynamically managed and created. Controller Manager contains a TokenCleanercontroller that deletes bootstrap tokens as they expire.

The tokens are of the form [a-z0-9]{6}.[a-z0-9]{16}. The first component is aToken ID and the second component is the Token Secret. You specify the tokenin an HTTP header as follows:

  1. Authorization: Bearer 781292.db7bc3a58fc5f07e

You must enable the Bootstrap Token Authenticator with the—enable-bootstrap-token-auth flag on the API Server. You must enablethe TokenCleaner controller via the —controllers flag on the ControllerManager. This is done with something like —controllers=*,tokencleaner.kubeadm will do this for you if you are using it to bootstrap a cluster.

The authenticator authenticates as system:bootstrap:<Token ID>. It isincluded in the system:bootstrappers group. The naming and groups areintentionally limited to discourage users from using these tokens pastbootstrapping. The user names and group can be used (and are used by kubeadm)to craft the appropriate authorization policies to support bootstrapping acluster.

Please see Bootstrap Tokens for in depthdocumentation on the Bootstrap Token authenticator and controllers along withhow to manage these tokens with kubeadm.

Static Password File

Basic authentication is enabled by passing the —basic-auth-file=SOMEFILEoption to API server. Currently, the basic auth credentials last indefinitely,and the password cannot be changed without restarting API server. Note that basicauthentication is currently supported for convenience while we finish making themore secure modes described above easier to use.

The basic auth file is a csv file with a minimum of 3 columns: password, user name, user id.In Kubernetes version 1.6 and later, you can specify an optional fourth column containingcomma-separated group names. If you have more than one group, you must enclose the fourthcolumn value in double quotes (“). See the following example:

  1. password,user,uid,"group1,group2,group3"

When using basic authentication from an http client, the API server expects an Authorization headerwith a value of Basic BASE64ENCODED(USER:PASSWORD).

Service Account Tokens

A service account is an automatically enabled authenticator that uses signedbearer tokens to verify requests. The plugin takes two optional flags:

  • —service-account-key-file A file containing a PEM encoded key for signing bearer tokens.If unspecified, the API server’s TLS private key will be used.
  • —service-account-lookup If enabled, tokens which are deleted from the API will be revoked.

Service accounts are usually created automatically by the API server andassociated with pods running in the cluster through the ServiceAccountAdmission Controller. Bearer tokens aremounted into pods at well-known locations, and allow in-cluster processes totalk to the API server. Accounts may be explicitly associated with pods using theserviceAccountName field of a PodSpec.

Note: serviceAccountName is usually omitted because this is done automatically.
  1. apiVersion: apps/v1 # this apiVersion is relevant as of Kubernetes 1.9
  2. kind: Deployment
  3. metadata:
  4. name: nginx-deployment
  5. namespace: default
  6. spec:
  7. replicas: 3
  8. template:
  9. metadata:
  10. # ...
  11. spec:
  12. serviceAccountName: bob-the-bot
  13. containers:
  14. - name: nginx
  15. image: nginx:1.7.9

Service account bearer tokens are perfectly valid to use outside the cluster andcan be used to create identities for long standing jobs that wish to talk to theKubernetes API. To manually create a service account, simply use the kubectlcreate serviceaccount (NAME) command. This creates a service account in thecurrent namespace and an associated secret.

  1. kubectl create serviceaccount jenkins
  1. serviceaccount "jenkins" created

Check an associated secret:

  1. kubectl get serviceaccounts jenkins -o yaml
  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. # ...
  5. secrets:
  6. - name: jenkins-token-1yvwg

The created secret holds the public CA of the API server and a signed JSON WebToken (JWT).

  1. kubectl get secret jenkins-token-1yvwg -o yaml
  1. apiVersion: v1
  2. data:
  3. ca.crt: (APISERVER'S CA BASE64 ENCODED)
  4. namespace: ZGVmYXVsdA==
  5. token: (BEARER TOKEN BASE64 ENCODED)
  6. kind: Secret
  7. metadata:
  8. # ...
  9. type: kubernetes.io/service-account-token
Note: Values are base64 encoded because secrets are always base64 encoded.

The signed JWT can be used as a bearer token to authenticate as the given serviceaccount. See above for how the token is includedin a request. Normally these secrets are mounted into pods for in-cluster access tothe API server, but can be used from outside the cluster as well.

Service accounts authenticate with the username system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT),and are assigned to the groups system:serviceaccounts and system:serviceaccounts:(NAMESPACE).

WARNING: Because service account tokens are stored in secrets, any user withread access to those secrets can authenticate as the service account. Be cautiouswhen granting permissions to service accounts and read capabilities for secrets.

OpenID Connect Tokens

OpenID Connect is a flavor of OAuth2 supported bysome OAuth2 providers, notably Azure Active Directory, Salesforce, and Google.The protocol’s main extension of OAuth2 is an additional field returned withthe access token called an ID Token.This token is a JSON Web Token (JWT) with well known fields, such as a user’semail, signed by the server.

To identify the user, the authenticator uses the id_token (not the access_token)from the OAuth2 token responseas a bearer token. See above for how the tokenis included in a request.

Kubernetes OpenID Connect Flow

  • Login to your identity provider
  • Your identity provider will provide you with an access_token, id_token and a refresh_token
  • When using kubectl, use your id_token with the —token flag or add it directly to your kubeconfig
  • kubectl sends your id_token in a header called Authorization to the API server
  • The API server will make sure the JWT signature is valid by checking against the certificate named in the configuration
  • Check to make sure the id_token hasn’t expired
  • Make sure the user is authorized
  • Once authorized the API server returns a response to kubectl
  • kubectl provides feedback to the userSince all of the data needed to validate who you are is in the id_token, Kubernetes doesn’t need to“phone home” to the identity provider. In a model where every request is stateless this provides a very scalablesolution for authentication. It does offer a few challenges:

  • Kubernetes has no “web interface” to trigger the authentication process. There is no browser or interface to collect credentials which is why you need to authenticate to your identity provider first.

  • The id_token can’t be revoked, it’s like a certificate so it should be short-lived (only a few minutes) so it can be very annoying to have to get a new token every few minutes.
  • There’s no easy way to authenticate to the Kubernetes dashboard without using the kubectl proxy command or a reverse proxy that injects the id_token.

Configuring the API Server

To enable the plugin, configure the following flags on the API server:

ParameterDescriptionExampleRequired
—oidc-issuer-urlURL of the provider which allows the API server to discover public signing keys. Only URLs which use the https:// scheme are accepted. This is typically the provider’s discovery URL without a path, for example “https://accounts.google.com" or “https://login.salesforce.com". This URL should point to the level below .well-known/openid-configurationIf the discovery URL is https://accounts.google.com/.well-known/openid-configuration, the value should be https://accounts.google.comYes
—oidc-client-idA client id that all tokens must be issued for.kubernetesYes
—oidc-username-claimJWT claim to use as the user name. By default sub, which is expected to be a unique identifier of the end user. Admins can choose other claims, such as email or name, depending on their provider. However, claims other than email will be prefixed with the issuer URL to prevent naming clashes with other plugins.subNo
—oidc-username-prefixPrefix prepended to username claims to prevent clashes with existing names (such as system: users). For example, the value oidc: will create usernames like oidc:jane.doe. If this flag isn’t provided and —oidc-user-claim is a value other than email the prefix defaults to ( Issuer URL )# where ( Issuer URL ) is the value of —oidc-issuer-url. The value - can be used to disable all prefixing.oidc:No
—oidc-groups-claimJWT claim to use as the user’s group. If the claim is present it must be an array of strings.groupsNo
—oidc-groups-prefixPrefix prepended to group claims to prevent clashes with existing names (such as system: groups). For example, the value oidc: will create group names like oidc:engineering and oidc:infra.oidc:No
—oidc-required-claimA key=value pair that describes a required claim in the ID Token. If set, the claim is verified to be present in the ID Token with a matching value. Repeat this flag to specify multiple claims.claim=valueNo
—oidc-ca-fileThe path to the certificate for the CA that signed your identity provider’s web certificate. Defaults to the host’s root CAs./etc/kubernetes/ssl/kc-ca.pemNo

Importantly, the API server is not an OAuth2 client, rather it can only beconfigured to trust a single issuer. This allows the use of public providers,such as Google, without trusting credentials issued to third parties. Admins whowish to utilize multiple OAuth clients should explore providers which support theazp (authorized party) claim, a mechanism for allowing one client to issuetokens on behalf of another.

Kubernetes does not provide an OpenID Connect Identity Provider.You can use an existing public OpenID Connect Identity Provider (such as Google, or others).Or, you can run your own Identity Provider, such as CoreOS dex, Keycloak, CloudFoundry UAA, or Tremolo Security’s OpenUnison.

For an identity provider to work with Kubernetes it must:

  • Support OpenID connect discovery; not all do.
  • Run in TLS with non-obsolete ciphers
  • Have a CA signed certificate (even if the CA is not a commercial CA or is self signed)A note about requirement #3 above, requiring a CA signed certificate. If you deploy your own identity provider (as opposed to one of the cloud providers like Google or Microsoft) you MUST have your identity provider’s web server certificate signed by a certificate with the CA flag set to TRUE, even if it is self signed. This is due to GoLang’s TLS client implementation being very strict to the standards around certificate validation. If you don’t have a CA handy, you can use this script from the CoreOS team to create a simple CA and a signed certificate and key pair.Or you can use this similar script that generates SHA256 certs with a longer life and larger key size.

Setup instructions for specific systems:

Using kubectl

Option 1 - OIDC Authenticator

The first option is to use the kubectl oidc authenticator, which sets the id_token as a bearer token for all requests and refreshes the token once it expires. After you’ve logged into your provider, use kubectl to add your id_token, refresh_token, client_id, and client_secret to configure the plugin.

Providers that don’t return an id_token as part of their refresh token response aren’t supported by this plugin and should use “Option 2” below.

  1. kubectl config set-credentials USER_NAME \
  2. --auth-provider=oidc \
  3. --auth-provider-arg=idp-issuer-url=( issuer url ) \
  4. --auth-provider-arg=client-id=( your client id ) \
  5. --auth-provider-arg=client-secret=( your client secret ) \
  6. --auth-provider-arg=refresh-token=( your refresh token ) \
  7. --auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
  8. --auth-provider-arg=id-token=( your id_token )

As an example, running the below command after authenticating to your identity provider:

  1. kubectl config set-credentials mmosley \
  2. --auth-provider=oidc \
  3. --auth-provider-arg=idp-issuer-url=https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP \
  4. --auth-provider-arg=client-id=kubernetes \
  5. --auth-provider-arg=client-secret=1db158f6-177d-4d9c-8a8b-d36869918ec5 \
  6. --auth-provider-arg=refresh-token=q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXqHega4GAXlF+ma+vmYpFcHe5eZR+slBFpZKtQA= \
  7. --auth-provider-arg=idp-certificate-authority=/root/ca.pem \
  8. --auth-provider-arg=id-token=eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw

Which would produce the below configuration:

  1. users:
  2. - name: mmosley
  3. user:
  4. auth-provider:
  5. config:
  6. client-id: kubernetes
  7. client-secret: 1db158f6-177d-4d9c-8a8b-d36869918ec5
  8. id-token: eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw
  9. idp-certificate-authority: /root/ca.pem
  10. idp-issuer-url: https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP
  11. refresh-token: q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXq
  12. name: oidc

Once your id_token expires, kubectl will attempt to refresh your id_token using your refresh_token and client_secret storing the new values for the refresh_token and id_token in your .kube/config.

Option 2 - Use the —token Option

The kubectl command lets you pass in a token using the —token option. Simply copy and paste the id_token into this option:

  1. kubectl --token=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL21sYi50cmVtb2xvLmxhbjo4MDQzL2F1dGgvaWRwL29pZGMiLCJhdWQiOiJrdWJlcm5ldGVzIiwiZXhwIjoxNDc0NTk2NjY5LCJqdGkiOiI2RDUzNXoxUEpFNjJOR3QxaWVyYm9RIiwiaWF0IjoxNDc0NTk2MzY5LCJuYmYiOjE0NzQ1OTYyNDksInN1YiI6Im13aW5kdSIsInVzZXJfcm9sZSI6WyJ1c2VycyIsIm5ldy1uYW1lc3BhY2Utdmlld2VyIl0sImVtYWlsIjoibXdpbmR1QG5vbW9yZWplZGkuY29tIn0.f2As579n9VNoaKzoF-dOQGmXkFKf1FMyNV0-va_B63jn-_n9LGSCca_6IVMP8pO-Zb4KvRqGyTP0r3HkHxYy5c81AnIh8ijarruczl-TK_yF5akjSTHFZD-0gRzlevBDiH8Q79NAr-ky0P4iIXS8lY9Vnjch5MF74Zx0c3alKJHJUnnpjIACByfF2SCaYzbWFMUNat-K1PaUk5-ujMBG7yYnr95xD-63n8CO8teGUAAEMx6zRjzfhnhbzX-ajwZLGwGUBT4WqjMs70-6a7_8gZmLZb2az1cZynkFRj2BaCkVT3A2RrjeEwZEtGXlMqKJ1_I2ulrOVsYx01_yD35-rw get nodes

Webhook Token Authentication

Webhook authentication is a hook for verifying bearer tokens.

  • —authentication-token-webhook-config-file a configuration file describing how to access the remote webhook service.
  • —authentication-token-webhook-cache-ttl how long to cache authentication decisions. Defaults to two minutes.

The configuration file uses the kubeconfigfile format. Within the file, clusters refers to the remote service andusers refers to the API server webhook. An example would be:

  1. # Kubernetes API version
  2. apiVersion: v1
  3. # kind of the API object
  4. kind: Config
  5. # clusters refers to the remote service.
  6. clusters:
  7. - name: name-of-remote-authn-service
  8. cluster:
  9. certificate-authority: /path/to/ca.pem # CA for verifying the remote service.
  10. server: https://authn.example.com/authenticate # URL of remote service to query. Must use 'https'.
  11. # users refers to the API server's webhook configuration.
  12. users:
  13. - name: name-of-api-server
  14. user:
  15. client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
  16. client-key: /path/to/key.pem # key matching the cert
  17. # kubeconfig files require a context. Provide one for the API server.
  18. current-context: webhook
  19. contexts:
  20. - context:
  21. cluster: name-of-remote-authn-service
  22. user: name-of-api-sever
  23. name: webhook

When a client attempts to authenticate with the API server using a bearer tokenas discussed above,the authentication webhook POSTs a JSON-serialized authentication.k8s.io/v1beta1 TokenReview object containing the tokento the remote service. Kubernetes will not challenge a request that lacks such a header.

Note that webhook API objects are subject to the same versioning compatibility rulesas other Kubernetes API objects. Implementers should be aware of loosercompatibility promises for beta objects and check the “apiVersion” field of therequest to ensure correct deserialization. Additionally, the API server mustenable the authentication.k8s.io/v1beta1 API extensions group (—runtime-config=authentication.k8s.io/v1beta1=true).

The POST body will be of the following format:

  1. {
  2. "apiVersion": "authentication.k8s.io/v1beta1",
  3. "kind": "TokenReview",
  4. "spec": {
  5. "token": "(BEARERTOKEN)"
  6. }
  7. }

The remote service is expected to fill the status field ofthe request to indicate the success of the login. The response body’s specfield is ignored and may be omitted. A successful validation of the bearertoken would return:

  1. {
  2. "apiVersion": "authentication.k8s.io/v1beta1",
  3. "kind": "TokenReview",
  4. "status": {
  5. "authenticated": true,
  6. "user": {
  7. "username": "janedoe@example.com",
  8. "uid": "42",
  9. "groups": [
  10. "developers",
  11. "qa"
  12. ],
  13. "extra": {
  14. "extrafield1": [
  15. "extravalue1",
  16. "extravalue2"
  17. ]
  18. }
  19. }
  20. }
  21. }

An unsuccessful request would return:

  1. {
  2. "apiVersion": "authentication.k8s.io/v1beta1",
  3. "kind": "TokenReview",
  4. "status": {
  5. "authenticated": false
  6. }
  7. }

HTTP status codes can be used to supply additional error context.

Authenticating Proxy

The API server can be configured to identify users from request header values, such as X-Remote-User.It is designed for use in combination with an authenticating proxy, which sets the request header value.

  • —requestheader-username-headers Required, case-insensitive. Header names to check, in order, for the user identity. The first header containing a value is used as the username.
  • —requestheader-group-headers 1.6+. Optional, case-insensitive. “X-Remote-Group” is suggested. Header names to check, in order, for the user’s groups. All values in all specified headers are used as group names.
  • —requestheader-extra-headers-prefix 1.6+. Optional, case-insensitive. “X-Remote-Extra-” is suggested. Header prefixes to look for to determine extra information about the user (typically used by the configured authorization plugin). Any headers beginning with any of the specified prefixes have the prefix removed. The remainder of the header name is lowercased and percent-decoded and becomes the extra key, and the header value is the extra value.
Note: Prior to 1.11.3 (and 1.10.7, 1.9.11), the extra key could only contain characters which were legal in HTTP header labels.

For example, with this configuration:

  1. --requestheader-username-headers=X-Remote-User
  2. --requestheader-group-headers=X-Remote-Group
  3. --requestheader-extra-headers-prefix=X-Remote-Extra-

this request:

  1. GET / HTTP/1.1
  2. X-Remote-User: fido
  3. X-Remote-Group: dogs
  4. X-Remote-Group: dachshunds
  5. X-Remote-Extra-Acme.com%2Fproject: some-project
  6. X-Remote-Extra-Scopes: openid
  7. X-Remote-Extra-Scopes: profile

would result in this user info:

  1. name: fido
  2. groups:
  3. - dogs
  4. - dachshunds
  5. extra:
  6. acme.com/project:
  7. - some-project
  8. scopes:
  9. - openid
  10. - profile

In order to prevent header spoofing, the authenticating proxy is required to present a valid clientcertificate to the API server for validation against the specified CA before the request headers arechecked. WARNING: do not reuse a CA that is used in a different context unless you understandthe risks and the mechanisms to protect the CA’s usage.

  • —requestheader-client-ca-file Required. PEM-encoded certificate bundle. A valid client certificate must be presented and validated against the certificate authorities in the specified file before the request headers are checked for user names.
  • —requestheader-allowed-names Optional. List of Common Name values (CNs). If set, a valid client certificate with a CN in the specified list must be presented before the request headers are checked for user names. If empty, any CN is allowed.

Anonymous requests

When enabled, requests that are not rejected by other configured authentication methods aretreated as anonymous requests, and given a username of system:anonymous and a group ofsystem:unauthenticated.

For example, on a server with token authentication configured, and anonymous access enabled,a request providing an invalid bearer token would receive a 401 Unauthorized error.A request providing no bearer token would be treated as an anonymous request.

In 1.5.1-1.5.x, anonymous access is disabled by default, and can be enabled bypassing the —anonymous-auth=true option to the API server.

In 1.6+, anonymous access is enabled by default if an authorization mode other than AlwaysAllowis used, and can be disabled by passing the —anonymous-auth=false option to the API server.Starting in 1.6, the ABAC and RBAC authorizers require explicit authorization of thesystem:anonymous user or the system:unauthenticated group, so legacy policy rulesthat grant access to the user or group do not include anonymous users.

User impersonation

A user can act as another user through impersonation headers. These let requestsmanually override the user info a request authenticates as. For example, an admincould use this feature to debug an authorization policy by temporarilyimpersonating another user and seeing if a request was denied.

Impersonation requests first authenticate as the requesting user, then switchto the impersonated user info.

  • A user makes an API call with their credentials and impersonation headers.
  • API server authenticates the user.
  • API server ensures the authenticated users have impersonation privileges.
  • Request user info is replaced with impersonation values.
  • Request is evaluated, authorization acts on impersonated user info.

The following HTTP headers can be used to performing an impersonation request:

  • Impersonate-User: The username to act as.
  • Impersonate-Group: A group name to act as. Can be provided multiple times to set multiple groups. Optional. Requires “Impersonate-User”
  • Impersonate-Extra-( extra name ): A dynamic header used to associate extra fields with the user. Optional. Requires “Impersonate-User”. In order to be preserved consistently, ( extra name ) should be lower-case, and any characters which aren’t legal in HTTP header labels MUST be utf8 and percent-encoded.
Note: Prior to 1.11.3 (and 1.10.7, 1.9.11), ( extra name ) could only contain characters which were legal in HTTP header labels.

An example set of headers:

  1. Impersonate-User: jane.doe@example.com
  2. Impersonate-Group: developers
  3. Impersonate-Group: admins
  4. Impersonate-Extra-dn: cn=jane,ou=engineers,dc=example,dc=com
  5. Impersonate-Extra-acme.com%2Fproject: some-project
  6. Impersonate-Extra-scopes: view
  7. Impersonate-Extra-scopes: development

When using kubectl set the —as flag to configure the Impersonate-Userheader, set the —as-group flag to configure the Impersonate-Group header.

  1. kubectl drain mynode
  1. Error from server (Forbidden): User "clark" cannot get nodes at the cluster scope. (get nodes mynode)

Set the —as and —as-group flag:

  1. kubectl drain mynode --as=superman --as-group=system:masters
  1. node/mynode cordoned
  2. node/mynode drained

To impersonate a user, group, or set extra fields, the impersonating user musthave the ability to perform the “impersonate” verb on the kind of attributebeing impersonated (“user”, “group”, etc.). For clusters that enable the RBACauthorization plugin, the following ClusterRole encompasses the rules needed toset user and group impersonation headers:

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. name: impersonator
  5. rules:
  6. - apiGroups: [""]
  7. resources: ["users", "groups", "serviceaccounts"]
  8. verbs: ["impersonate"]

Extra fields are evaluated as sub-resources of the resource “userextras”. Toallow a user to use impersonation headers for the extra field “scopes,” a usershould be granted the following role:

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. name: scopes-impersonator
  5. rules:
  6. # Can set "Impersonate-Extra-scopes" header.
  7. - apiGroups: ["authentication.k8s.io"]
  8. resources: ["userextras/scopes"]
  9. verbs: ["impersonate"]

The values of impersonation headers can also be restricted by limiting the setof resourceNames a resource can take.

  1. apiVersion: rbac.authorization.k8s.io/v1
  2. kind: ClusterRole
  3. metadata:
  4. name: limited-impersonator
  5. rules:
  6. # Can impersonate the user "jane.doe@example.com"
  7. - apiGroups: [""]
  8. resources: ["users"]
  9. verbs: ["impersonate"]
  10. resourceNames: ["jane.doe@example.com"]
  11. # Can impersonate the groups "developers" and "admins"
  12. - apiGroups: [""]
  13. resources: ["groups"]
  14. verbs: ["impersonate"]
  15. resourceNames: ["developers","admins"]
  16. # Can impersonate the extras field "scopes" with the values "view" and "development"
  17. - apiGroups: ["authentication.k8s.io"]
  18. resources: ["userextras/scopes"]
  19. verbs: ["impersonate"]
  20. resourceNames: ["view", "development"]

client-go credential plugins

FEATURE STATE: Kubernetes v1.11betaThis feature is currently in a beta state, meaning:

  • The version names contain beta (e.g. v2beta3).
  • Code is well tested. Enabling the feature is considered safe. Enabled by default.
  • Support for the overall feature will not be dropped, though details may change.
  • The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, we will provide instructions for migrating to the next version. This may require deleting, editing, and re-creating API objects. The editing process may require some thought. This may require downtime for applications that rely on the feature.
  • Recommended for only non-business-critical uses because of potential for incompatible changes in subsequent releases. If you have multiple clusters that can be upgraded independently, you may be able to relax this restriction.
  • Please do try our beta features and give feedback on them! After they exit beta, it may not be practical for us to make more changes.

k8s.io/client-go and tools using it such as kubectl and kubelet are able to execute anexternal command to receive user credentials.

This feature is intended for client side integrations with authentication protocols not nativelysupported by k8s.io/client-go (LDAP, Kerberos, OAuth2, SAML, etc.). The plugin implements theprotocol specific logic, then returns opaque credentials to use. Almost all credential pluginuse cases require a server side component with support for the webhook token authenticatorto interpret the credential format produced by the client plugin.

Example use case

In a hypothetical use case, an organization would run an external service that exchanges LDAP credentialsfor user specific, signed tokens. The service would also be capable of responding to webhook tokenauthenticator requests to validate the tokens. Users would be requiredto install a credential plugin on their workstation.

To authenticate against the API:

  • The user issues a kubectl command.
  • Credential plugin prompts the user for LDAP credentials, exchanges credentials with external service for a token.
  • Credential plugin returns token to client-go, which uses it as a bearer token against the API server.
  • API server uses the webhook token authenticator to submit a TokenReview to the external service.
  • External service verifies the signature on the token and returns the user’s username and groups.

Configuration

Credential plugins are configured through kubectl config filesas part of the user fields.

  1. apiVersion: v1
  2. kind: Config
  3. users:
  4. - name: my-user
  5. user:
  6. exec:
  7. # Command to execute. Required.
  8. command: "example-client-go-exec-plugin"
  9. # API version to use when decoding the ExecCredentials resource. Required.
  10. #
  11. # The API version returned by the plugin MUST match the version listed here.
  12. #
  13. # To integrate with tools that support multiple versions (such as client.authentication.k8s.io/v1alpha1),
  14. # set an environment variable or pass an argument to the tool that indicates which version the exec plugin expects.
  15. apiVersion: "client.authentication.k8s.io/v1beta1"
  16. # Environment variables to set when executing the plugin. Optional.
  17. env:
  18. - name: "FOO"
  19. value: "bar"
  20. # Arguments to pass when executing the plugin. Optional.
  21. args:
  22. - "arg1"
  23. - "arg2"
  24. clusters:
  25. - name: my-cluster
  26. cluster:
  27. server: "https://172.17.4.100:6443"
  28. certificate-authority: "/etc/kubernetes/ca.pem"
  29. contexts:
  30. - name: my-cluster
  31. context:
  32. cluster: my-cluster
  33. user: my-user
  34. current-context: my-cluster

Relative command paths are interpreted as relative to the directory of the config file. IfKUBECONFIG is set to /home/jane/kubeconfig and the exec command is ./bin/example-client-go-exec-plugin,the binary /home/jane/bin/example-client-go-exec-plugin is executed.

  1. - name: my-user
  2. user:
  3. exec:
  4. # Path relative to the directory of the kubeconfig
  5. command: "./bin/example-client-go-exec-plugin"
  6. apiVersion: "client.authentication.k8s.io/v1beta1"

Input and output formats

The executed command prints an ExecCredential object to stdout. k8s.io/client-goauthenticates against the Kubernetes API using the returned credentials in the status.

When run from an interactive session, stdin is exposed directly to the plugin. Plugins should use aTTY check to determine if it’sappropriate to prompt a user interactively.

To use bearer token credentials, the plugin returns a token in the status of the ExecCredential.

  1. {
  2. "apiVersion": "client.authentication.k8s.io/v1beta1",
  3. "kind": "ExecCredential",
  4. "status": {
  5. "token": "my-bearer-token"
  6. }
  7. }

Alternatively, a PEM-encoded client certificate and key can be returned to use TLS client auth.If the plugin returns a different certificate and key on a subsequent call, k8s.io/client-gowill close existing connections with the server to force a new TLS handshake.

If specified, clientKeyData and clientCertificateData must both must be present.

clientCertificateData may contain additional intermediate certificates to send to the server.

  1. {
  2. "apiVersion": "client.authentication.k8s.io/v1beta1",
  3. "kind": "ExecCredential",
  4. "status": {
  5. "clientCertificateData": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
  6. "clientKeyData": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
  7. }
  8. }

Optionally, the response can include the expiry of the credential formatted as aRFC3339 timestamp. Presence or absence of an expiry has the following impact:

  • If an expiry is included, the bearer token and TLS credentials are cached untilthe expiry time is reached, or if the server responds with a 401 HTTP status code,or when the process exits.
  • If an expiry is omitted, the bearer token and TLS credentials are cached untilthe server responds with a 401 HTTP status code or until the process exits.
  1. {
  2. "apiVersion": "client.authentication.k8s.io/v1beta1",
  3. "kind": "ExecCredential",
  4. "status": {
  5. "token": "my-bearer-token",
  6. "expirationTimestamp": "2018-03-05T17:30:20-08:00"
  7. }
  8. }

Feedback

Was this page helpful?

Thanks for the feedback. If you have a specific, answerable question about how to use Kubernetes, ask it onStack Overflow.Open an issue in the GitHub repo if you want toreport a problemorsuggest an improvement.