Service Accounts
A service account is an identity for something that is not a person: a CI pipeline, a deployment controller, an AI agent. It belongs to an Organization, authenticates with a key pair, and can do exactly what it is granted. ConfigHub stores only the public half of its keys, so there is no secret on the server to leak or rotate.
How a service account works
A service account has an identity of its own in ConfigHub, created with it. The identity is not linked to any person or to any account in your identity provider, and the only way to authenticate as it is with one of the service account's keys.
The identity's ID is the service account's UserID. It is the ID that other entities' Permissions hold when you grant the service account access, the ID a Group lists when the service account is a member, and the ID that changes made by the service account are recorded under. You rarely need to type it: cub takes the service account's name wherever it needs one.
The service account itself is an entity like any other, with a slug, labels, and Permissions of its own. Its Permissions say who may manage it and who may act as it. What it may do elsewhere is what is granted to its identity.
A service account has no Organization role unless you give it one, so a new service account can do nothing until it is granted access.
Create a service account
Anyone in the Organization can create a service account:
cub serviceaccount create deploy-bot --label team=payments
As its creator, you are given Manage and Impersonate on it (see Who can do what to a service account). The service account is given View on itself, so that it can find itself, and nothing else.
To give it an Organization role, pass --org-role. The role cannot be higher than your own:
cub serviceaccount create release-auditor --org-role viewer
cub serviceaccount list and cub serviceaccount get show what exists. get also shows the service account's UserID.
Give it a key
Generate a key pair and register its public half:
cub serviceaccount key add deploy-bot --generate deploy-bot
--generate takes an alias or a path. A bare name such as deploy-bot is stored under ~/.confighub/keys; anything with a path separator is written to that path. Only the public half is sent to ConfigHub.
To register a public key you already have, pass it as a JWK instead, with a note saying where the private key lives:
cub serviceaccount key add deploy-bot --public-key ./deploy-bot.pub.jwk --description "CI runner, us-east"
cub serviceaccount key list deploy-bot shows the service account's keys, with when each was last used.
Authenticate as the service account
Log in with the private key:
cub auth login --private-key=deploy-bot
cub signs a short-lived assertion with the key and exchanges it for a session as the service account. When the session expires, cub renews it from the key without asking.
In a pipeline, keep the private key in a secret and put it in the CONFIGHUB_AUTH_PRIVATE_KEY environment variable, either as the key itself or as the path of a file holding it. cub auth login --private-key with no value reads it from there, and CONFIGHUB_URL names the server. In GitHub Actions:
- name: Log in to ConfigHub
env:
CONFIGHUB_URL: https://hub.confighub.com
CONFIGHUB_AUTH_PRIVATE_KEY: ${{ secrets.CONFIGHUB_DEPLOY_BOT_KEY }}
run: cub auth login --private-key
Use one service account per pipeline and environment, so that each key opens only what that pipeline needs.
Grant it access
On entities
To grant a service account access to an entity, add it to the entity's permissions with --permission <Category>:serviceaccount:<name>. For example, to let deploy-bot see the payments-prod Space and change the Units in it:
cub space update --patch payments-prod --permission View:serviceaccount:deploy-bot --permission EditChildren:serviceaccount:deploy-bot
When you read the Space's Permissions back, for example with cub space get payments-prod, the service account appears as its UserID.
Remove a grant the same way, with a leading -:
cub space update --patch payments-prod --permission -EditChildren:serviceaccount:deploy-bot
A grant on an entity takes effect on the service account's next request. See Authorization for what each category allows.
Through a Group
Adding the service account to a Group gives it the Group's grants:
cub group add payments-team serviceaccount:deploy-bot
cub group remove payments-team serviceaccount:deploy-bot
The service account is named as in --permission. People's Group memberships come from your identity provider, so service accounts are the only members you add in ConfigHub.
An Organization admin or manager may change a Group's service accounts, and so may a member of the Group. Either way, you also need Manage on the service account. Since only members can look a Group up by slug, an admin or manager who is not a member names the Group by ID.
With an Organization role
cub serviceaccount update --patch deploy-bot --org-role creator
Changing the role requires Manage on the service account, and the role cannot be higher than your own.
A service account's Organization role and Groups are read when it logs in, so a change to either takes effect at its next login. Grants on entities take effect immediately.
Common grants
These are the narrowest grants for common kinds of automation.
| The automation | Grants |
|---|---|
| Changes Units in a Space and publishes a Release | View and EditChildren on the Space. If the Space's release Target is in another Space, also Use on that Target. |
| Creates variants from a base Space, for example per pull request | Organization role creator, so it can create Spaces and manages the ones it creates; Use and UseChildren on the base Space, which lets it copy the base without changing it; Use on the Target the variants release to. |
| Reports the live status of what a Target is running | ViewChildren and EditChildren on the Target. It can then read the Spaces, Units, and Releases released to the Target and record the status of those Releases, and change nothing else. |
| Reads everything, for audit or reporting | Organization role viewer. |
cub finds an entity named as <space>/<slug> by looking up the Space, which needs View on the Space. When a service account has a grant on a Target but none on the Target's Space, name the Target by its ID.
Who can do what to a service account
The service account's own Permissions decide who can do what to it:
| Category | Allows |
|---|---|
| View | Seeing the service account and listing its keys |
| Edit | Changing its labels, annotations, and display name, and deleting it |
| Manage | Changing its Permissions and its Organization role, and adding it to Groups |
| Impersonate | Registering and deleting its keys |
Registering a key is acting as the service account: whoever holds the private key can authenticate as it. Impersonate is therefore separate from Manage, and Manage does not include it. Only someone who has Impersonate can grant it to someone else:
cub serviceaccount update --patch deploy-bot --permission Impersonate:alice@example.com
A service account cannot register or delete its own keys, so a key someone else registered can always be revoked by someone else.
Organization admins and managers are allowed all of these without a grant.
Rotate and revoke keys
A service account can have several keys, so you can rotate without an outage:
- Register the new key with
cub serviceaccount key add. - Move the pipeline to the new key.
- Check
cub serviceaccount key listuntil the new key's last use is recent and the old one's has stopped changing. - Delete the old key by its thumbprint, the
Kidcolumn of the list:
cub serviceaccount key delete deploy-bot NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs
Deleting a key stops new logins with it at once. A session started with the key before it was deleted keeps working until its token expires.
Delete a service account
cub serviceaccount delete deploy-bot
Deleting a service account deletes its keys and disables its identity. The identity is kept, so the changes the service account made are still recorded under its UserID.