Skip to main content
logoTetrate Service BridgeVersion: 1.14.x

Leveraging TSB service accounts

TSB service accounts can be leveraged internally within the platform to manage the cluster onboarding tctl install cluster-service-account and GitOps functionality, as well as externally for the 3rd-party systems to perform the configuration of various TSB features leveraging TSB API interface. The given article will focus on how TSB service accounts can be created and consumed by the external automation software leveraging tctl utility as a handler.

Working with TSB service accounts using tctl utility

Most of the interactions you need for service accounts are already available in the tctl service-account command:

tctl service-account -h
Output
Commands to manage TSB service accounts

Usage:
tctl service-account [command]

Aliases:
service-account, sa

Available Commands:
get Get one or multiple service accounts
create Creates a new service account
delete Deletes a service account
gen-key Generate a new key pair for the given service account
add-key Register a customer-supplied public key for the given service account
list-keys List the key pairs for the given service account
revoke-key Revoke one or more key pairs for the given service account
token Generate a new token that can be used to authenticate to TSB

Create a TSB service account using tctl service-account create. Private keys are returned when service accounts are created, but TSB will not store them. It is up to the client to store them securely. To learn more, please refer to YAML API Reference Guide:

tctl service-account create pipeline-sa1 > pipeline-sa1-jwk-private-key.jwk
cat pipeline-sa1-jwk-private-key.jwk
pipeline-sa1-jwk-private-key.jwk
{
"alg": "RS256",
"d": "DXxlZZcNodMTZv0XIYXglgNilwyL4gxnmu6e1zZetmtbm0oHKUx4CTlnWt_nBAinlxTzirEXClBNoDPqCh27Jg-WwbBeW01l2RPoSO7g4eM9Sz1r2KCy5o7NgptAq-_uZLy609gWDPgk8EjFT1QWMtGVXICi5StR9D0RbKazFVpgekIBPAlKoMDqwMUVM5nldIXyI6iwy4C19ZAdf0cW2HHw8rKBEMQ-bqXuD7RVkMWp18wPrnxbMpR8Xw1n4F_Wj7DqAepYezk8Vp1-uuUEnIP3rtMYbFVL1wn-nupQSAyIQIQsqvwSsGU-RD00YuPQ6hbeRTb201Ev-DvFYA1XUQ",
"dp": "lZdU20cP-G8q9dCEbFAYt15pVfzAfjy82cRlfGLjcYJFiTRyc-J8zj4VjDJSDg5CQfufQ_q_0duQi40HQH-8ihK1mPe-OZlvDc7syxbVlWIiwD4w1if-YuNWEvfyWOfa6nHsZY3utW5_SL4nvw2E-9iv_HJIJ3MkLEhZDysGvZE",
"dq": "v--gNJHrSbUMgZEuy3jfjmrgHjBM3ee6141zL3KmfeWrEK6OW8TYrVV0HBzk7Whj7ehxQmLGHVH-MykyrlKGggGtnQ1OgUpTPBhKE8j5QaXmAuO7pY1oDcOWQmqg8qu1X0X61-LmMQ42he8gGSBvcL3jWxpDSGuGeYwPJeJ9FZc",
"e": "AQAB",
"kid": "zuAiwPFQu2eI3GAGddaS1UHG08A01BA4XStF2C45uiA",
"kty": "RSA",
"n": "s5ENuvPJ9C2gMsnqFUXosXYY4k8AcnCjfUFQgUJc1FBpM15EnrgwkArZNsgHscH7ngnqIvwIf7SvM10CSkKj7dWZ6oabmdY-IFaeKIZ96EoFicNpRgkhJQREunLNtwHjvZZ_j86Vbnt4YGn6Y09y42HlEAT2NjUBiZI9C_gUmWl7smW-gZBGa4U6PsAOpi0H6Ct5dKpYJUO0qj1JLqC739nG2Exr4QEQGkFo-UaBBTTq1miHXfs1ptytYqfd64xTg0PIX0-9CfjtKrXS3hWEAWHHcChl9eHp89RU7a3bjWHbVJJVjYwcht6kFR_GX6oScGGnM4vQSR2ifh034vSA3w",
"p": "y4ynCbHHJW984_nC4UKCSF3kFjqAWG4E7K4_qJ7b5sXN7aQsWgBi6Jt6c9Paf4X3HUPDs9rbQ8ab4PJNP4r3JNc90wpvSR0b_w3E_bOtfQhbLbG5T17eO2laEpJCYWK71EVuZ2ykvuf6rkgTi4T27c9KdgJHMKQGNH7TwQFJKUU",
"q": "4dZZugK6vTlt_i2ySEuvRTAErLAVK7UWIuLQN9eeO8viX_vgoNe1L1rEN1Lb-OjdV4j5hyGMqkJ3kbCm0awDmxaR4nXVZ-GKC_mvilpfuyoYK4rm9iod_ZSuLytqr9LPnvtalaYeToNT9U7KqbzVsFY0nKTF6_ujRfqD8g282dM",
"qi": "anAZOAEZNUHf9HjqVeZiMExSZf7_OhHDceyKQ3KKI7CZSHaSj-aRtXqfAzArwpi3jDkiVQK79pt5zYKg0K47Z-X2PJ_W1tqqzAQX3Fqkdvs1c3L3Fy3w_C59N_B_QiA5e-y9J5qM1Qk12jnhlCn0DnlolwadfrkciUIS4ZdHMcs"
}

When JWK private key is acquired through the TSB service account creation step, generate an access token for the session authentication using tctl service-account token --key-path with the defined duration:

tctl service-account token pipeline-sa1 --key-path pipeline-sa1-jwk-private-key.jwk --expiration 1h30m0s
Output
eyJhbGciOiJSUzI1NiIsImtpZCI6Inp1QWl3UEZRdTJlSTNHQUdkZGFTMVVIRzA4QTAxQkE0WFN0RjJDNDV1aUEiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NTcwNTIyNTksImlhdCI6MTY1NzA1MDQ1OSwic3ViIjoibXktc2EjenVBaXdQRlF1MmVJM0dBR2RkYVMxVUhHMDhBMDFCQTRYU3RGMkM0NXVpQSIsInRzYi50ZXRyYXRlLmlvL3VzZSI6InRjdGwifQ.PRN5noVwB5RT0kFL75XjBe8pO3l90QvqpeUrR-Cw_Wt3-I4jTEWOVZXwkg6BJp0sL3cdq4wBPOCjQ8FXKrd527bIujh8f0E0Cj0obhbbSGUmAFwJO2UrvovjfXr1Ra35KHsFY6HCnTjKRxFVZ_czdYAc4s3YbOYRhiz74v1O6U9nX5jgTLl_vg9dxDUxiYYeUn1gR9_Jf0APkM48JSiZa4Bz0Ly6oGKm_GkUY003xPl4PSMFhR-4i1rYrcFH2YYP_6uUieToTrCSNchPk8S6Mh3rnkMiKTazrUnAuO5Anc3C6UlbDw9-ax18dvyKKi47wdRcjeDNPxjCSX27Qe-ryA

And configure that token in the desired tctl user profile. You can also do it all in once:

tctl config users set pipeline-sa1 --token $(tctl service-account token pipeline-sa1 --key-path pipeline-sa1-jwk-private-key.jwk --expiration 1h30m0s)

For more details how to leverage tctl to connect to TSB, please consult Connect to TSB with tctl

Bringing your own key

Available from TSB 1.14.4

By default, TSB generates a service account's key pair itself and returns the private half once, as shown above. You can instead generate the key pair yourself and register only the public half with TSB, so the private key never reaches TSB at all.

To create a service account this way, pass its public key (in JWK format) to --key-path:

tctl service-account create pipeline-sa1 --key-path pipeline-sa1-public-key.jwk

A service account created this way has no TSB-generated key, so nothing is printed to standard output except the ID of the key you registered. To add a customer-supplied key to a service account that already exists — the way you'd add a second key ahead of a rotation, or bring your own key to a service account TSB originally generated a key for — use add-key instead:

tctl service-account add-key pipeline-sa1 --key-path pipeline-sa1-public-key.jwk

Whether a service account's first key came from TSB or from a customer-supplied --key-path is recorded on the service account as keyManagement, TSB or CLIENT. It's decided once, when the service account is created, and doesn't change afterwards — you can still add keys either way after that.

The public key you supply must:

  • Carry a kid. This becomes the key's ID — the same ID list-keys and revoke-key --id use — so unlike a TSB-generated key, you choose it. It's limited to 128 letters, digits, -, . and _, and must not collide with the ID of another key already on the service account.
  • Be a public key, not a private one.
  • Be strong enough to be trusted, and use the same signature algorithm TSB will verify it with.

Configuring the algorithm and key size of generated keys

Available from TSB 1.14.4

When TSB generates a service account's key pair itself, the algorithm and — for RSA — the key size are controlled by spec.serviceAccountKeySettings on the Organization resource:

apiVersion: api.tsb.tetrate.io/v2
kind: Organization
metadata:
name: tetrate
spec:
serviceAccountKeySettings:
algorithm: RS256 # RS256 (default), ES256, ES384 or ES512
rsaKeySize: 3072 # 2048 (default), 3072 or 4096; RSA algorithms only

This only affects keys generated after you change it — existing service account keys are left as they are.

Listing and rotating keys

Available from TSB 1.14.4

list-keys shows every key pair on a service account, including when each one was added (keys created before this feature has no timestamp):

tctl service-account list-keys pipeline-sa1

A service account accepts a token signed by any key it holds until that key is revoked, which is what makes rotation safe: add the replacement key before removing the old one, rather than replacing it in place.

  1. Generate or register a new key: tctl service-account gen-key <name>, or add-key with a key you generated yourself.
  2. Install the new key wherever tokens for this service account are signed — for a CI/CD pipeline or external tool, wherever that tool reads its key from; for a control plane's service account, see below.
  3. Use list-keys to find the key ID (kid) of the key(s) you're replacing.
  4. Once nothing signs with the old key anymore and every token it issued has expired, revoke it: tctl service-account revoke-key <name> --id <old-kid>. --id can be repeated to revoke several keys in one command.

revoke-key refuses to remove every key from a service account — leaving it with none would leave it unable to authenticate — unless you pass --force. Revoking a key ID the service account doesn't have is reported and skipped rather than treated as an error, so the command is safe to repeat.

There's no single command that rotates a key for you: TSB usually needs to keep accepting tokens signed by the old key for a while after the new one is installed, and how long that takes depends on what the service account is used for.

Rotating a control plane's service account key

Each onboarded cluster has its own service account, which its control plane uses to authenticate to the management plane. Rotate it with the same add-then-revoke pattern as any other service account, using the cluster-specific commands from onboarding a cluster:

  1. Generate a new key for the cluster and render it into the control plane secrets manifest:

    tctl install cluster-service-account \
    --cluster <cluster-name-in-tsb> \
    > cluster-<cluster-name-in-tsb>-service-account.jwk

    tctl install manifest control-plane-secrets \
    --cluster <cluster-name-in-tsb> \
    --cluster-service-account="$(cat cluster-<cluster-name-in-tsb>-service-account.jwk)" \
    > controlplane-secrets.yaml

    tctl install cluster-service-account adds this key alongside the cluster's existing one rather than replacing it, so the cluster keeps authenticating with its current key until you apply the new secret.

  2. Apply the regenerated secrets to the target control plane cluster, and confirm the control plane has picked up the new key — for example by checking that it's still successfully refreshing its agent tokens against the management plane.

    kubectl apply -f controlplane-secrets.yaml
  3. Find the cluster's service account and the ID of its previous key:

    tctl service-account get
    tctl service-account list-keys <cluster-service-account-name>
  4. Once you've confirmed the control plane is using the new key, revoke the old one:

    tctl service-account revoke-key <cluster-service-account-name> --id <old-kid>
caution

Revoke the old key only after confirming the control plane has switched to the new one. Revoking it too early breaks the cluster's connection to the management plane, since a control plane that hasn't picked up the new key yet has nothing valid left to authenticate with.