Tempkey Blog
A Pragmatic Architecture for Managing Contractor Access to Google Cloud BigQuery
Discover how to configure fine-grained IAM roles, enforce column-level security, and prevent data exfiltration when onboarding and offboarding external BigQuery analysts.
The Core Risks of Unmanaged Contractor Access in Cloud Data Warehouses
Granting an external contributor access to a production data warehouse introduces structural risks that differ fundamentally from internal employee workflows. Internal data team members typically operate on managed corporate workstations governed by mobile device management (MDM) software, connect through corporate VPNs, and retain access over long, predictable employment cycles. Freelance data analysts, by contrast, frequently operate on personal hardware (BYOD), move across varying residential or public networks, and often work with multiple competing clients concurrently on the same physical machine.
When engineering teams take shortcuts—such as issuing persistent access grants or distributing raw JSON service account keys—they open their data warehouse to three distinct vulnerabilities:
- Unbounded Query Billing: In BigQuery's on-demand compute model, queries are billed based on the number of bytes scanned. A single unindexed, unpartitioned query across terabytes of log data or event streams can incur significant costs in seconds. External contractors unfamiliar with your partitioning schemas or table clustering can accidentally rack up thousands of dollars in query fees on your primary billing account.
- Inadvertent PII and Sensitive Data Exposure: Analysts brought in to optimize a marketing funnel or build an operational dashboard rarely need to see raw customer email addresses, phone numbers, or credit card tokens. Granting blanket project-level read rights grants visibility into all underlying datasets within that project, bypassing the principle of least privilege.
- Unmonitored External Data Egress: BigQuery makes it straightforward to run an
EXPORT DATA OPTIONSstatement, writing the output of a query directly to a Google Cloud Storage (GCS) bucket. If IAM permissions are not strictly bounded, a compromised identity or a rogue actor can exfiltrate entire tables to an external, publicly readable cloud storage location without triggering immediate perimeter alarms.
Compounding these operational issues is the lifecycle problem. Engineering leads often create temporary credentials during an urgent sprint, intending to revoke them upon project completion. Months later, audit reviews reveal that past contractors still maintain active read permissions to core production datasets. Preventing these scenarios requires eliminating manual deprovisioning in favor of strict IAM boundaries and automated access lifecycles.
---Principles for Managing Contractor Access to Google Cloud BigQuery
A resilient data access model balances contractor velocity with strict administrative boundaries. Rather than treating BigQuery as a monolithic database where users are simply added to the project, implement three structural principles to manage risk.
1. Enforce Separation of Duties Across Compute and Storage
In Google Cloud, compute (query processing) and storage (datasets and tables) can be managed across entirely separate projects. A foundational best practice when managing contractor access to google cloud bigquery is establishing a two-project architecture:
- The Data Project (Storage): Contains the raw tables, partitioned datasets, and underlying storage assets. No external contractors are given compute permissions or project-level roles within this project.
- The Analytics/Query Project (Compute): Serves as the compute sandbox. Contractors are granted permissions to run queries inside this project, ensuring all query processing costs are attributed directly to an isolated compute budget. This project queries datasets living in the Data Project via authorized dataset permissions.
This decoupling ensures that if a contractor executes an expensive query, the compute usage is billed to an analytics project equipped with hard quota ceilings and automated budget alerts, protecting the core production data project from billing spikes or resource contention.
2. Adopt Zero Standing Privileges (ZSP)
Persistent credentials present unnecessary risk. Under a Zero Standing Privileges model, freelance contributors possess zero default permissions outside active milestones. When an analytics sprint begins, permissions are provisioned with an enforced time-to-live (TTL). When the milestone concludes, the access expires automatically at the identity provider level, eliminating the risk of neglected permissions.
3. Establish Write-Once Audit Pipelines
Every IAM policy binding, role update, and data access operation must be systematically recorded. Relying on transient terminal histories or manual administrative notes leaves security teams blind during operational reviews. All contractor query activity, table export jobs, and administrative access assignments should be streamed directly to Cloud Audit Logs and monitored via automated security alerts.
---Designing BigQuery IAM for Freelancers: Roles, Scopes, and Boundaries
Configuring effective BigQuery IAM access control requires avoiding broad primitive roles like roles/viewer or roles/editor. Instead, leverage Google Cloud's predefined IAM roles applied exclusively at granular resource levels.
Understanding the exact mechanics of Google Cloud IAM roles is essential to setting up an effective architecture for bigquery iam for freelancers:
roles/bigquery.jobUser: Grants permissions to run query jobs, cancel jobs, and list jobs within a specific compute project. This role does not grant read access to any data. It should be assigned to the contractor on the Query Project so they can execute queries.- roles/bigquery.dataViewer : Grants read access to datasets, tables, and views, including table schema and metadata. Crucially, this role should rarely be granted at the project level. Instead, assign it directly at the specific dataset layer within the Data Project.
roles/bigquery.user: A composite role that includes table read access and the ability to run jobs. Because it bundles storage and compute permissions, it is generally too broad for external freelancers and should be avoided in favor of discrete role assignments.
Designing a Custom Role for External Data Analysts
Even roles/bigquery.dataViewer can be overly permissive if your organization wants to restrict contractors from exporting large result sets to cloud buckets. You can assemble a custom IAM role that supplies the minimum viable permissions required to inspect schemas and read table contents through the console or API, while explicitly excluding export capabilities:
title: "RestrictedContractorAnalyst"
description: "Allows query reads on specific datasets without export or snapshot capabilities"
stage: "GA"
includedPermissions:
- bigquery.tables.get
- bigquery.tables.getData
- bigquery.tables.list
- bigquery.routines.get
- bigquery.routines.list
By pairing this custom role at the dataset level with roles/bigquery.jobUser on their assigned query project, the external analyst can execute analytical SQL queries against the dataset without possessing the authority to dump raw tables into uncontrolled GCS storage buckets.
Restricting Data Access for Contractors Using Authorized Views and Column Masking
Granting dataset-level read access is often insufficient when tables hold sensitive operational data. When evaluating contractor access manager workflows, organizations frequently require techniques for restricting data access for contractors at both the column and row levels.
1. Abstracting Source Tables with Authorized Views
An Authorized View allows you to share query results with specific users without giving them direct read access to the underlying tables. For example, if you hire an outside analyst to evaluate aggregate customer conversion rates, they do not need access to the raw transactions table containing unencrypted billing names and addresses.
To implement this:
- Create an analytical view in a dedicated, contractor-accessible dataset that aggregates metrics and omits sensitive columns:
CREATE VIEW `analytics_sandbox.contractor_conversion_metrics` AS SELECT campaign_id, DATE_TRUNC(transaction_date, DAY) AS transaction_day, COUNT(transaction_id) AS total_conversions, SUM(order_value_cents) / 100 AS gross_revenue_usd FROM `production_data.raw_customer_transactions` GROUP BY campaign_id, transaction_day; - Authorize the view within the source dataset (
production_data). This grants the view permission to read the underlyingraw_customer_transactionstable on behalf of any user who queries the view. - Grant the contractor
roles/bigquery.dataVieweronly on theanalytics_sandboxdataset. When the contractor queries the view, BigQuery verifies their access to the view and uses the view's internal authorization to fetch the underlying records. Direct attempts by the contractor to queryproduction_data.raw_customer_transactionswill be blocked with an access denied error.
2. Dynamic Data Masking via Data Catalog Policy Tags
If contractors must write exploratory queries against primary production schemas, use BigQuery column-level security and dynamic data masking. Dynamic masking preserves the schema structure while intercepting and transforming sensitive column values at query runtime.
The workflow relies on Google Cloud Data Catalog taxonomies:
- Create a policy taxonomy (e.g.,
Customer_PII) in Data Catalog and define a policy tag (e.g.,Email_Address). - Attach a masking rule to the policy tag, such as
Email mask(transformsjohn.doe@example.comintoj***n@example.com) orNullify. - Assign the policy tag directly to the sensitive columns in your table schema using the BigQuery console, CLI, or Terraform:
ALTER TABLE `production_data.users` ALTER COLUMN email SET DATA POLICY `projects/my-org/locations/us/taxonomies/pii/policyTags/email_mask_policy`; - Grant your internal engineers the
roles/datacatalog.categoryFineGrainedReaderrole on that policy tag so they can inspect raw strings. Contractors, lacking this role, will execute queries successfully against the table, but BigQuery will dynamically evaluate their identity and return only masked strings for the designated columns.
3. Partitioning Data Using Row-Level Security
If you engage regional contractors who should only see metrics relevant to their territory, implement BigQuery row-level security (RLS). Row access policies act as persistent SQL filters applied invisibly to every query executed by the specified principals.
CREATE OR REPLACE ROW ACCESS POLICY regional_contractor_filter
ON `production_data.retail_orders`
GRANT TO ('group:emea-contractors@example.com')
FILTER USING (region = 'EMEA');
When an identity belonging to emea-contractors@example.com executes SELECT * FROM production_data.retail_orders , BigQuery automatically rewrites the query execution plan to inject WHERE region = 'EMEA' . The contractor rarely sees records outside their assigned boundary, and queries that attempt to scan other regions return empty results for those rows.
---Step-by-Step Implementation: Managing Contractor Access to Google Cloud BigQuery
Building a robust access model involves orchestrating identity boundaries, role allocations, compute limits, and network perimeters. Follow these four steps to implement an end-to-end system for managing external analyst access.
Step 1: Provision Managed Cloud Identities Over Service Account Keys
rarely generate and distribute JSON service account keys to freelance workers. Service account keys bypass single-sign-on protections, cannot be tied easily to an individual session, and are frequently committed to personal GitHub repositories or stored insecurely on external laptops.
Instead, issue the contractor a dedicated Cloud Identity account under your domain (e.g., analyst.jane@contractors.yourcompany.com) or add their corporate identity to a dedicated Google Group (e.g., external-bi-team@yourcompany.com). Managing access through group memberships ensures that updating or terminating the group binding instantly modifies permissions across all attached resources.
Step 2: Assign Granular Scopes via Terraform or gcloud CLI
Automate your dataset permissions using Infrastructure as Code (IaC) or authenticated Google Cloud CLI scripts. This ensures a clean audit log and prevents configuration drift.
First, permit the contractor group to execute jobs within the dedicated Compute/Query Project:
gcloud projects add-iam-policy-binding analytics-compute-prod \
--member="group:external-bi-team@yourcompany.com" \
--role="roles/bigquery.jobUser"
Second, assign the dataset-level read viewer role on the specific dataset inside the Storage Project:
bq add-iam-policy-binding \
--dataset storage-warehouse-prod:marketing_aggregate_mart \
--member="group:external-bi-team@yourcompany.com" \
--role="roles/bigquery.dataViewer"
This explicit assignment ensures the group has no listing or read rights to other datasets (such as finance_raw or core_pii) within the same storage project.
Step 3: Enforce Session Expiration Using IAM Conditions
Google Cloud IAM supports conditional policy bindings based on contextual attributes, including the request timestamp. You can construct an IAM binding that automatically expires at a designated calendar date and time, eliminating the risk of neglected permissions if manual offboarding is delayed:
gcloud projects add-iam-policy-binding analytics-compute-prod \
--member="group:external-bi-team@yourcompany.com" \
--role="roles/bigquery.jobUser" \
--condition='title=contract_end_bound,description=Expires at end of sprint,expression=request.time < timestamp("2026-10-31T23:59:59Z")'
Once the clock strikes the defined UTC timestamp, Google Cloud's policy evaluation engine automatically denies all subsequent authorization requests from that binding without requiring manual administrative intervention.
Step 4: Configure Byte-Scan Limits and VPC Service Controls
To protect against unexpected bills, navigate to the BigQuery console in your Query Project and establish custom per-query byte limits. Under Query Management, configure maximum bytes billed thresholds for contractor identities. Alternatively, apply the --maximum_bytes_billed flag in script configurations to terminate any query job projected to exceed your allocated threshold.
For high-assurance deployments, place the storage projects inside a VPC Service Controls (VPC SC) service perimeter. A VPC SC perimeter blocks external data exfiltration by rejecting API requests that originate outside designated corporate networks, authorized VPCs, or approved access levels—even if the user presents valid IAM credentials.
---Automating Offboarding and Ephemeral Lifecycle Grants
While native tools like IAM Conditions provide temporal constraints, relying solely on manual CLI commands or static end-dates across disparate cloud providers introduces operational friction. Small businesses, ops managers, and engineering teams using freelancers frequently juggle access not just in BigQuery, but across connected tools like Google Workspace, GitHub, Slack, and cloud providers.
Manual offboarding checklists consistently break down in high-velocity teams. A project manager might remember to revoke a contractor's Google Workspace identity while forgetting their dataset permissions in Google Cloud, or vice versa. This operational fragmentation leaves zombie credentials lingering in infrastructure.
Modern data security architectures address this by incorporating purpose-built access lifecycle automation. When establishing your offboarding workflows, focus on two critical capabilities: automated credential lifecycles and verifiable audit confirmation.
Engineering teams frequently use programmatic controls to govern these transitions. 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.
Integrating lifecycle automation ensures that access grants are treated as ephemeral workflows rather than permanent configurations. Rather than manually auditing dozens of datasets at the end of each fiscal quarter, access is granted with an explicit duration. 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. Slack carries one condition worth stating: automatic deactivation uses Slack's SCIM API, which Slack ships on Business+ and Enterprise only. Below that, Tempkey verifies the removal rather than performing it, so do not promise automatic Slack revocation without naming the plan.
Reviewing historical access states is equally critical for governance. Tempkey keeps an append-only audit trail you can export to CSV or PDF. Describe it as append-only, not immutable, and do not claim unlimited retention. Furthermore, 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.
When selecting solutions, teams often compare per-seat operational tools against granular grant systems. Enterprise IT suites (e.g. Rippling, Okta, JumpCloud) bundle contractor offboarding inside larger, per-employee-priced products; their pricing changes often and is frequently quote-gated. Tempkey prices per active contractor grant. For teams looking to scale their external workforce without overhead, plans are month-to-month (Free / $39 Team / $99 Business) with active-grant limits of 2 / 10 / 30. Business includes extended audit-history retention. You can explore structured options on the pricing page.
To inspect credential isolation in your internal architectures, review modern security design considerations. For example, provider admin tokens are write-only in the browser and encrypted at rest using AWS KMS in production; they are never displayed again after submission.
---Monitoring, Cost Caps, and Audit Logging for External Analyst Accounts
Even with rigorous role assignments and authorized views in place, continuous operational observability is necessary to detect abnormal contractor query behavior before it impacts budgets or compromises data integrity.
Querying the INFORMATION_SCHEMA for Anomalous Operations
BigQuery exposes comprehensive operational telemetry through its system-defined INFORMATION_SCHEMA views. Security leads can configure scheduled queries to run daily, scanning for unusual query behavior executed by contractor accounts. For example, the following query audits the total gigabytes billed and identifies all data-export queries run by external contractors over the past 7 days:
SELECT
user_email,
job_id,
creation_time,
total_bytes_billed / POWER(1024, 3) AS gigabytes_billed,
query
FROM
`analytics-compute-prod.`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT`
WHERE
creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
AND user_email LIKE '%contractor%'
AND (
query LIKE '%EXPORT DATA%'
OR total_bytes_billed > 100 * POWER(1024, 3) -- Flag queries over 100 GB billed
)
ORDER BY
gigabytes_billed DESC;
Setting up alerts via Cloud Monitoring based on the results of this view ensures that your engineering leads receive prompt notifications if a freelance analyst runs an unoptimized cross-join or attempts an unsanctioned table export.
Cloud Audit Logs and Log Sinks
BigQuery emits two primary types of logs to Cloud Logging:
- Admin Activity Logs: Captures structural modifications, such as the creation, alteration, or deletion of datasets, tables, and views, as well as modifications to IAM access policies. These logs cannot be disabled and provide a reliable ledger of resource state changes.
- Data Access Logs: Records individual query jobs and API calls that inspect table data. Because these logs can generate substantial volume, ensure your Cloud Logging ingestion filters are calibrated to capture external contractor identities while excluding high-volume automated internal service accounts.
Route these audit events through a Cloud Logging Sink into an append-only, centralized storage bucket or security information and event management (SIEM) pipeline. Retaining clear, verifiable records of access lifecycles and query histories allows engineering teams to validate compliance controls and confirm that external access was cleanly revoked when engagements concluded.
---Frequently Asked Questions
What is the most secure way to grant a freelance analyst query access to BigQuery?
The most secure method is implementing a two-project architecture separating compute from storage. Provision the freelancer a managed Google Identity (rarely raw service account JSON keys) and grant them roles/bigquery.jobUser on a dedicated Analytics Compute Project. On the Data Storage Project, grant them roles/bigquery.dataViewer strictly at the specific dataset or authorized view level—rarely at the project level. Finally, bound the permission with a time-based IAM Condition or an automated lifecycle management tool.
Can I limit how much data a contractor queries in BigQuery to prevent runaway bills?
Yes. You can limit query spend using multiple controls: apply the --maximum_bytes_billed limit to client-side query calls, configure custom per-user or per-project query quotas in the Google Cloud Console under Quotas & System Limits, and isolate the contractor's compute jobs within a dedicated Query Project configured with strict Cloud Billing budget alerts that notify engineering leads or disable billing when thresholds are reached.
Should contractors use Google Cloud Service Account keys or their own Google accounts?
Contractors should use managed Google accounts under your domain (or their corporate Google Workspace email mapped via Cloud Identity), rarely raw service account keys. Long-lived service account keys present severe credential leakage risks, cannot be protected with multi-factor authentication, and obfuscate individual accountability in Cloud Audit Logs. If machine-to-machine access is required, implement Workload Identity Federation instead of static keys.
How do Authorized Views help protect sensitive data from external contractors?
Authorized Views allow you to grant contractors read access to curated SQL query results—such as aggregated metrics, filtered rows, or masked values—without granting them permission to view or query the underlying production tables. BigQuery authorizes the view itself to access the source dataset, effectively creating a secure abstraction layer between the contractor's account and your raw sensitive data.
---Managing external data access requires a deliberate architecture: separating compute and storage, applying least-privilege IAM controls, and eliminating persistent credentials. Explore how Tempkey automates time-bound access lifecycles with verified offboarding and exportable audit records for your contractors.