Configure user-specified service accounts

To follow the principle of least privilege in Cloud Build, you can configure Cloud Build to use a service account with just enough privileges to execute a build. This page documents how to set up a service account.

If you don't specify a service account, Cloud Build may automatically select a service account to execute builds on your behalf. This service account may have permissions that are unnecessarily broad for your use case, like access to your Cloud Source Repositories and any Cloud Storage bucket in your project.

To improve the security posture of your projects and reduce the potential impact of misconfigurations or malicious users, we recommend following the principle of least privilege. Adopting this principle, you can assign to each service account the permissions and roles scoped to the task it performs. For example, you can use one service account for building and pushing images to Artifact Registry, as shown on the Google Cloud Blog.

Before you begin

  • Enable the Cloud Build and IAM APIs.

    Enable the APIs

  • If you plan to use this account to create and manage credentials, for example to create short-lived credentials, enable the IAM Service Account Credentials API.

    Enable the API

  • Create a service account, if you haven't already done so.

Grant IAM permissions

To allow your build to access the services it needs to connect to, you must grant some roles and permissions:

  1. Open the Cloud Build Settings page:

    Open the Cloud Build Settings page

    You'll see the Service account permissions tab:

    Screenshot of the Service account permissions page

  2. From the drop-down list, select the service account whose roles you want to change.

  3. Set the status of the role you want to add to Enable.

  4. If the role you need for your build pipeline is not listed here, you can grant additional roles in the IAM configurations page.

You can find additional information about the roles commonly required for a build on Configuring access to Cloud Build resources and on the full list of Cloud Build IAM roles and permissions.

Set up build logs

When you specify your own service account for builds, you must store your build logs either in Cloud Logging or in a user-created Cloud Storage bucket. You can not store your logs in the default logs bucket.

Execute a build using a config file

To manually run a build using a config file:

  1. In your project root directory, create a Cloud Build build config file named cloudbuild.yaml or cloudbuild.json.

  2. Add the serviceAccount field and the preferred logging setup.

    • If you're storing the build logs in Cloud Logging, add a logging field and set the value of the field to CLOUD_LOGGING_ONLY.

    • If you're storing the build logs in a user-created Cloud Storage bucket:

      • Add a logging field and set its value to GCS_ONLY.
      • Add a logsBucket field and set its value to your Cloud Storage bucket location.

    The following example configures Cloud Build to execute builds using a user-specified service account and configures build logs to be stored in a user-created Cloud Storage bucket:

    YAML

    steps:
    - name: 'bash'
      args: ['echo', 'Hello world!']
    logsBucket: 'LOGS_BUCKET_LOCATION'
    serviceAccount: 'projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT'
    options:
      logging: GCS_ONLY
    

    JSON

    {
      "steps": [
      {
        "name": "bash",
        "args": [
          "echo",
          "Hello world!"
        ]
      }
      ],
      "logsBucket": "LOGS_BUCKET_LOCATION",
      "serviceAccount": "projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT",
      "options": {
        "logging": "GCS_ONLY"
      }
    }
    
    

    Replace the placeholder values in your build config file with the following:

    • LOGS_BUCKET_LOCATION is the Cloud Storage bucket to store build logs. For example, gs://mylogsbucket.
    • PROJECT_ID is the ID of the Google Cloud project where you're running the build.
    • SERVICE_ACCOUNT is the email address or unique ID of the service account you want to specify for builds. For example, a service account email address looks like: service-account-name@project-id.iam.gserviceaccount.com.
  3. Start the build using the build config file:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    Replace the placeholder values in the above commands with the following:

    • CONFIG_FILE_PATH is path to the build config file.
    • SOURCE_DIRECTORY is path or URL to the source code.

    If you don't specify a CONFIG_FILE_PATH and SOURCE_DIRECTORY in the gcloud builds submit command, Cloud Build assumes that the build config file and the source code are in the current working directory.

Execute builds using triggers

To execute a build with Cloud Build triggers using your own service account, set up your preferred logging option and select your preferred service account when creating the trigger.

  1. In the build config file:

    • If you're storing the build logs in Cloud Logging, add a logging field and set the value of the field to CLOUD_LOGGING_ONLY.

    • If you're storing the build logs in a user-created Cloud Storage bucket:

      • Add a logging field and set its value to GCS_ONLY.
      • Add a logsBucket field and set its value to your Cloud Storage bucket location.

    The following example configures build logs to be stored in a user-created Cloud Storage bucket:

    YAML

    steps:
    - name: 'bash'
      args: ['echo', 'Hello world!']
    logsBucket: 'LOGS_BUCKET_LOCATION'
    options:
      logging: GCS_ONLY
    

    JSON

    {
      "steps": [
      {
        "name": "bash",
        "args": [
          "echo",
          "Hello world!"
        ]
      }
      ],
      "logsBucket": "LOGS_BUCKET_LOCATION",
      "options": {
        "logging": "GCS_ONLY"
      }
    }
    

    Replace LOGS_BUCKET_LOCATION with the Cloud Storage bucket to store build logs. For example, gs://mylogsbucket.

  2. Specify a service account to use with your build trigger:

    Console

    To run builds using the Trigger page in the Google Cloud console, the user-specified service account must be in the same project as your build trigger. To use triggers with cross-project service accounts, create the build trigger using the gcloud tool.

    1. Create or edit your build trigger.

    2. In the Service account field, specify your service account. If you do not specify a service account, Cloud Build uses the default service account.

    3. Click Create to save your build trigger.

    gcloud

    When creating a build trigger, specify your service account using the --service-account flag. In the following example, the gcloud command creates a build trigger that pulls code from a Git repository:

    gcloud builds triggers create github \
       --name=TRIGGER_NAME \
       --repo-name=REPO_NAME \
       --repo-owner=REPO_OWNER \
       --branch-pattern=BRANCH_PATTERN
       --build-config=BUILD_CONFIG_FILE
       --service-account=SERVICE_ACCOUNT
       --project=BUILD_PROJECT
    

    Replace the placeholder values in your build config file with the following:

    • TRIGGER_NAME is the name of your build trigger.
    • REPO_NAME is the name of your repository.
    • REPO_OWNER is the username of the repository owner.
    • BRANCH_PATTERN is the branch name in your repository to invoke the build on.
    • TAG_PATTERN is the tag name in your repository to invoke the build on.
    • BUILD_CONFIG_FILE is the path to your build configuration file.
    • SERVICE_ACCOUNT is your service account in the format /projects/PROJECT_ID/serviceAccounts/ACCOUNT_ID_OR_EMAIL.
    • BUILD_PROJECT is the project where you're starting builds.

Cross-project set up

If the user-specified service account is in a project that is different from the project where you're starting builds, grant the necessary access:

  • In the project that has your user-specified service account, ensure that the iam.disableCrossProjectServiceAccountUsage organization policy constraint is not enforced. This constraint is enforced by default. To disable this organization policy constraint, run the following command where SERVICE_ACCOUNT_PROJECT_ID is the project that contains your user-specified service account:

    gcloud resource-manager org-policies disable-enforce \
       iam.disableCrossProjectServiceAccountUsage \
       --project=SERVICE_ACCOUNT_PROJECT_ID
    
  • In the project that has your user-specified service account, grant the roles/iam.serviceAccountTokenCreator role for the Cloud Build service agent of the project where you're running builds:

    gcloud projects add-iam-policy-binding SERVICE_ACCOUNT_PROJECT_ID \
        --member="serviceAccount:BUILD_SERVICE_AGENT" \
        --role="roles/iam.serviceAccountTokenCreator"
    

    Replace the placeholder values in the command with the following:

    • SERVICE_ACCOUNT_PROJECT_ID: The project ID of the project that contains your user-specified service account.
    • BUILD_SERVICE_AGENT: The email ID of the service agent of the form service-BUILD_PROJECT_NUMBER@gcp-sa-cloudbuild.iam.gserviceaccount.com, where BUILD_PROJECT_NUMBER is the project number of the project where you're running builds. You can get the project number from the project settings page.

Limitations:

  • Your Google Cloud project must be in a Google Cloud organization.

  • You must start builds in the command line using gcloud builds submit or gcloud builds triggers create. To use the Triggers page in the Google Cloud console, the user-specified service account and the build trigger must be in the same project.

What's next