Create and use service accounts with Configuration as Code

3 minute readSecurityScalabilityAutomation

You can manage service accounts and their tokens using Configuration as Code (CasC). CasC provides declarative configuration to define service accounts, tokens, and group memberships at root and item scope.

Define root-scoped service accounts

Define root service accounts and memberships in root-scoped groups in the CasC bundle’s rbac.yaml file. Service accounts are defined under a serviceAccounts section at the root. Each service account definition includes a name and an authentication list.

Define item-scoped service accounts

Define item-scoped service accounts and memberships in the CasC bundle’s items.yaml file. Service accounts are defined under a serviceAccounts section under an item definition. Each service account definition includes a name and an authentication list.

Configuration modes in CasC

As with RBAC in CasC, you must select either SYNC or UPDATE mode within the rbac.yaml file and within each items.yaml file to specify how service accounts, tokens, and group memberships are managed when the configuration is applied.

  • SYNC mode: Ensures that any service accounts, tokens, and group memberships not defined in CasC are removed when the configuration is applied.

  • UPDATE mode: Adds or modifies only the service accounts, tokens, and group memberships defined in CasC, leaving others unchanged.

Example CasC configuration

The following example items.yaml defines an item-scoped service account with one token and adds the service account to a group.

  • CloudBees recommends that you use ${readFile:…​} to read from secure sources like Kubernetes Secrets rather than hardcoding passwords. For details about supported secret sources and access syntax, refer to the Jenkins Configuration as Code documentation for Handling Secrets.

  • The rbac.yaml file is assumed to come from a trusted source and may use interpolation such as ${readFile:…} to define service account token passwords. However, users with only folder-level permissions can apply items.yaml files, so loading files from the server could be a security risk. Therefore, by default, the items.yaml file cannot use interpolation unless an administrator has explicitly enabled it in the CasC configuration.

removeStrategy: rbac: SYNC(1) items: NONE items: - kind: folder name: my-team serviceAccounts: - name: bot authentication: - type: password(2) id: bot-token(3) description: for CLI access(4) password: ${readFile:/run/secrets/bot-token}(5) expiration: '2027-01-01T00:00:00Z'(6) groups: - name: build-managers roles: - name: build-jobs members: serviceAccounts: - my-team/bot(7)
1 Configuration mode must be SYNC or UPDATE. Refer to Configuration modes in CasC.
2 Authentication type must be password. No other types are supported.
3 Mandatory id attribute uniquely identifies the token.
4 Optional description for the token’s purpose.
5 The password value (whether read from a file via ${readFile:…​} or hardcoded) must begin with a cloudbees_ci_sa_ prefix, followed by exactly 32 hexadecimal characters (for example, cloudbees_ci_sa_abc123def456789012345678901234ef). You can generate compliant tokens using standard tools, such as openssl rand -hex 16 on Linux/macOS.
6 Optional expiration in ISO-8601 format (must be quoted in YAML).
7 Item-scoped service accounts must be referenced by their full path.

Manage token lifecycles in CasC

When applying a CasC bundle, the token behavior depends on whether the token already exists (as identified by id) and whether the password attribute is specified:

Token type password attribute specified password attribute omitted

Existing token

The password attribute is updated. Other attributes (for example, description and expiration) are added, modified, or cleared according to what you specified in the bundle.

The password attribute remains unchanged. Other attributes (for example, description and expiration) are added, modified, or cleared according to what you specified in the bundle.

New token

The token is created with the specified password.

The token is not created, and a warning is issued.

When you export a CasC bundle, all token fields are included except password. This behavior enables token rotation in CasC while allowing the old token to be used temporarily.

Example: Rotate a token with temporary overlap

The following procedure shows how to rotate a token, allowing the old token to work until 2026-06-08:

  1. Start with your initial service account definition:

    serviceAccounts: - name: bot authentication: - type: password id: bot-token password: ${readFile:/run/secrets/bot-token}
  2. Edit the bundle on 2026-06-01, to add the new token and set an expiration on the old token:

    serviceAccounts: - name: bot authentication: - type: password id: bot-token description: deprecated, please switch to new token expiration: '2026-06-08T00:00:00Z' - type: password id: new-bot-token password: ${readFile:/run/secrets/bot-token}
  3. Change the backing Secret to a new value and apply the bundle so that both tokens work for one week.

  4. Update any scripts or tools to use the new token before 2026-06-08.

  5. After 2026-06-08, edit the bundle again to remove the old token:

    serviceAccounts: - name: bot authentication: - type: password id: new-bot-token password: ${readFile:/run/secrets/bot-token}