When a person uses the OKD CLI or web console, their API token authenticates them to the OpenShift API. However, when a regular user’s credentials are not available, it is common for components to make API calls independently. For example:
Replication controllers make API calls to create or delete pods.
Applications inside containers could make API calls for discovery purposes.
External applications could make API calls for monitoring or integration purposes.
Service accounts provide a flexible way to control API access without sharing a regular user’s credentials.
Every service account has an associated user name that can be granted roles, just like a regular user. The user name is derived from its project and name:
For example, to add the view role to the robot service account in the top-secret project:
$ oc policy add-role-to-user view system:serviceaccount:top-secret:robot
If you want to grant access to a specific service account in a project, you can
$ oc policy add-role-to-user <role_name> -z <serviceaccount_name>
If not in the project, use the
Every service account is also a member of two groups:
Includes all service accounts in the system.
Includes all service accounts in the specified project.
For example, to allow all service accounts in all projects to view resources in the top-secret project:
$ oc policy add-role-to-group view system:serviceaccount -n top-secret
To allow all service accounts in the managers project to edit resources in the top-secret project:
$ oc policy add-role-to-group edit system:serviceaccount:managers -n top-secret
Three service accounts are automatically created in every project:
Used by build pods. It is given the system:image-builder role, which allows pushing images to any image stream in the project using the internal Docker registry.
Used by deployment pods and is given the system:deployer role, which allows viewing and modifying replication controllers and pods in the project.
Used to run all other pods unless they specify a different service account.
All service accounts in a project are given the system:image-puller role, which allows pulling images from any image stream in the project using the internal Docker registry.
Service accounts are API objects that exist within each project. To manage
service accounts, you can use the
oc command with the
object type or use the web console.
To get a list of existing service accounts in the current project:
$ oc get sa NAME SECRETS AGE builder 2 2d default 2 2d deployer 2 2d
To create a new service account:
$ oc create sa robot serviceaccount "robot" created
As soon as a service account is created, two secrets are automatically added to it:
an API token
credentials for the OpenShift Container Registry
These can be seen by describing the service account:
$ oc describe sa robot Name: robot Namespace: project1 Labels: <none> Annotations: <none> Image pull secrets: robot-dockercfg-qzbhb Mountable secrets: robot-token-f4khf robot-dockercfg-qzbhb Tokens: robot-token-f4khf robot-token-z8h44
The system ensures that service accounts always have an API token and registry credentials.
The generated API token and registry credentials do not expire, but they can be revoked by deleting the secret. When the secret is deleted, a new one is automatically generated to take its place.
Service accounts authenticate to the API using tokens signed by a private RSA key. The authentication layer verifies the signature using a matching public RSA key.
To enable service account token generation, update the
stanza in the /etc/origin/master/master-config.yml file on the master to
privateKeyFile (for signing), and a matching public key file in
serviceAccountConfig: ... masterCA: ca.crt (1) privateKeyFile: serviceaccount.private.key (2) publicKeyFiles: - serviceaccount.public.key (3) - ...
|1||CA file used to validate the API server’s serving certificate.|
|2||Private RSA key file (for token signing).|
|3||Public RSA key files (for token verification). If private key files are provided, then the public key component is used. Multiple public key files can be specified, and a token will be accepted if it can be validated by one of the public keys. This allows rotation of the signing key, while still accepting tokens generated by the previous signer.|
Service accounts are required in each project to run builds, deployments, and
other pods. The
managedNames setting in the
/etc/origin/master/master-config.yml file on the master controls which
service accounts are automatically created in every project:
serviceAccountConfig: ... managedNames: (1) - builder (2) - deployer (3) - default (4) - ...
|1||List of service accounts to automatically create in every project.|
|2||A builder service account in each project is required by build pods, and is given the system:image-builder role, which allows pushing images to any image stream in the project using the internal container registry.|
|3||A deployer service account in each project is required by deployment pods, and is given the system:deployer role, which allows viewing and modifying replication controllers and pods in the project.|
|4||A default service account is used by all other pods unless they specify a different service account.|
All service accounts in a project are given the system:image-puller role, which allows pulling images from any image stream in the project using the internal container registry.
Several infrastructure controllers run using service account credentials. The following service accounts are created in the OKD infrastructure project (openshift-infra) at server start, and given the following roles cluster-wide:
Assigned the system:replication-controller role
Assigned the system:deployment-controller role
Assigned the system:build-controller role. Additionally, the build-controller service account is included in the privileged security context constraint in order to create privileged build pods.
To configure the project where those service accounts are created, set the
openshiftInfrastructureNamespace field in the
/etc/origin/master/master-config.yml file on the master:
policyConfig: ... openshiftInfrastructureNamespace: openshift-infra
limitSecretReferences field in the
/etc/origin/master/master-config.yml file on the master to
true to require
pod secret references to be whitelisted by their service accounts. Set its value
false to allow pods to reference any secret in the project.
serviceAccountConfig: ... limitSecretReferences: false
In addition to providing API credentials, a pod’s service account determines which secrets the pod is allowed to use.
Pods use secrets in two ways:
image pull secrets, providing credentials used to pull images for the pod’s containers
mountable secrets, injecting the contents of secrets into containers as files
To allow a secret to be used as an image pull secret by a service account’s pods, run:
$ oc secrets link --for=pull <serviceaccount-name> <secret-name>
To allow a secret to be mounted by a service account’s pods, run:
$ oc secrets link --for=mount <serviceaccount-name> <secret-name>
Limiting secrets to only the service accounts that reference them is disabled by
default. This means that if
This example creates and adds secrets to a service account:
$ oc secrets new secret-plans plan1.txt plan2.txt secret/secret-plans $ oc secrets new-dockercfg my-pull-secret \ --docker-username=mastermind \ --docker-password=12345 \ --email@example.com secret/my-pull-secret $ oc secrets link robot secret-plans --for=mount $ oc secrets link robot my-pull-secret --for=pull $ oc describe serviceaccount robot Name: robot Labels: <none> Image pull secrets: robot-dockercfg-624cx my-pull-secret Mountable secrets: robot-token-uzkbh robot-dockercfg-624cx secret-plans Tokens: robot-token-8bhpp robot-token-uzkbh
When a pod is created, it specifies a service account (or uses the default service account), and is allowed to use that service account’s API credentials and referenced secrets.
A file containing an API token for a pod’s service account is automatically mounted at /var/run/secrets/kubernetes.io/serviceaccount/token.
That token can be used to make API calls as the pod’s service account. This example calls the users/~ API to get information about the user identified by the token:
$ TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" $ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ "https://openshift.default.svc.cluster.local/oapi/v1/users/~" \ -H "Authorization: Bearer $TOKEN" kind: "User" apiVersion: "v1" metadata: name: "system:serviceaccount:top-secret:robot" selflink: "/oapi/v1/users/system:serviceaccount:top-secret:robot" creationTimestamp: null identities: null groups: - "system:serviceaccount" - "system:serviceaccount:top-secret"
The same token can be distributed to external applications that need to authenticate to the API.
Use the following syntax to to view a service account’s API token:
$ oc describe secret <secret-name>
$ oc describe secret robot-token-uzkbh -n top-secret Name: robot-token-uzkbh Labels: <none> Annotations: kubernetes.io/service-account.name=robot,kubernetes.io/service-account.uid=49f19e2e-16c6-11e5-afdc-3c970e4b7ffe Type: kubernetes.io/service-account-token Data token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... $ oc login --token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9... Logged into "https://server:8443" as "system:serviceaccount:top-secret:robot" using the token provided. You don't have any projects. You can try to create a new project, by running $ oc new-project <projectname> $ oc whoami system:serviceaccount:top-secret:robot