diff --git a/cicd-mcp-server/cloudbuild/cloudbuild.go b/cicd-mcp-server/cloudbuild/cloudbuild.go index 104c02a..5813ed8 100644 --- a/cicd-mcp-server/cloudbuild/cloudbuild.go +++ b/cicd-mcp-server/cloudbuild/cloudbuild.go @@ -135,12 +135,12 @@ func setPermissionsForCloudBuildSA(ctx context.Context, projectID, serviceAccoun gcbSARoles := []string{ "roles/artifactregistry.writer", "roles/cloudbuild.builds.editor", - "roles/cloudbuild.workerpools.use", "roles/developerconnect.tokenAccessor", "roles/logging.logWriter", "roles/run.developer", "roles/serviceusage.serviceUsageConsumer", "roles/storage.admin", + "roles/iam.serviceAccountUser", } for _, r := range gcbSARoles { _, err := iamClient.AddIAMRoleBinding(ctx, fmt.Sprintf("projects/%s", projectID), r, resolvedSA) @@ -174,14 +174,6 @@ func setPermissionsForCloudBuildSA(ctx context.Context, projectID, serviceAccoun } } - // 4. Role for the Cloud Build Service Agent on the Cloud Run SA (Default Compute SA) - defaultComputeSA := fmt.Sprintf("serviceAccount:%d-compute@developer.gserviceaccount.com", projectNumber) - resource := fmt.Sprintf("projects/%s/serviceAccounts/%s", projectID, strings.TrimPrefix(defaultComputeSA, "serviceAccount:")) - _, err = iamClient.AddIAMRoleBinding(ctx, resource, "roles/iam.serviceAccountUser", gcbP4sa) - if err != nil { - return "", fmt.Errorf("unable to add iam.serviceAccountUser role to Cloud Build P4SA %s on SA %s err: %w", gcbP4sa, defaultComputeSA, err) - } - return resolvedSA, nil } diff --git a/cicd-mcp-server/cloudbuild/cloudbuild_test.go b/cicd-mcp-server/cloudbuild/cloudbuild_test.go index 0bdcfb6..b4240cc 100644 --- a/cicd-mcp-server/cloudbuild/cloudbuild_test.go +++ b/cicd-mcp-server/cloudbuild/cloudbuild_test.go @@ -42,12 +42,12 @@ func TestSetPermissionsForCloudBuildSA(t *testing.T) { gcbSARoles := []string{ "roles/artifactregistry.writer", "roles/cloudbuild.builds.editor", - "roles/cloudbuild.workerpools.use", "roles/developerconnect.tokenAccessor", "roles/logging.logWriter", "roles/run.developer", "roles/serviceusage.serviceUsageConsumer", "roles/storage.admin", + "roles/iam.serviceAccountUser", } dcP4sa := fmt.Sprintf("serviceAccount:service-%d@gcp-sa-developerconnect.iam.gserviceaccount.com", projectNumber) gcbP4sa := fmt.Sprintf("serviceAccount:service-%d@gcp-sa-cloudbuild.iam.gserviceaccount.com", projectNumber) @@ -55,8 +55,6 @@ func TestSetPermissionsForCloudBuildSA(t *testing.T) { "roles/cloudbuild.serviceAgent", "roles/developerconnect.tokenAccessor", } - defaultComputeSA := fmt.Sprintf("%d-compute@developer.gserviceaccount.com", projectNumber) - saResource := fmt.Sprintf("projects/%s/serviceAccounts/%s", projectID, defaultComputeSA) t.Run("with service account", func(t *testing.T) { for _, r := range gcbSARoles { @@ -67,7 +65,6 @@ func TestSetPermissionsForCloudBuildSA(t *testing.T) { for _, r := range gcbP4saRoles { mockIAMClient.EXPECT().AddIAMRoleBinding(ctx, fmt.Sprintf("projects/%s", projectID), r, gcbP4sa).Return(nil, nil) } - mockIAMClient.EXPECT().AddIAMRoleBinding(ctx, saResource, "roles/iam.serviceAccountUser", gcbP4sa).Return(nil, nil) resolvedSA, err := setPermissionsForCloudBuildSA(ctx, projectID, serviceAccount, mockRMClient, mockIAMClient) assert.NoError(t, err) @@ -83,7 +80,6 @@ func TestSetPermissionsForCloudBuildSA(t *testing.T) { for _, r := range gcbP4saRoles { mockIAMClient.EXPECT().AddIAMRoleBinding(ctx, fmt.Sprintf("projects/%s", projectID), r, gcbP4sa).Return(nil, nil) } - mockIAMClient.EXPECT().AddIAMRoleBinding(ctx, saResource, "roles/iam.serviceAccountUser", gcbP4sa).Return(nil, nil) resolvedSA, err := setPermissionsForCloudBuildSA(ctx, projectID, serviceAccountWOPrefix, mockRMClient, mockIAMClient) assert.NoError(t, err) diff --git a/skills/google-cicd-pipeline-design/references/how_to_create_cloudbuild_trigger.md b/skills/google-cicd-pipeline-design/references/how_to_create_cloudbuild_trigger.md index f19f491..8c17927 100644 --- a/skills/google-cicd-pipeline-design/references/how_to_create_cloudbuild_trigger.md +++ b/skills/google-cicd-pipeline-design/references/how_to_create_cloudbuild_trigger.md @@ -44,9 +44,8 @@ Cloud Build triggers connect to source code via Developer Connect. The entire co Cloud Build triggers should **always** use a dedicated, user-managed service account instead of the default Compute Engine service account to follow the principle of least privilege. **CRITICAL: NEVER use the default Compute Engine service account (typically formatted as `[PROJECT_NUMBER]-compute@developer.gserviceaccount.com`), even if you observe existing triggers in the project using it.** -1. **Check for Service Account**: Check if a dedicated service account for Cloud Build (e.g., `cloud-build-runner@.iam.gserviceaccount.com`) already exists. -2. **Create Service Account (if needed)**: If no dedicated service account exists, create one using `gcloud iam service-accounts create`. -3. **Required Roles (Ensured Automatically)**: The `create_build_trigger` MCP tool will **automatically ensure** the necessary roles (e.g., `roles/logging.logWriter`, `roles/artifactregistry.writer`, `roles/developerconnect.tokenAccessor`, `roles/run.developer`, `roles/storage.admin`, `roles/serviceusage.serviceUsageConsumer`, `roles/cloudbuild.builds.editor`, `roles/cloudbuild.workerpools.use`, and specific IAM delegation on the default Compute SA) are granted to the relevant service accounts. You **do not** need to grant these permissions manually. +1. **Create Service Account**: Create one using `gcloud iam service-accounts create`. +3. **Required Roles (Ensured Automatically)**: Using the `create_build_trigger` MCP tool will **automatically ensure** the necessary roles are granted to the given service account. You **do not** need to grant these permissions manually. ---