Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CT-717] Add Grants to BigQuery Materializations #198

Closed
2 tasks
nathaniel-may opened this issue Jun 2, 2022 · 3 comments · Fixed by #212
Closed
2 tasks

[CT-717] Add Grants to BigQuery Materializations #198

nathaniel-may opened this issue Jun 2, 2022 · 3 comments · Fixed by #212
Assignees
Labels
enhancement New feature or request

Comments

@nathaniel-may
Copy link
Contributor

blocked by: dbt-labs/dbt-core#5263

Once the above work is merged into core, there are some tweaks that need to be made in the BigQuery adapter to fully expose the feature:

  • add a call to apply_grants(..., revoke=True) to all custom materializations
  • override apply_grants so that it directly makes the API call to revoke grants (BigQuery Docs) instead of getting sql from get_revoke_all_sql.
@nathaniel-may nathaniel-may added enhancement New feature or request triage labels Jun 2, 2022
@github-actions github-actions bot changed the title Add Grants to Materializations [CT-717] Add Grants to Materializations Jun 2, 2022
@jtcohen6
Copy link
Contributor

jtcohen6 commented Jun 3, 2022

Following up on latest thinking in dbt-labs/dbt-core#5263 (comment), there may actually be a way to do this that's SQL-only, without any API calls. That may be slightly slower, but it's much more visible, and easier to debug.

Docs:

Defaults should work for:

  • get_grant_sql
  • get_revoke_sql, IFF we take the "more sophisticated" approach of calculating diffs, since BQ only supports revoke [specific_privilege], not revoke all

We'd need a custom version of get_show_grants_sql, which should look like (pseudo code):

select * from {{ relation.project }}.`{{ target.location }}`.INFORMATION_SCHEMA.OBJECT_PRIVILEGES
where object_schema = '{{ relation.dataset }}' and object_name = '{{ relation.identifier }}'

Example flow

In dbt:

-- models/my_table.sql

{{ config(grants = {
    'roles/bigquery.dataViewer': ['user:jeremy@example.com'],
    'roles/custom.whatEver': ['user:another@example.com'],
} }}

select ...

So dbt runs:

grant `roles/bigquery.dataViewer` on dbt_jcohen.my_table to "user:jeremy@example.com";
grant `roles/custom.whatEver` on dbt_jcohen.my_table to "user:another@example.com";

Now, we change that to just:

-- models/my_table.sql

{{ config(grants = {
    'roles/bigquery.dataViewer': ['user:jeremy@example.com'],
} }}

select ...

So dbt runs:

select * from `region-us`.INFORMATION_SCHEMA.OBJECT_PRIVILEGES
where object_schema = 'dbt_jcohen' and object_name = 'my_table';

(result of that query, in JSON format)

{  "object_catalog": "dbt-test-env",  "object_schema": "dbt_jcohen",  "object_name": "my_table",  "object_type": "TABLE",  "privilege_type": "roles/bigquery.dataViewer",  "grantee": "user:jeremy@example.com"}
{  "object_catalog": "dbt-test-env",  "object_schema": "dbt_jcohen",  "object_name": "my_table",  "object_type": "TABLE",  "privilege_type": "roles/custom.whatEver",  "grantee": "user:another@example.com"}
revoke `roles/custom.whatEver` on dbt_jcohen.my_table from "user:another@example.com";

The cool thing about BigQuery is that we could actually perform the show + revoke + grant statements all in one dynamic "script," using "procedural SQL", if we so chose. That's fairly different from the general implementation we'd need on other databases, though.

@emmyoop emmyoop self-assigned this Jun 23, 2022
@emmyoop emmyoop changed the title [CT-717] Add Grants to Materializations [CT-717] Add Grants to BigQuery Materializations Jun 24, 2022
@avipaul6
Copy link

avipaul6 commented Jul 7, 2022

Will this also work for Authorized Views? @jtcohen6
I can't find any SQL example of revoking just that view from the dataset without having to

  1. call the dataset,
  2. get the whole list of views and
  3. remove just that view
  4. update the dataset.

I can see that done via API calls in Python from https://cloud.google.com/bigquery/docs/samples/bigquery-revoke-dataset-access

@jtcohen6
Copy link
Contributor

jtcohen6 commented Jul 7, 2022

@avipaul6 This will not work for authorized views, for the reasons you've indicated.

dbt already supports authorized views on BigQuery today, but the syntax is pretty wonky, and differs from the standard we're looking to implement in this feature: https://docs.getdbt.com/reference/resource-configs/bigquery-configs#authorized-views

Our main constraint here by what BigQuery StandardSQL makes available. I'm definitely interested in future work that reconciles / rationalizes dbt's approach to standard grants with the dataset operations required by authorized views.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants