The Kubernetes community considers bound service account tokens as best practice although non-expiring ones are still supported.
Bound SA tokens are used for Prow components and ci-tools except the following cases in the next section.
Each SA's token is created by prowjob/periodic-ci-secret-generator
and bound to the same object secret/token-bound-object-{0|1}
in the same namespace.
To expire the tokens,
-
Bind all tokens to the other secret in the generator's configuration file, e.g., bind to
secret/token-bound-object-1
ifsecret/token-bound-object-0
currently. Create a PR and Merge it. -
Trigger
prowjob/periodic-ci-secret-generator
to generator the tokens bound to the new secret.
make job JOB=periodic-ci-secret-generator
- Delete the secret that the old tokens were previously bound to. It will expire the old tokens. Since the old secret's manifests is still in the release repo, it will be created with a new uid and to be prepared the next rotation.
oc --context ${CLUSTER} delete secret -A -l ci.openshift.io/token-bound-object=$(TOKEN_BOUND_OBJECT_NAME_SUFFIX) --dry-run=none --as system:admin
We use non-expiring tokens DPTP-3087 in the following cases:
- config-updater: Their kubeconfigs are used to manage manifests on all clusters, including the secrets of kubeconfigs for other service accounts. We break the checken-and-egg issue this way.
- The kubeconfigs that are used by the
cronjobs
on thepsi
clusters to communicate with the clusters in CI production. The secrets onpsi
are not managed by our tools because it is inside Red Hat Intranet.
The version of Non-Expiring Tokens is configured in _token.yaml. Before generating new tokens for those service accounts which use non-expiring tokens, we have to bump the token version there:
# need to install yq https://github.com/kislyuk/yq
$ make increase-token-version
Then, populate the new version in other places:
make refresh-token-version
Then create a pull request based on the changes and merge it.
To keep the maintenance simple, we should use non-expiring tokens as the last resort, i.e., only use it when bound tokens do not work for the case.
If we have to use it for a new service account, an additional required step is to ignore the SAin the service account refresher
controller of dptp-controller-manager
to void deleting the secret holding its non-expiring token.
The tokens in dptp/config-updater have to be refreshed manually. If it is for a cluster managed by us, we can get the kubeconfig by
make CLUSTER=${CLUSTER} API_SERVER_URL=$API_SERVER_URL config-updater-kubeconfig
If the cluster is not managed by the test-platform team such as vsphere
, we could use oc extract secret/config-updater -n ci --to=- --keys sa.config-updater.${CLUSTER}.config
to get the new token or ask the owners of the cluster to provide the new token if secret/config-updater
on app.ci
is still valid.
Then the secret will be refreshed with the new token after the next run of prowjob/periodic-ci-secret-bootstrap
.
In case secret/config-updater
does not work, we have to fix the secret manually because prowjob/periodic-ci-secret-bootstrap
depends on it.
$ make secret-config-updater
If the version is modified, the secrets on psi
have to be refreshed manually with the new tokens with the steps below.
$ make -C ./clusters/psi apply_credentials
After merging of the pull request, we expire the token with a previous version on every cluster:
$ make CLUSTER=${CLUSTER} EXPIRE_TOKEN_VERSION=1 DRY_RUN=none expire-token-version
Note that we have to always use a new name for the secrets (e.g, config-updater-token-version-n) that contain the non-expiring token because it would reactivate the expired token otherwise. That is the reason we cannot bounce between two secrets like we do for the bound SA's tokens. Instead, we increase the number in the secret's names each time.
On any cluster, we should keep only the latest version of those secrets.
$ make list-token-secrets
oc --context app.ci -n ci get secret -l ci.openshift.io/token-version --show-labels
NAME TYPE DATA AGE LABELS
config-updater-token-version-1 kubernetes.io/service-account-token 4 13d ci.openshift.io/non-expiring-token=true,ci.openshift.io/token-version=version-1
sync-rover-groups-updater-token-version-1 kubernetes.io/service-account-token 4 13d ci.openshift.io/non-expiring-token=true,ci.openshift.io/token-version=version-1