Service Accounts Management
Traditional service accounts enable organizations to take advantage of automation, but they come with a host of security concerns: lack of visibility, long-standing credentials, usability, and the threat of compromise.
BastionZero offers a solution to these drawbacks when using service accounts by providing command logs; session recordings; credential rotation; robust policy enforcement, including instant revocation; and a trustless architecture that utilizes two roots-of-trust.
A BastionZero service account is a Google, Azure, or generic service account that integrates with BastionZero by sharing its JSON Web Key Set (JWKS) URL. The headless authentication closely follows the OpenID Connect (OIDC) protocol. The JWKS contains the public key from a public/private key pair that you must generate. You use the private key to sign the service account’s identity and access tokens, and then BastionZero uses the public key within the JWKS URL to validate the service account.
BastionZero service accounts can perform many of the actions a named identity provider (IdP) user or administrator can perform (e.g., shelling into a target, uploading/downloading files from a Linux box, creating policy, and connecting to a Kubernetes cluster).
There are a few exceptions. Service accounts cannot:
- 1.Add new service accounts
- 2.Enable or disable a service account
- 3.Configure targets to recognize themselves or other service accounts
- 4.Rotate a service account’s multi-factor authentication (MFA) credentials, including its own
- 5.Change the role (user/admin) of other service accounts or users
- 6.Enable or disable MFA for users
- 7.Remove users from a BastionZero organization
- 8.Delete an IdP groups integration from a BastionZero organization
All the above actions must be done from an administrator account tied to a named IdP user.
All service accounts are added as users by default. If you would like a service account to be able to perform actions beyond a “user” role, you must modify its role after creation to be an administrator.
IMPORTANT: You must be a BastionZero administrator to set up a service account
Requirements: Service accounts require a minimum of
zli v. 6.14.0
and bzero v. 7.3.0
- 1.Create a private/public key pair by using, for example, openSSL:
openssl genrsa -out private.key 2048; openssl pkey -pubout -in private.key > public.pem
- 2.
- 3.Create a new URL that serves your JWK. This URL must adhere to the following format:
https://<url>/<service-account-username>@<service-account-domain>
.- For example, a Google service account’s URL would look like:
https://www.googleapis.com/service_accounts/v1/jwk/[email protected]
.
- 4.Create and securely store a JSON file that will serve as your provider file. This must contain the following information:
client_id
: a unique identifier chosen by you that BastionZero will use to identify your service accountprivate_key_id
: key id (kid) used when you converted your public key to JWK formatprivate_key
: private key created in step 1client_email
: service account email address (although this does not need to be a functioning email address, it must still validate against the following regex:^[a-zA-Z0-9_-][email protected](?:[a-zA-Z0-9-]+\.)+[a-zA-Z]+$)
jwksURL
: URL created in step 3jwksURLPattern
: structure of your JWKS URL (prefix and suffix). For example, if your JWKS URL werehttps://bastionzero-service-accounts/[email protected]
, the pattern would behttps://bastionzero-service-accounts/*@bastionzero.com
, wherehttps://bastionzero-service-accounts/
is your prefix and@bastionzero.com
is your suffix.
- 5.Log in to the ZLI:
zli login
. - 6.Create your BastionZero service account:
zli service-account create <provider-file.json>
. The result of this command will be abzeroCreds.json
file that you must securely store because it will be required to access your BastionZero service account. - 7.Your BastionZero service account is now added to your BastionZero organization! Next steps may include adding the service account to new or existing policies, modifying the service account’s role to be an administrator, and configuring your existing targets to recognize your service account.
- 8.Finally, once you’ve set up policy and configured any existing targets to recognize your service account (or registered a new target), log in and try connecting to a target as your service account:
zli service-account login --providerCreds /path/to/provider-file.json --bzeroCreds /path/to/bzeroCreds.json
, followed by azli connect
command.
When adding a service account, you may need to take two actions on behalf of existing targets:
- 1.Upgrade your
bzero
agent to a version (7.3.0+
) that supports BastionZero service accounts. - 2.Once the agent is at the minimum supported feature version, configure existing target(s) to recognize the service account as a valid user using:
zli service-account configure -a <service-account-username>@<service-account-domain> -t <target-name(s), delimited with spaces>
to enable the service account on a subset of existing targets, orzli service-account configure -a <service-account-username>@<service-account-domain> --all
to enable the service account on all existing targets This command will add the JWKS URL format to the targets so any future service accounts that use the same JWKS pattern (prefix and suffix) will already be configured and will require no additional action on your end. For example, if your service account email,[email protected]
, has a JWKS URL that looks likehttps://bastionzero-service-accounts/[email protected]
, future accounts that also usehttps://bastionzero-service-accounts/*@bastionzero.com
will not require further configuration.
This configuration step is not required for any targets registered after your service accounts are created. All new targets will be provided the existing service accounts'
jwksUrlPatterns
during registration. Note that if you add another service account using a new jwksUrlPattern
after target registration, you will have to configure the service account using the zli service-account configure
command, as shown above.The Google Cloud Platform (GCP) provides a convenient way of creating the public/private key pair and the JWKS URL, both of which are needed for setting up your BastionZero service account.
- 1.Using your GCP account and an existing or new project, navigate to the Identity and Access Management (IAM) & Admin menu and select the “Service Accounts” tab.
- 2.Create a new service account. Choose the service account ID carefully because this, combined with the project name, will be the BastionZero service account’s email and unique identifier. Note that the service account ID must be unique within your BastionZero organization and cannot overlap with an existing user.
- 3.Click on your newly created service account and select “Keys” in the top menu.
- 4.Add a new JSON key. GCP will prompt you to save the private key locally to your machine. This will be your provider file, and we strongly suggest saving it in a vault or other secure location.
- 5.
Azure provides a way to create and host the JWKS URL needed to use BastionZero service accounts.
- 1.Use this guide provided by Azure to create the
.well-known
OIDC configuration document. When generating the discovery document in step 2, ensure thejwks_uri
satisfies the required pattern for BastionZero service accounts (see generic service account step 3 for full details).- For example, your
jwks_uri
may be:https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_STORAGE_CONTAINER}/openid/v1/jwks/[email protected]
. Note that[email protected]
does not need to be a functioning email address.
- 2.Generate your JWKS using the next section in the Azure guide. Verify that you replace the
--name
value in step 3 with the suffix created in step 1 above (i.e.,--name openid/v1/jwks/[email protected]
). - 3.You’ve now created both the private/public key pair and the JWKS URL that serves the public key. Follow the remaining instructions in the generic service account setup starting at step 4. A few things to note:
- Your
client_email
will be the address you used above in step 1 (i.e.,[email protected]
) - You will find your key ID in the
jwks.json
file you created in step 2 - When adding your private key to your BastionZero provider file, make sure that new lines in your key are represented with a valid JSON format (
\n
).
BastionZero service accounts are primarily managed from the Zero-Trust Command Line Interface (ZLI). Full details on new and expanded ZLI commands are below.
Action | ZLI command | Role required | Notes |
---|---|---|---|
Add a new service account | zli service-account create </path/to/provider_creds.json> [--bz-creds=/path/to/write/bzcreds.json] | Non-service-account admin |
|
Configure the service account on existing target(s) | zli service-account configure --target <target-names, delimited with spaces> --service-account <service-account-email> | Non-service-account admin | If you would like to enable the service account on all existing targets, use the --all flag instead of specifying --target. |
List all service accounts | zli service-account list [-d] | User | Use the -d flag to receive additional details about your service account(s). |
Modify a service account's role (user/admin) | zli service-account set-role <admin/user> <service-account-email> | Non-service-account admin | By default, all service accounts are added as users. |
Add a service account to an existing policy | zli policy add-subject <policyName> <service-account-email> | Admin | This command can be used to add both service accounts and IdP users to an existing policy. |
Create a new policy with a service account as a subject | zli policy create-{cluster |tconnect|recording|proxy} --serviceAccounts <service account> | Admin | For all 4 policy create commands, there is a new flag --serviceAccounts, which allows you to add a service account as a subject for the new policy. |
Remove a service account from an existing policy | zli policy delete-subject <policyName> <service-account-email> | Admin | This command can be used to remove both service accounts and IdP users from an existing policy. |
Rotate a service account's TOTP MFA credential | zli service-account rotate-mfa <service-account-email> | Non-service-account admin | This command will create a new bzcreds.json file. Store this in a vault or other secure place. |
Enable/disable a service account | zli service-account <enable|disable> <service-account-email> | Non-service-account admin | Once you disable a service account, it will be deleted from all relevant policies. If you re-enable it at a later date, you must re-add the service account to all necessary policies. |
Log in with a service account | zli service-account login --creds=/path/to/providercreds.json --bz-creds=/path/to/write/bzcreds.json | User | We strongly recommend that the provider_creds.json file and the bzcreds.json file are stored in a vault or other secured place. |
Although managing your service accounts is done from the ZLI, several changes are present in the web app, as illustrated below.
You will notice a new field called “Service Accounts” in the Kubernetes, proxy, session recording, and target connect policies. This field allows you to add a service account as a policy subject and grants it access to specific targets and actions.

Service accounts generate audit logs in the same way as BastionZero users tied to an IdP account. Below is an example of the
[email protected]
service account performing the "exit" command “ as the ssm-user
on the than-bzero-agent
. Service account activity is captured in command logs, Kubernetes command logs, connections, connections events, and subject events (renamed from user events).
What used to be called “User Management” underneath the “Administration” section has been renamed to “Users & Service Accounts.” You can both disable/enable a service account from this menu and close all its active connections.

Last modified 6mo ago