Tempkey Blog
Managing Contractor Access to Google Cloud Build Without Leaking Secrets
Learn how to give freelancers and agencies the Google Cloud Build access they need for a project, keep secrets out of build logs, and remove that access when the work is done.
Managing contractor access to Google Cloud Build requires scoping Identity and Access Management (IAM) permissions down to specific build triggers and isolating execution permissions from production environments. When bringing external engineers into your continuous integration workflow, isolating permissions protects your source repositories, artifact registries, and runtime secrets from accidental exposure or unauthorized reuse.
Google Cloud Build acts as an arbitrary execution engine inside your Google Cloud environment. When you invite outside developers into a project to fix a bug or assemble a deployment pipeline, granting standard project-level permissions can inadvertently turn a simple test runner into an administrative backdoor. Safely managing contractor access to Google Cloud Build means understanding the dual nature of build pipelines: the user triggering the build and the service identity executing it.
Why Google Cloud Build Access Is Harder to Hand Out Than It Looks
Most development environments treat build tools like standard developer utilities. In Google Cloud, however, Cloud Build operates as a shared execution surface with direct access to sensitive infrastructure components. A developer who can submit a build config file (such as a cloudbuild.yaml) can execute arbitrary shell commands inside Google Cloud container instances. Those containers run within your project's networking envelope and inherit identity credentials that interact with Artifact Registry, Google Cloud Storage, Secret Manager, and runtime environments like Cloud Run or Google Kubernetes Engine (GKE).
The standard administrative instinct when onboarding a freelancer is to grant convenience roles. Predefined roles such as Cloud Build Editor (roles/cloudbuild.builds.editor) and Service Account User (roles/iam.serviceAccountUser) are fast to assign, but they give a contractor sweeping rights to view, cancel, create, and trigger builds across every pipeline in the project. If that project houses both your staging application and your production database migration routines, that single grant bridges the gap between contractor-written code and critical infrastructure.
This operational reality creates two distinct categories of operational risk:
- Dormant, unmonitored privileges: Contractors complete their scope of work, submit their final invoice, and move on to other clients. If their user identity remains bound to project IAM policies, any compromise of their personal workstation, secondary email, or stored credentials becomes an unmonitored point of ingress into your build systems months after the engagement concludes.
- Credential leakage via build logs and parameters: Cloud Build streams execution standard output and standard error into project logs. If a contractor echoes environment variables to debug a failing step, or if your pipeline accepts unencrypted parameters via build substitutions, production API keys and database strings are written directly to Cloud Logging. Anyone with log-viewing rights can inspect those values indefinitely.
Securing this environment does not require locking contractors out of modern deployment tools. Instead, it requires treating CI/CD access as a lifecycle: issuing the minimum permissions needed to run code, enforcing secret isolation during execution, setting clear grant boundaries, and validating total revocation once the project is finished.
How Google Cloud Build Permissions Actually Work
To safely scope access, you must separate the human identity submitting the build from the non-human identity executing the build steps. Google Cloud Build implements a two-tier execution model based on user permissions and service account delegation.
When a build runs, it executes under the authority of a designated service account. Historically, new projects defaulted to the legacy Cloud Build service account (formatted as [PROJECT_NUMBER]@cloudbuild.gserviceaccount.com). Today, Google Cloud emphasizes user-specified service accounts, allowing operators to run builds under custom identities tailored to specific security postures. Understanding how Cloud Build service accounts are configured is foundational to containing the blast radius of any individual build script.
The human identity—the contractor—only needs enough permission to initiate that process. Understanding standard Google Cloud Build permissions prevents unnecessary privilege escalation:
- Cloud Build Viewer (
roles/cloudbuild.builds.viewer): Grants read-only access to build configurations, statuses, and build artifacts. It does not permit the user to run builds, modify triggers, or cancel active queues. - Cloud Build Editor (
roles/cloudbuild.builds.editor): Grants permissions to create, cancel, and inspect builds, as well as create and manage build triggers across the entire project. - Service Account User (
roles/iam.serviceAccountUser): Allows a user to attach a service account to an execution process. If granted broadly across the project, the user can run arbitrary code under that service account's identity.
Triggers introduce an additional layer of abstraction. If a contractor has write access to a GitHub or GitLab repository connected to a Cloud Build trigger, they do not necessarily need direct Google Cloud IAM permissions to run code. Pushing a commit or opening a pull request can invoke the trigger automatically. In this scenario, the build executes using the service account associated with the trigger, making the repository's branch protections your primary line of defense.
Substitutions represent another common attack surface. Cloud Build allows variables to be injected into build steps using substitution variables (such as _DEPLOY_ENV or _IMAGE_TAG). If developers use substitutions to pass sensitive credentials instead of dedicated secret management, those strings are captured in plain text within the build's configuration metadata, visible to anyone with basic viewer permissions.
| Contractor Task | Standard Over-Grant | Narrowest Sufficient Role | Key Constraint |
|---|---|---|---|
| Inspect build failures | Project Viewer / Cloud Build Editor | roles/cloudbuild.builds.viewer |
Cannot trigger builds or alter configurations. |
| Trigger manual staging builds | Cloud Build Editor + Service Account User | Custom Role with cloudbuild.builds.create |
Limit Service Account User to staging SA only. |
| Update pipeline steps | Cloud Build Editor (Project Level) | Source repo PR permissions | Let trigger run via Git branch protection rules. |
| Check container build artifacts | Storage Admin / Artifact Registry Admin | roles/artifactregistry.reader |
Scope to specific staging repositories. |
Scoping Access: The Narrowest Grant That Still Lets Them Work
When provisioning external developers, avoid binding IAM roles at the Google Cloud organization or folder level. Organization-wide bindings inherit downward, granting visibility across internal tools, unrelated microservices, and compliance-sensitive infrastructure that freelancers have no reason to access.
Identity provenance matters just as much as role assignment. Avoid binding IAM roles directly to a contractor’s personal unmanaged email address. If the contractor modifies personal recovery settings, shares credentials, or experiences an account compromise, your organization lacks central administrative visibility and suspension controls. Require contractors to use an identity provisioned inside a Google Workspace domain you manage, or federate their directory identity through your primary identity provider. Controlling the identity lifecycle ensures you can suspend account access promptly at the directory level if an engagement ends early.
To implement least privilege, evaluate whether the contractor truly needs the broad Cloud Build Editor role. In many setups, external engineers only need to trigger pre-configured workflows. Instead of project-wide editing rights, you can construct a fine-grained role granting only cloudbuild.builds.create and cloudbuild.builds.get. For teams managing strict compliance requirements, reading our guide on Google Cloud IAM custom roles for contractors outlines how to package granular API permissions without distributing default administrative bundles.
Pay special attention to the Service Account User role. If a contractor requires the ability to submit builds directly via the gcloud builds submit CLI command, they must be allowed to act as the build's service account. Avoid granting roles/iam.serviceAccountUser at the project level. As detailed in Google Cloud's documentation on understanding service accounts, assigning this role across an entire project permits the user to impersonate every service account within that project, including privileged deployment identities. Instead, grant it exclusively on the specific, low-privilege service account assigned to the contractor's build pipeline:
# Correct: Grant Service Account User only on the designated build identity
gcloud iam service-accounts add-iam-policy-binding \
staging-builder@my-project.iam.gserviceaccount.com \
--member="user:contractor@example.com" \
--role="roles/iam.serviceAccountUser"
This binding ensures that even if the developer can execute workloads, they can only run them using the tightly scoped staging-builder identity, rather than attaching high-privilege compute or deployment service accounts.
Keeping Secrets Out of Build Logs and Substitutions
Build automation inevitably interacts with sensitive assets: registry signing keys, third-party package tokens, database seeds, and deployment webhooks. The most common vulnerability when onboarding outside engineers to CI/CD pipelines is exposing those values in build output. According to Google Cloud's documentation on viewing build results and logs, logs generated during pipeline execution are stored in Cloud Storage or Cloud Logging and can be inspected by anyone holding basic logging viewer permissions on the project.
Because substitution parameters appear directly in the Google Cloud Console UI under the build summary tab, passing an authentication token as a substitution variable publishes it in plain text to anyone with cloudbuild.builds.viewer. Rather than relying on substitutions for credential delivery, Google Cloud's official documentation on using secrets in Cloud Build recommends resolving credentials dynamically via Secret Manager directly within your build configuration file.
To supply credentials securely, grant the build’s specific service account the Secret Manager Secret Accessor role (roles/secretmanager.secretAccessor) on the exact secret required. Do not grant access across all secrets. Inside the cloudbuild.yaml, consume the secret using the native availableSecrets block:
steps:
- name: 'gcr.io/cloud-builders/npm'
entrypoint: 'bash'
args:
- '-c'
- |
echo "Running build with isolated tokens"
npm install
secretEnv: ['NPM_AUTH_TOKEN']
availableSecrets:
secretManager:
- versionName: projects/my-project/secrets/npm-auth-token/versions/latest
env: 'NPM_AUTH_TOKEN'
Even with Secret Manager in place, debugging habits present risks. External developers troubleshooting a failing step frequently insert commands like printenv, env, or set -x to trace build variables. If executed while a secret is loaded into the step's environment, that secret is captured permanently in the build logs. For deep dives on granular secret isolation, review our walkthrough on managing contractor access to Google Cloud Secret Manager.
To reduce your exposure surface, adopt this secret-hygiene checklist before providing build access:
- Verify that no sensitive credentials exist in build substitution defaults or inline build scripts.
- Ensure the build service account has secret access scoped only to individual secrets, not the entire project catalog.
- Restrict contractor access to Cloud Logging by withholding project-level
roles/logging.viewer; grant access strictly to Cloud Build UI logs where log masking can be monitored. - Configure ephemeral tokens or short-lived credentials instead of permanent static API keys wherever possible.
Securing CI/CD Pipelines for Freelancers and Agencies
Pipeline engineering relies on shared responsibility. The outside developer owns the functional logic of the code they write, while internal operations leads own the integrity and blast radius of the execution pipeline. Securing CI/CD pipelines for freelancers requires building structural boundaries that separate feature development from infrastructure deployment.
Start by establishing isolated build pipelines for external contributors. Do not allow untrusted pull requests or external contractor commits to trigger pipelines that contain production deployment stages or elevated credentials. Configure separate Cloud Build triggers for feature validation. For example, create a trigger that runs unit tests and static linting inside a minimal container, while reserving deployment triggers for branches requiring internal maintainer review and signed commits.
Branch protection within your code hosting platform (GitHub, GitLab, or Bitbucket) is your primary defense against pipeline tampering. Because Cloud Build triggers can watch repository branches, a contractor with direct push access to a staging branch can modify cloudbuild.yaml directly, executing custom scripts under the build service account. Ensure that any modification to CI configuration files requires an explicit review approval from a full-time staff engineer.
Implement an artifact promotion pattern rather than building directly into production-ready repositories. In this pattern:
- Contractor code builds and outputs container images exclusively to a non-production repository in Artifact Registry (for example,
projects/my-project/locations/us-central1/repositories/staging-repo). - Contractors possess read and write access only to this staging artifact path.
- A completely independent, internally controlled pipeline validates the image, runs vulnerability scans, and promotes it to the production registry.
This operational strategy applies across modern build automation systems. If your organization operates a multi-cloud or hybrid CI structure, compare this operational setup to our recommendations for CircleCI contractor access management, where runner isolation and context scoping solve analogous challenges.
To decide whether a contractor should share an existing build pipeline or receive an isolated workflow, evaluate these criteria:
- Direct Deployment vs. Package Compilation: If the pipeline merely packages an application asset (such as compiling a React frontend bundle), shared read triggers are acceptable. If the pipeline runs deployment steps (such as applying Terraform configurations or invoking
gcloud run deploy), the contractor must be restricted to an isolated sandbox pipeline. - Secret Access Requirements: If the build requires access to proprietary third-party API keys or sensitive integration endpoints, do not run builds directly against unvetted contractor pull requests. Instead, utilize mocked dependencies for contractor validation runs.
Time-Boxing Access: Grants That Expire on Their Own
The primary operational failure in contractor lifecycle management is the persistence of forgotten permissions. At the beginning of a sprint, access is provisioned rapidly to unblock development. At the end of the contract, offboarding is regularly omitted because teams lack a structured process or forget to set a calendar alert. Weeks later, external parties retain valid permissions across your build tooling.
Modern access control demands time-boxing: permissions should be granted with an explicit expiration date baked into the grant itself. While Google Cloud supports IAM Conditions to enforce temporary date-time constraints for specific resources, managing conditional bindings manually across multiple IAM roles, service accounts, and linked source repositories creates operational drag. Manual conditions do not constitute an end-to-end offboarding system; they do not handle accompanying tools like code repositories, communication channels, or related project trackers.
This challenge is where specialized access management tools streamline the operational workflow. Tempkey grants contractors and freelancers access to company tools for a set period and revokes it automatically when the grant expires. Rather than relying on an administrator to manually remember a calendar reminder on a Friday afternoon, access windows close automatically.
Crucially, effective security requires verification, not just command execution. On natively enforced providers, Tempkey reads provider state back after revoking to confirm access was actually removed. Tempkey natively enforces access on 10 providers — Slack, Google Workspace, Microsoft 365, GitHub, GitLab, Zoom, AWS IAM, Figma, Dropbox, and Asana. Notion and Trello are limited-native (tracked, not fully enforced) and Zapier/Make are best-effort webhook bridges without automated verification. Automatic Slack deactivation uses Slack's SCIM API, which Slack offers on its Business+ and Enterprise plans. On other Slack plans, Tempkey verifies that access was removed rather than removing it. For an organization managing contractor pipelines, controlling the GitHub or GitLab identity alongside Google Workspace ensures that when an engagement ends, the contractor's ability to trigger pipelines or inspect source code shuts down across all connected providers. For an overarching look at this lifecycle pattern, explore our guide to an automated access revocation strategy.
Revoking Contractor Access to Google Cloud Build
When an outside developer completes their deliverables, revoking access cleanly requires more than clicking "Remove" on a single IAM row. Because Cloud Build intersects with source control, service identities, and messaging queues, complete offboarding demands a systematic walkthrough.
Follow these steps to revoke a contractor's Google Cloud Build footprint thoroughly:
- Remove Project-Level IAM Bindings: Remove all direct bindings assigned to the contractor’s identity (such as
roles/cloudbuild.builds.vieweror custom build roles) using the Google Cloud Console or the CLI:gcloud projects remove-iam-policy-binding my-project \ --member="user:contractor@example.com" \ --role="roles/cloudbuild.builds.viewer" - Sever Service Account Delegation: Inspect the specific service accounts configured for your builds. Remove any
roles/iam.serviceAccountUserorroles/iam.serviceAccountTokenCreatorbindings mapped to the contractor. Review our detailed playbook on managing contractor access to Google Cloud IAM service accounts for deep-dive commands. - Disconnect Source Repository Permissions: Cloud Build triggers fire on repository events. Revoke the contractor’s membership or write permissions in the underlying GitHub, GitLab, or Cloud Source Repositories project. If they retain push access to a linked branch, they can continue executing builds via triggers even without Google Cloud console access.
- Check Indirect Trigger Mechanisms: Ensure the user has not configured automated jobs under their identity via Cloud Scheduler or Cloud Pub/Sub topics wired to build triggers. Inspect existing triggers to verify that no webhook triggers rely on API keys or secrets known exclusively to the contractor.
- Rotate Shared and Exposed Secrets: If the contractor had visibility into build logs during active debugging, treat any credentials that appeared in plain text as compromised. Rotate those secrets in Secret Manager immediately.
- Verify Policy State: Do not rely solely on the console UI's visual confirmation. Query the live policy directly through the Cloud IAM API or CLI to confirm the member has been dropped from all bindings:
If the response returns empty, the project-level identity bindings have been successfully purged.gcloud projects get-iam-policy my-project \ --flatten="bindings[].members" \ --filter="bindings.members:contractor@example.com"
Operational realities mean that programmatic revocations occasionally experience transient network or API failures. Tempkey executes revocation and reads provider state back to confirm it. Because revocation depends on third-party provider APIs, Tempkey does not guarantee removal within any specific time and surfaces failed or unenforceable revokes in the audit log. Having clear visibility into API execution state prevents edge-case errors from silently leaving access open.
Keeping a Record You Can Show an Auditor or Client
Granting and revoking access is only half of the governance requirement. When customers conduct vendor security reviews or enterprise clients request proof of control, operational teams must produce clear records demonstrating who had access to build infrastructure, why they had it, and exactly when it was removed.
A defensible access record must capture five core data points for every contractor engagement:
- The authenticated identity (email address and associated directory ID).
- The precise scope of access granted (roles, repositories, and environment boundaries).
- The approving internal manager who authorized the request.
- The exact timestamp of the grant initiation and the configured expiration boundary.
- The timestamp of completed revocation, accompanied by a verified state check.
Teams attempting to maintain this documentation using manual spreadsheets invariably fall behind. Manual tracking often slips during rapid delivery cycles, resulting in mismatched dates and undocumented grants. While Google Cloud Audit Logs record raw administrative calls, querying Cloud Logging months later to stitch together an individual contractor's full lifecycle across multiple cloud tools requires complex queries and steep log-retention costs.
To eliminate manual documentation overhead, Tempkey keeps an append-only audit trail you can export to CSV or PDF. This creates an unedited, chronologically verifiable record of the contractor’s entire access lifecycle across your integrated platforms. Tempkey gives you an exportable, append-only audit trail to support your own compliance and offboarding records. Tempkey does not currently hold SOC 2, ISO 27001, HIPAA, or PCI certification. Having structured records ready for immediate export drastically reduces the stress of client audits. Source: Tempkey source.
For organizations operating central internal tooling, Tempkey has a public REST API covering grants, extension, revocation with read-back verification, integrations, the audit trail, and API-key management. Keys are bearer tokens with read/write scopes; an OpenAPI 3 spec is published at api.tempkey.io/openapi.json and human docs at tempkey.io/docs/api. This allows operations teams to integrate grant state events into their existing reporting infrastructure. For a comprehensive framework on running these operational routines, reference our complete contractor access management checklist.
A Practical Checklist for Onboarding and Offboarding Build Access
To keep your build infrastructure secure without creating unnecessary bottlenecks for delivery teams, use this operational checklist whenever engaging external talent.
Phase 1: Onboarding
- Identity Provisioning: Issue a company-managed Google Workspace identity so your team retains administrative control over authentication, multi-factor settings, and account suspension.
- Role Scoping: Assign the narrowest viable role. Default to Cloud Build Viewer (
roles/cloudbuild.builds.viewer). Only grant build execution rights if local emulators or mock runners are insufficient. - Service Account Isolation: If manual execution is required, bind
roles/iam.serviceAccountUserstrictly to a non-privileged staging service account rather than assigning it project-wide. - Secret Verification: Confirm that no static secrets exist in build substitution defaults. Verify that Secret Manager access is restricted to the specific secret versions required for the build.
- Time-Box Setup: Establish an explicit contract end date. Record the access window in your lifecycle system so termination is scheduled automatically.
Phase 2: During the Engagement
- Scope Monitoring: Review active IAM policies monthly to detect privilege creep. Watch for impromptu requests granting global permissions to resolve temporary build roadblocks.
- Log Auditing: Periodically review build logs for accidental secret leaks resulting from debugging commands.
- Timeline Maintenance: If an engagement scope expands, re-evaluate and formalize the extension date in your access records rather than allowing access to linger open-ended.
Phase 3: Offboarding
- IAM Deprovisioning: Delete all direct IAM role bindings from the contractor's identity at the project level.
- Trigger and Repo Removal: Remove the contractor from connected code repositories and trigger permissions to prevent automated builds from executing on their behalf.
- Credential Invalidation: Rotate any runtime tokens, staging API keys, or package registry tokens the contractor had access to inspect during development.
- Read-Back Verification: Query the Google Cloud IAM API directly to confirm that no latent bindings remain assigned to the user.
- Audit Trail Archival: Export the complete grant, extension, and revocation event logs to CSV or PDF for compliance records.
If you manage a lean engineering team and lack the time to run extensive manual security protocols, focus on three non-negotiables: always use company-managed accounts, never put secrets in build substitutions, and schedule access expiration the minute you issue a grant. For broader strategies suited to resource-constrained operators, review our guide to small business contractor access security.
Frequently Asked Questions
What is the minimum Google Cloud Build permission a contractor needs to run builds?
To run builds manually using the Google Cloud CLI, a contractor needs a role granting cloudbuild.builds.create and cloudbuild.builds.get, alongside the Service Account User role (roles/iam.serviceAccountUser) bound specifically to the build's dedicated service account. If the contractor only needs to trigger builds via code commits, they do not need any direct Google Cloud IAM permissions; granting them commit or pull request rights on your source repository is sufficient.
Can I limit a contractor's Cloud Build access to a specific time period?
Yes. Within Google Cloud IAM, you can configure IAM Conditions to enforce access based on temporary date-time constraints. For a comprehensive offboarding approach that covers surrounding tools like GitHub, Slack, and Google Workspace simultaneously, teams use tools like Tempkey, which grants contractors access for a set period and revokes it automatically when the grant expires.
How do I stop secrets from appearing in Cloud Build logs?
As documented in Google Cloud's guide on using secrets in Cloud Build, substitution variables are visible in build metadata and console logs. To prevent credential leakage, use Google Cloud Secret Manager to inject secrets as environment variables directly inside the cloudbuild.yaml configuration using the native availableSecrets block. Additionally, instruct developers to avoid echoing environment variables (such as running printenv) within build script steps.
What should I check after revoking a contractor's Google Cloud Build access?
After revoking project-level IAM bindings, verify that the contractor's permissions have been removed from the connected source repositories, as branch commits can still trigger builds automatically. Check that any Service Account User bindings on custom service accounts have been deleted, ensure no personal tokens remain in Cloud Scheduler or Pub/Sub triggers, and rotate any secrets the developer had permission to inspect during their engagement.
Does Tempkey integrate with Google Cloud Build directly?
Tempkey natively enforces access on 10 providers: Slack, Google Workspace, Microsoft 365, GitHub, GitLab, Zoom, AWS IAM, Figma, Dropbox, and Asana. While it does not enforce Google Cloud IAM natively, Tempkey manages and revokes contractor access across the surrounding development ecosystem—including GitHub, GitLab, and Google Workspace identities—ensuring external contributors lose their repository trigger rights and managed cloud login capabilities the moment their grant expires.
If you want contractor access to expire on its own instead of waiting on a calendar reminder, try Tempkey free: grant access for a set period, revoke it automatically when the grant expires, and keep an append-only audit trail you can export to CSV or PDF. As documented on Tempkey, plans are month-to-month (Free / $39 Team / $99 Business) with active-grant limits of 2 / 10 / 30. Business includes extended audit-history retention.