So I ran into some technical hurdles with the way the client was deploying groups (Active Directory ->Azure? -> AWS roll -> Redshift group) and had to restructure a few things but here is the current path forwarded.
Permissions will be at the table level and there hierarchy of sorts to give access to increasingly sensitive information. This was combined with controlling what level of curated tables (reports, dimensional models, staged data, raw data) a user will have access to as well so that all permissions can be managed with one process.
It starts with a series of variables in the project file to define the list of groups a table will be given select access to.
vars:
# Data warehouse permission Groups
reports: ['reports','analysis','privileged','sensitive','development','administration']
analysis: ['analysis','privileged','sensitive','development','administration']
privileged: ['privileged','sensitive','development','administration']
sensitive: ['sensitive','development','administration']
development: ['development','administration']
administration: ['administration']
all_groups: ['reports','analysis','privileged','sensitive','development','administration']
Then a default set of permissions is applied in the project file using a custom configuration using the name of variable. Note this is just the name of the variable and not the result of the var
function. And a macro is applied as a post hook to generate the permission granting statements.
models:
my-project:
post-hook: ["{{ apply_security() }}"]
staging:
+security_group:
- 'development'
marts:
+security_group:
- 'analysis'
reporting:
+security_group:
- 'reports'
The macro to generate the permission statements compares the provided list with the full list and generates a grant or revoke statement accordingly.
{% macro apply_security() -%}
{%- set security_groups = config.get('security_group') -%}
{%- set full_list = var('all_groups') -%}
{%- for security_group in security_groups -%}
{%- set groups = var(security_group)-%}
{%- for group in full_list -%}
{% if group is in groups %}
grant select on {{this}} to group {{ group }} ;
{% else %}
revoke select on {{this}} from group {{ group }};
{% endif %}
{%- endfor %}
{%- endfor %}
{%- endmacro %}
When a table is identified as needed a level different then the default can be overridden with a model configuration.
{{
config(
security_group = ['sensitive']
)
}}
This set up allows for procedural control of access on a model level, at least for this client and there set up.