Getting Started

We will demonstrate how to use Data Fence locally with a Docker container. In most real world use cases, you will probably be running similar commands inside of a Continuous Deployment pipeline or a cloud service inside of a Docker Container.

First create a programmatic access token on Snowflake so that you can login without a browser. Note that this application is for security administration and will therefore require elevated access.

Clone the Example

You can try out the example configuration.

git clone https://github.com/zoom/zoom-data-fence.git
cd zoom-data-fence/docs/_includes/example

Connect To Snowflake

You will need to be able to connect to Snowflake. The example uses a profiles.yml file which defines your connection to Snowflake.

default-profile: dev
profiles:
  dev:
    provider-name: SNOWFLAKE
    connection:
      snowflake:
        connection-string: jdbc:snowflake://${var.account}.snowflakecomputing.com:443
        connection-properties:
          user: ${var.user}
          password: ${var.token}
          sys-admin-role: accountadmin
          security-admin-role: accountadmin

You will need a programmatic method to connect to Snowflake. For this example, we are using a Programmatic Access Token.

alter user MY_USER add programmatic access token dfence_test
role_restriction = 'ACCOUNTADMIN';

Export Environment Variables for the variables in the profiles.ymlfile. You can specify your own variable names based on your needs when you write your own profile.

export DFENCE_USER="Your Snowflake Login Name"
export DFENCE_TOKEN="Your Programmatic Access Token"
export DFENCE_ACCOUNT="Your Snowflake Account Name"

Define Snowflake Roles To Create

Now we will use a role definition file to define roles.


roles:
  example-1:
    name: example_1_${var.env-name}
    grants: []
  example-2:
    name: example_2_${var.env-name}
    grants:
      - object-type: role
        object-name: example_1_${var.env-name}
        privileges:
          - usage

Note that the role file also refers to data fence variables. These variables could be provided by environment variables like we did with the connection variables. However, they can also be provided by a file. It is convenient to organize variables into files for each environment. Here we have placed the environment file at env/dev/vars.yml.

env-name: dev

Execute in DFence Docker Container

Now, mount the directory and secrets to a data fence docker container running interactively.

docker run -it -v $PWD:/example -e DFENCE_TOKEN -e DFENCE_USER -e DFENCE_ACCOUNT \
  --workdir /example --entrypoint bash zoomvideo/zoom-data-fence

You should now have a shell in the docker container.

Make sure that you can run dfence by running a help command.

dfence --help

Compile Changes

Run a dfence compile command to connect to the database and plan the changes.

dfence compile --var-file env/dev/vars.yml roles

You should now see the compiled changes which would be run.

---
changes:
- role-creation-statements:
  - "CREATE ROLE IF NOT EXISTS EXAMPLE_1_DEV;"
  - "GRANT OWNERSHIP ON ROLE EXAMPLE_1_DEV TO ROLE securityadmin COPY CURRENT GRANTS;"
  role-grant-statements: []
  role-id: "example-1"
  role-name: "example_1_dev"
- role-creation-statements:
  - "CREATE ROLE IF NOT EXISTS EXAMPLE_2_DEV;"
  - "GRANT OWNERSHIP ON ROLE EXAMPLE_2_DEV TO ROLE securityadmin COPY CURRENT GRANTS;"
  role-grant-statements:
  - - "GRANT ROLE \"EXAMPLE_1_DEV\" TO ROLE EXAMPLE_2_DEV;"
  role-id: "example-2"
  role-name: "example_2_dev"
total-changes: 2
total-roles: 2

If you like the compiled result, you can instead run the apply command.

Apply Changes

dfence apply --var-file env/dev/vars.yml roles

You are asked to approve the changes. Select ‘y’ if you are Ok with the roles being created.

If you run compile again, you should see that no further changes are planned.

---
changes: []
total-changes: 0
total-roles: 2

Evolve Roles

Now let’s edit the roles file to remove example_2_dev role’s usage permission on the example_1_dev role.


roles:
  example-1:
    name: example_1_${var.env-name}
    grants: []
  example-2:
    name: example_2_${var.env-name}
    grants: []

Let’s run apply against the changed role.

dfence apply --var-file env/dev/vars.yml roles-changed

Now we should see that Data Fence will revoke the grant.

---
changes:
- role-creation-statements: []
  role-grant-statements:
  - - "REVOKE ROLE \"EXAMPLE_1_DEV\" FROM ROLE EXAMPLE_2_DEV;"
  role-id: "example-2"
  role-name: "example_2_dev"
total-changes: 1
total-roles: 2

We can manage permissions for roles on any snowflake object with Data Fence, such as tables, views, schemas, procedures, functions and database.