Skip to content

Access#

Note

The below checks require manifest.json to be present.

Checks related to model access controls and contract enforcement.

Functions:

Name Description
check_model_access

Models must have the specified access attribute. Requires dbt 1.7+.

check_model_contract_enforced_for_public_model

Public models must have contracts enforced.

check_model_grant_privilege

Model can have grant privileges that match the specified pattern.

check_model_grant_privilege_required

Model must have the specified grant privilege.

check_model_has_contracts_enforced

Model must have contracts enforced.

check_model_number_of_grants

Model can have the specified number of privileges.

check_model_access #

Models must have the specified access attribute. Requires dbt 1.7+.

Parameters:

Name Type Description Default
access Literal[private, protected, public]

The access level to check for.

required

Receives at execution time:

Name Type Description
model ModelNode

The ModelNode object to check.

Other Parameters (passed via config file):

Name Type Description
description str | None

Description of what the check does and why it is implemented.

exclude str | None

Regex pattern to match the model path. Model paths that match the pattern will not be checked.

include str | None

Regex pattern to match the model path. Only model paths that match the pattern will be checked.

materialization Literal[ephemeral, incremental, table, view] | None

Limit check to models with the specified materialization.

severity Literal[error, warn] | None

Severity level of the check. Default: error.

Example(s):

manifest_checks:
    # Align with dbt best practices that marts should be `public`, everything else should be `protected`
    - name: check_model_access
      access: protected
      include: ^models/intermediate
    - name: check_model_access
      access: public
      include: ^models/marts
    - name: check_model_access
      access: protected
      include: ^models/staging

Source code in src/dbt_bouncer/checks/manifest/models/access.py
@check
def check_model_access(model, *, access: str):
    """Models must have the specified access attribute. Requires dbt 1.7+.

    Parameters:
        access (Literal["private", "protected", "public"]): The access level to check for.

    Receives:
        model (ModelNode): The ModelNode object to check.

    Other Parameters:
        description (str | None): Description of what the check does and why it is implemented.
        exclude (str | None): Regex pattern to match the model path. Model paths that match the pattern will not be checked.
        include (str | None): Regex pattern to match the model path. Only model paths that match the pattern will be checked.
        materialization (Literal["ephemeral", "incremental", "table", "view"] | None): Limit check to models with the specified materialization.
        severity (Literal["error", "warn"] | None): Severity level of the check. Default: `error`.

    Example(s):
        ```yaml
        manifest_checks:
            # Align with dbt best practices that marts should be `public`, everything else should be `protected`
            - name: check_model_access
              access: protected
              include: ^models/intermediate
            - name: check_model_access
              access: public
              include: ^models/marts
            - name: check_model_access
              access: protected
              include: ^models/staging
        ```

    """
    if model.access and model.access.value != access:
        fail(
            f"`{get_clean_model_name(model.unique_id)}` has `{model.access.value}` access, it should have access `{access}`."
        )

check_model_contract_enforced_for_public_model #

Public models must have contracts enforced.

Receives at execution time:

Name Type Description
model ModelNode

The ModelNode object to check.

Other Parameters (passed via config file):

Name Type Description
description str | None

Description of what the check does and why it is implemented.

exclude str | None

Regex pattern to match the model path. Model paths that match the pattern will not be checked.

include str | None

Regex pattern to match the model path. Only model paths that match the pattern will be checked.

materialization Literal[ephemeral, incremental, table, view] | None

Limit check to models with the specified materialization.

severity Literal[error, warn] | None

Severity level of the check. Default: error.

Example(s):

manifest_checks:
    - name: check_model_contract_enforced_for_public_model

Source code in src/dbt_bouncer/checks/manifest/models/access.py
@check
def check_model_contract_enforced_for_public_model(model):
    """Public models must have contracts enforced.

    Receives:
        model (ModelNode): The ModelNode object to check.

    Other Parameters:
        description (str | None): Description of what the check does and why it is implemented.
        exclude (str | None): Regex pattern to match the model path. Model paths that match the pattern will not be checked.
        include (str | None): Regex pattern to match the model path. Only model paths that match the pattern will be checked.
        materialization (Literal["ephemeral", "incremental", "table", "view"] | None): Limit check to models with the specified materialization.
        severity (Literal["error", "warn"] | None): Severity level of the check. Default: `error`.

    Example(s):
        ```yaml
        manifest_checks:
            - name: check_model_contract_enforced_for_public_model
        ```

    """
    if (
        model.access
        and model.access.value == "public"
        and (not model.contract or model.contract.enforced is not True)
    ):
        fail(
            f"`{get_clean_model_name(model.unique_id)}` is a public model but does not have contracts enforced."
        )

check_model_grant_privilege #

Model can have grant privileges that match the specified pattern.

Receives at execution time:

Name Type Description
model ModelNode

The ModelNode object to check.

privilege_pattern str

Regex pattern to match the privilege.

Other Parameters (passed via config file):

Name Type Description
description str | None

Description of what the check does and why it is implemented.

exclude str | None

Regex pattern to match the model path. Model paths that match the pattern will not be checked.

include str | None

Regex pattern to match the model path. Only model paths that match the pattern will be checked.

materialization Literal[ephemeral, incremental, table, view] | None

Limit check to models with the specified materialization.

severity Literal[error, warn] | None

Severity level of the check. Default: error.

Example(s):

manifest_checks:
    - name: check_model_grant_privilege
      include: ^models/marts
      privilege_pattern: ^select

Source code in src/dbt_bouncer/checks/manifest/models/access.py
@check
def check_model_grant_privilege(model, *, privilege_pattern: str):
    """Model can have grant privileges that match the specified pattern.

    Receives:
        model (ModelNode): The ModelNode object to check.
        privilege_pattern (str): Regex pattern to match the privilege.

    Other Parameters:
        description (str | None): Description of what the check does and why it is implemented.
        exclude (str | None): Regex pattern to match the model path. Model paths that match the pattern will not be checked.
        include (str | None): Regex pattern to match the model path. Only model paths that match the pattern will be checked.
        materialization (Literal["ephemeral", "incremental", "table", "view"] | None): Limit check to models with the specified materialization.
        severity (Literal["error", "warn"] | None): Severity level of the check. Default: `error`.

    Example(s):
        ```yaml
        manifest_checks:
            - name: check_model_grant_privilege
              include: ^models/marts
              privilege_pattern: ^select
        ```

    """
    compiled = compile_pattern(privilege_pattern.strip())
    config = model.config
    grants = config.grants if config else {}
    non_complying_grants = [i for i in (grants or {}) if compiled.match(str(i)) is None]

    if non_complying_grants:
        fail(
            f"`{get_clean_model_name(model.unique_id)}` has grants (`{privilege_pattern}`) that don't comply with the specified regexp pattern ({non_complying_grants})."
        )

check_model_grant_privilege_required #

Model must have the specified grant privilege.

Receives at execution time:

Name Type Description
model ModelNode

The ModelNode object to check.

privilege str

The privilege that is required.

Other Parameters (passed via config file):

Name Type Description
description str | None

Description of what the check does and why it is implemented.

exclude str | None

Regex pattern to match the model path. Model paths that match the pattern will not be checked.

include str | None

Regex pattern to match the model path. Only model paths that match the pattern will be checked.

materialization Literal[ephemeral, incremental, table, view] | None

Limit check to models with the specified materialization.

severity Literal[error, warn] | None

Severity level of the check. Default: error.

Example(s):

manifest_checks:
    - name: check_model_grant_privilege_required
      include: ^models/marts
      privilege: select

Source code in src/dbt_bouncer/checks/manifest/models/access.py
@check
def check_model_grant_privilege_required(model, *, privilege: str):
    """Model must have the specified grant privilege.

    Receives:
        model (ModelNode): The ModelNode object to check.
        privilege (str): The privilege that is required.

    Other Parameters:
        description (str | None): Description of what the check does and why it is implemented.
        exclude (str | None): Regex pattern to match the model path. Model paths that match the pattern will not be checked.
        include (str | None): Regex pattern to match the model path. Only model paths that match the pattern will be checked.
        materialization (Literal["ephemeral", "incremental", "table", "view"] | None): Limit check to models with the specified materialization.
        severity (Literal["error", "warn"] | None): Severity level of the check. Default: `error`.

    Example(s):
        ```yaml
        manifest_checks:
            - name: check_model_grant_privilege_required
              include: ^models/marts
              privilege: select
        ```

    """
    config = model.config
    grants = config.grants if config else {}
    if privilege not in (grants or {}):
        fail(
            f"`{get_clean_model_name(model.unique_id)}` does not have the required grant privilege (`{privilege}`)."
        )

check_model_has_contracts_enforced #

Model must have contracts enforced.

Receives at execution time:

Name Type Description
model ModelNode

The ModelNode object to check.

Other Parameters (passed via config file):

Name Type Description
description str | None

Description of what the check does and why it is implemented.

exclude str | None

Regex pattern to match the model path. Model paths that match the pattern will not be checked.

include str | None

Regex pattern to match the model path. Only model paths that match the pattern will be checked.

materialization Literal[ephemeral, incremental, table, view] | None

Limit check to models with the specified materialization.

severity Literal[error, warn] | None

Severity level of the check. Default: error.

Example(s):

manifest_checks:
    - name: check_model_has_contracts_enforced
      include: ^models/marts

Source code in src/dbt_bouncer/checks/manifest/models/access.py
@check
def check_model_has_contracts_enforced(model):
    """Model must have contracts enforced.

    Receives:
        model (ModelNode): The ModelNode object to check.

    Other Parameters:
        description (str | None): Description of what the check does and why it is implemented.
        exclude (str | None): Regex pattern to match the model path. Model paths that match the pattern will not be checked.
        include (str | None): Regex pattern to match the model path. Only model paths that match the pattern will be checked.
        materialization (Literal["ephemeral", "incremental", "table", "view"] | None): Limit check to models with the specified materialization.
        severity (Literal["error", "warn"] | None): Severity level of the check. Default: `error`.

    Example(s):
        ```yaml
        manifest_checks:
            - name: check_model_has_contracts_enforced
              include: ^models/marts
        ```

    """
    if not model.contract or model.contract.enforced is not True:
        fail(
            f"`{get_clean_model_name(model.unique_id)}` does not have contracts enforced."
        )

check_model_number_of_grants #

Model can have the specified number of privileges.

Receives at execution time:

Name Type Description
max_number_of_privileges int | None

Maximum number of privileges, inclusive.

min_number_of_privileges int | None

Minimum number of privileges, inclusive.

model ModelNode

The ModelNode object to check.

Other Parameters (passed via config file):

Name Type Description
description str | None

Description of what the check does and why it is implemented.

exclude str | None

Regex pattern to match the model path. Model paths that match the pattern will not be checked.

include str | None

Regex pattern to match the model path. Only model paths that match the pattern will be checked.

materialization Literal[ephemeral, incremental, table, view] | None

Limit check to models with the specified materialization.

severity Literal[error, warn] | None

Severity level of the check. Default: error.

Example(s):

manifest_checks:
    - name: check_model_number_of_grants
      include: ^models/marts
      max_number_of_privileges: 1 # Optional
      min_number_of_privileges: 0 # Optional

Source code in src/dbt_bouncer/checks/manifest/models/access.py
@check
def check_model_number_of_grants(
    model, *, max_number_of_privileges: int = 100, min_number_of_privileges: int = 0
):
    """Model can have the specified number of privileges.

    Receives:
        max_number_of_privileges (int | None): Maximum number of privileges, inclusive.
        min_number_of_privileges (int | None): Minimum number of privileges, inclusive.
        model (ModelNode): The ModelNode object to check.

    Other Parameters:
        description (str | None): Description of what the check does and why it is implemented.
        exclude (str | None): Regex pattern to match the model path. Model paths that match the pattern will not be checked.
        include (str | None): Regex pattern to match the model path. Only model paths that match the pattern will be checked.
        materialization (Literal["ephemeral", "incremental", "table", "view"] | None): Limit check to models with the specified materialization.
        severity (Literal["error", "warn"] | None): Severity level of the check. Default: `error`.

    Example(s):
        ```yaml
        manifest_checks:
            - name: check_model_number_of_grants
              include: ^models/marts
              max_number_of_privileges: 1 # Optional
              min_number_of_privileges: 0 # Optional
        ```

    """
    config = model.config
    grants = config.grants if config else {}
    num_grants = len((grants or {}).keys())

    if num_grants < min_number_of_privileges:
        fail(
            f"`{get_clean_model_name(model.unique_id)}` has less grants (`{num_grants}`) than the specified minimum ({min_number_of_privileges})."
        )
    if num_grants > max_number_of_privileges:
        fail(
            f"`{get_clean_model_name(model.unique_id)}` has more grants (`{num_grants}`) than the specified maximum ({max_number_of_privileges})."
        )