[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["わかりにくい","hardToUnderstand","thumb-down"],["情報またはサンプルコードが不正確","incorrectInformationOrSampleCode","thumb-down"],["必要な情報 / サンプルがない","missingTheInformationSamplesINeed","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-09-04 UTC。"],[[["\u003cp\u003eAvoid granting sensitive permissions like project owner, BigQuery data editor/owner/viewer, or Cloud Billing viewer roles to users who should only access filtered data, to prevent side-channel attacks and data leakage.\u003c/p\u003e\n"],["\u003cp\u003eRefrain from granting table write permissions to users who should only see filtered data to prevent data tampering, and use separate groups for table write access and row-level access policies.\u003c/p\u003e\n"],["\u003cp\u003eWhen managing row-level access policies, avoid using \u003ccode\u003eCREATE OR REPLACE\u003c/code\u003e for the last policy on a table; instead, remove all access, recreate the policies, and then re-enable access to prevent inadvertent unfiltered access.\u003c/p\u003e\n"],["\u003cp\u003eUse row-level security exclusively within your organization, not across organizations, to mitigate the risk of side-channel attacks and to maintain control over sensitive data access.\u003c/p\u003e\n"],["\u003cp\u003eManage the \u003ccode\u003ebigquery.filteredDataViewer\u003c/code\u003e role exclusively through row-level access policies, and avoid applying this role via IAM, to ensure intended restrictions are enforced.\u003c/p\u003e\n"]]],[],null,["# Best practices for row-level security in BigQuery\n=================================================\n\nThis document explains best practices when using\n[row-level security](/bigquery/docs/row-level-security-intro).\n\nBefore you read this document, familiarize yourself with\nrow-level security by reading\n[Introduction to BigQuery row-level security](/bigquery/docs/row-level-security-intro)\nand\n[Working with row-level security](/bigquery/docs/managing-row-level-security).\n\nRestrict user permissions to limit side-channel attacks\n-------------------------------------------------------\n\n| **Best practice:** Don't grant sensitive permissions to users who should only see filtered data.\n\nA side-channel attack is a security attack based on information gained from the\nsystem itself. An attacker with broader permissions than necessary can\nmount side-channel attacks, and learn sensitive data by **observing** or\n**searching** billing, logging, or system messages.\n\nTo mitigate such opportunities, BigQuery hides\nsensitive statistics on all queries against tables with row-level security.\nThese sensitive statistics include the number of bytes and partitions processed,\nthe number of bytes billed, and the query plan stages.\n\n*We recommend that admins should refrain from granting the following permissions\nto users who should only see filtered data, to avoid giving access to sensitive\ndata.*\n\n**Examples**\n\n- Through repeated **observation** of query duration when querying tables with row-level access policies, a user could infer the values of rows that otherwise might be protected by row-level access policies. This type of attack requires many repeated attempts over a range of key values in partitioning or clustering columns. Even though there is inherent noise when observing or measuring query duration, with repeated attempts, an attacker could obtain a reliable estimate. *If you are sensitive to this level\n of protection, we recommend using separate tables to isolate rows with\n different access control requirements, instead.*\n- An attacker could **search** for the bytes processed by a query by monitoring the errors that occur when the query job limits (such as maximum bytes billed or custom cost controls) are exceeded. However, this attack requires a high volume of queries.\n- Through repeated queries and **observing** the BigQuery billing amount in Cloud Billing, a user could infer the values of rows that otherwise might be protected by row-level access policies. This type of attack requires many repeated attempts over a range of key values in partitioning or clustering columns. *If you are sensitive to this level of protection, we recommend that you limit access to billing data for\n queries.*\n\n*We also recommend that admins monitor\nCloud Audit Logs(/bigquery/docs/reference/auditlogs)\nfor suspicious activity on tables with row-level security, such as unexpected\nadditions, modifications, and deletions of row-level access policies.*\n\nRestrict user permissions to limit data tampering\n-------------------------------------------------\n\n| **Best practice:** Don't grant table write permissions to users who should only see filtered data.\n\nUsers with write permissions to a table can insert data into the table with the\n[`bq load` command](/bigquery/docs/reference/bq-cli-reference#bq_load) or with\nthe BigQuery Storage Write API. This can allow the user with\nwrite permissions to alter the query results of other users.\n\n*We recommend that admins create separate Google groups for table write access\nand row-levels access policies. Users that should only see filtered table\nresults shouldn't have write access to the filtered table.*\n\nAvoid inadvertent access when re-creating row-level access policies\n-------------------------------------------------------------------\n\n| **Best practice:** If there is only one row-level access policy on a table, don't recreate that row-level access policy with the `CREATE OR REPLACE` command. Instead, first remove all access to the table with table access controls, recreate the policies as needed, and then re-enable access.\n\nWhen you add a row access policy on a table for the first time, you immediately\nbegin filtering data in query results. When you remove the last row-level access\npolicy on a table, even if you intend to only re-create the row-level access\npolicy, you may inadvertently grant unfiltered access to a wider-than-intended\naudience.\n\n*We recommend that admins pay special attention when recreating the last\nrow-level access policy on a table, by following these guidelines:*\n\n1. First remove all access to the table, by using [table access controls](/bigquery/docs/control-access-to-resources-iam).\n2. Remove all row-level access policies.\n3. Re-create the row-level access policies.\n4. Re-enable access to the table.\n\nAlternatively, you can first create new row-level access policies on the table,\nthen delete the earlier row-level access policies that are no longer needed.\n\nUse row-level security only within organizations, not across organizations\n--------------------------------------------------------------------------\n\n| **Best practice:** Only use row-level security within your organization.\n\nDon't use the row-level security feature across organizations, to help prevent\ndata leakage through side-channel attacks, and to maintain greater control over\naccess to sensitive data.\n\nFor subquery row-level access policies, create and search tables within\norganizations or projects. This leads to better security and simpler ACL\nconfiguration, as grantees must have the `bigquery.tables.getData` permission on\nthe target and referenced tables in policies, as well as any relevant\n[column-level security](/bigquery/docs/column-level-security-intro) permissions.\n\n*We recommend using row-level security feature for within-organization\nsecurity constraints only (such as for sharing data within an\norganization/enterprise/company), and not for cross-organizational or public\nsecurity.*\n\n**Example**\n\nOutside of your organization, you have less control over who has access to data.\nWithin your organization, you can control who has been granted access to billing\ninformation of queries against tables with row-level access policies. Billing\ninformation is a vector for [side-channel attacks](#limit-side-channel-attacks).\n\nManage the `Filtered Data Viewer` role through row-level access policies\n------------------------------------------------------------------------\n\n| **Best practice:** `bigquery.filteredDataViewer` is a system-managed role granted through row-level access policies. Manage the role only through row-level access policies. Don't apply the role through Identity and Access Management (IAM).\n\nWhen you\n[create a row-level access policy](/bigquery/docs/managing-row-level-security#create-policy),\nthe principals in the policy are automatically granted the\n`bigquery.filteredDataViewer` role. You can only add or remove principals from\nthe access policy\n[with a DDL statement](/bigquery/docs/managing-row-level-security#examples).\n\nThe `bigquery.filteredDataViewer` role *must not* be granted through\n[IAM](/bigquery/access-control) to a higher-level resource, such\nas a table, dataset, or project. Granting the role in this way lets users\nview rows defined by *all* row-level access policies within that scope,\nregardless of intended restrictions. While the union of row-level access policy\nfilters might not encompass the entire table, this practice poses a significant\nsecurity risk and undermines the purpose of row-level security.\n\nWe recommend managing the `bigquery.filteredDataViewer` role exclusively through\nrow-level access policies. This method ensures that principals are granted the\n`bigquery.filteredDataViewer` role implicitly and correctly, respecting the\ndefined filter predicates for each policy.\n\nPerformance impact of filters on partitioned columns\n----------------------------------------------------\n\n| **Best practice:** Try to avoid making row access policies that filter on clustered and partitioned columns.\n\nRow-level access policy filters don't participate in query\n[pruning on partitioned and clustered tables](/bigquery/docs/using-row-level-security-with-features#partitioned_and_clustered_tables).\n\nIf your row-level access policy names a partitioned column, your query does not\nreceive the performance benefits of query pruning."]]