# Explore what Skyflow can do

This guide is an introduction to using Skyflow Studio and Skyflow's Management and Data APIs. Following this guide, you'll use Skyflow's Quickstart vault and data governance engine to securely share and govern access to vault data for different types of users. You'll also insert, read, tokenize, and detokenize data in your vault.

## Prerequisites

#### Studio

- [Sign in](https://docs.skyflow.com/docs/resources/sign-in) to your Skyflow account. If you don't have an account,
  [sign up for a free trial](https://www.skyflow.com/try-skyflow).

#### API

- [Sign in](https://docs.skyflow.com/docs/resources/sign-in) to your Skyflow account. If you don't have an account,
  [sign up for a free trial](https://www.skyflow.com/try-skyflow).

- A bearer token to authenticate API calls. For a short-lived token, use the following process. To generate tokens from service accounts, see [Authenticate](/docs/fundamentals/api-authentication/).

1. In Studio, click your account icon and choose **Generate API Bearer Token**.

2. Click **Generate Token**.

- A device with the following tools available:
  - A terminal that can run `bash` commands
  - `curl`
  - [`jq`](https://stedolan.github.io/jq/) 1.6 or greater

- Skyflow account, vault, and workspace details:
1. In Studio, click **vault menu icon > View vault details**.
2. Note your **Account ID**, **Vault ID**, and **Vault URL** values.

- Your environment's Management API URL:
  - Trial or Production: `https://manage.skyflowapis.com`
  - Staging: `https://manage.skyflowapis-preview.com`

- Set environment variables for your account and vault details:

  ```bash
  export ACCOUNT_ID=$ACCOUNT_ID
  export VAULT_ID=$VAULT_ID
  export VAULT_URL=$VAULT_URL
  export MANAGEMENT_URL=$MANAGEMENT_URL
  export TOKEN=$TOKEN
  export SKYFLOW_ID=$SKYFLOW_ID
  ```

## Explore a vault

This guide uses the Quickstart vault template. This vault is a training tool to help people learn how to use Skyflow. Every account contains one or more workspaces, and workspaces contain vaults.

#### Studio

Every Skyflow trial account comes with a Quickstart vault. Navigate to your Quickstart vault or create a new one:

1. Sign in to Skyflow Studio.
2. Click **Add Vault > Start with a template**.
3. Under **Quickstart**, click **Create**.

#### API

You can create a Quickstart vault by referencing the Quickstart vault template ID.

1. Create a Quickstart vault (which has a vault template ID of "h81d2cf638cb4c5489869928fbaa3f71") and set the vault ID as a variable. It may take a moment to receive your response while Skyflow creates your vault.

   ```bash
   export OUTPUT=$( \
       curl -s -X POST "$MANAGEMENT_URL/v1/vaults" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "name": "Quickstart",
           "templateID": "h81d2cf638cb4c5489869928fbaa3f71",
           "workspaceID": "'"$WORKSPACE_ID"'"
       }'
   ) && \
   echo $OUTPUT | jq && \
   export VAULT_ID=$(echo $OUTPUT | jq -r ".ID")
   ```

2. Set the vault URL as a variable:

   ```bash
   export OUTPUT=$( \
       curl -s -X GET "$MANAGEMENT_URL/v1/vaults/$VAULT_ID" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN"
   ) && \
   echo $OUTPUT | jq && \
   export VAULT_URL=$(echo $OUTPUT | jq -r ".vault.openapiSpec | fromjson | .servers[0].url")
   ```

3. Populate the vault with some placeholder data:

   ```bash
   curl -s -X POST "$VAULT_URL/v1/vaults/$VAULT_ID/credit_cards" \
       -H "Content-Type: application/json" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "records": [
               {
                   "fields": {
                       "card_number": "7483905725643605",
                       "cardholder_name": "Jane Doe",
                       "expiry_month": "12",
                       "expiry_year": "2029"
                   }
               },
               {
                   "fields": {
                       "card_number": "8475027345184987",
                       "cardholder_name": "John Doe",
                       "expiry_month": "04",
                       "expiry_year": "2028"
                   }
               },
               {
                   "fields": {
                       "card_number": "4163890563927785",
                       "cardholder_name": "Terry Doe",
                       "expiry_month": "08",
                       "expiry_year": "2030"
                   }
               }
           ],
           "tokenization": true
       }' | jq && \
   curl -s -X POST "$VAULT_URL/v1/vaults/$VAULT_ID/persons" \
       -H "Content-Type: application/json" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "records": [
               {
                   "fields": {
                       "name": "Jane Doe",
                       "email_address": "jane.doe@acme.com",
                       "ssn": "123-45-6789",
                       "date_of_birth": "1990-02-27",
                       "state": "Louisiana"
                   }
               },
               {
                   "fields": {
                       "name": "John Doe",
                       "email_address": "john.doe@acme.com",
                       "ssn": "567-89-1234",
                       "date_of_birth": "2000-03-14",
                       "state": "Arizona"
                   }
               },
               {
                   "fields": {
                       "name": "Terry Doe",
                       "email_address": "terry.doe@acme.com",
                       "ssn": "223-67-8469",
                       "date_of_birth": "1980-01-01",
                       "state": "California"
                   }
               }
           ],
           "tokenization": true
       }' | jq
   ```

4. Get your Quickstart vault's schema:

   ```bash
   curl -s "$MANAGEMENT_URL/v1/vaults/$VAULT_ID" \
   -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
   -H "Content-Type: application/json" \
   -H "Authorization: Bearer $TOKEN" \
   | jq
   ```

The Quickstart vault has a predefined schema with two tables (**credit\_cards** and **persons**) and fake rows of data.

The role and policies assigned to your user account determine your amount of access to the data. Even though you're the owner of the vault, most fields are redacted or partially redacted by default. A column's definition in the vault schema and your user account's policies determine whether data is full or partially redacted when you access it.

Column settings fall into four categories:

- **General**: Things like the column name, uniqueness, regular expression validation, and transient field status.
- **Tokens**: The kind of non-sensitive token to substitute for sensitive data in the column.
- **Redaction**: How to obscure data to prevent unauthorized access to sensitive data.
- **Encryption**: Operations allowed to perform over fully encrypted data through [polymorphic encryption](https://www.skyflow.com/post/a-look-at-polymorphic-encryption-the-new-paradigm-of-data-privacy). All data within a vault is encrypted at rest and during transit.

To view the **card\_number** column's settings,

#### Studio

1. In the **credit\_cards** table, click the **card\_number** column's down arrow.
2. Choose **View column**.

When you're done investigating the column settings, close the column editor dialog.

#### API

1. In your vault schema, navigate to "vault.schemas", then find the object with a "name" of "credit\_cards". Objects contained within "vault.schemas" are the tables in your vault.
2. Navigate to "fields", then find the object with a "name" of "card\_number". This is the **card\_number** field.
3. Navigte to "tags". This array defines settings for the column. For a reference of available tags and values, see [Vault settings](https://docs.skyflow.com/docs/vaults/vault-settings).

## Perform an encrypted operation

One of the ways you can retrieve records from the vault is through SQL queries. Through polymorphic encryption, your query operations run against fully encrypted data and return results without ever decrypting any of the data.

SQL queries require `LIST` permissions on the columns being accessed. Even if
you filter by specific values in your WHERE clause, the ExecuteQuery operation
requires `LIST` rather than `READ` permissions.

#### Studio

To perform an SQL query,

1. Navigate to the **persons** table.

2. Click **SQL query**.

3. Below the green comments in the text area, type the following SQL statement:

   ```sql
   select * from persons where state = 'California'
   ```

4. Click **Run**.

The encrypted operation runs against your vault, and the results display in the table.

#### API

To perform an SQL query, run the following command:

```bash
curl -s -X POST "$VAULT_URL/v1/vaults/$VAULT_ID/query" \
-H "Content-Type: application/json" \
-H "X-SKYFLOW-ACCOUNT-ID: $ACOUNT_ID" \
-H "Authorization: Bearer $TOKEN" \
-d '{
    "query": "select * from persons where state = '\''California'\''"
}' | jq
```

The encrypted operation runs against your vault and returns an array of record objects that match the query.

## Share limited access to a vault

Within any product or organization, different users and services have different requirements for seeing and interacting with sensitive customer data. Skyflow takes a zero-trust approach to this, where no user or service has access to any data unless explicitly granted. With Skyflow's [data governance engine](/docs/governance/), you can create simple policies that control what a user can see and how they see it.

To control a user's access to vault data, you create a role, create access policies, attach the policies to the role, then assign the role to the user. The following examples show to a marketing role and a customer support role might have different policies and access to the same data.

### Create a marketing role

The marketing role flags read access to specific fields at different levels of visibility.

#### Studio

1. From the vault schema page, click the **Access** in the side navigation.

2. Click **Add new role**.

3. For **Name**, enter "Marketing Role".

4. For **Description**, enter a value. For example, "Limited vault access".

5. Click **Create**.

6. Click **Attach Policies**, and replace the placeholder content with the following policies:

   ```policy
   ALLOW READ, LIST ON persons.name, persons.email_address, persons.state WITH REDACTION = PLAIN_TEXT
   ALLOW READ, LIST ON persons.date_of_birth WITH REDACTION = MASKED
   ALLOW READ, LIST ON persons.ssn WITH REDACTION = REDACTED
   ```

   The policies grant access to view person records in the **persons** table with different redaction levels. The `READ` permissions allow accessing specific records by skyflow\_id or column\_values, while the `LIST` permissions allow viewing all records in Studio or through SQL queries.

7. Click **Create**, enter "Marketing Policy" for the policy name, then click **Save**.

8. Click **Enable**, then close the dialog.

#### API

Creating a role involved creating the role entity, the creating and assigning policies to the role.

1. Create the Marketing role and set the role's ID to a variable:

   ```bash
   export OUTPUT=$( \
       curl -s -X POST "$MANAGEMENT_URL/v1/roles" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "roleDefinition": {
               "name": "Marketing Role"
           },
           "resource": {
               "type": "VAULT",
               "ID": "'"$VAULT_ID"'"
           }
       }'
   ) && \
   echo $OUTPUT | jq && \
   export MARKETING_ROLE_ID=$(echo $OUTPUT | jq -r ".ID")
   ```

2. Create the Marketing policy and set the policy's ID to a variable:

   ```bash
   export OUTPUT=$( \
       curl -s -X POST "$MANAGEMENT_URL/v1/policies" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "name": "Marketing Policy",
           "activated": true,
           "resource": {
               "type": "VAULT",
               "ID": "'"$VAULT_ID"'"
           },
            "ruleParams": [
                {
                    "columnRuleParams": {
                        "vaultID": "'"$VAULT_ID"'",
                        "effect": "ALLOW",
                        "actions": [
                            "READ",
                            "LIST"
                        ],
                        "columns": [
                            "persons.name",
                            "persons.email_address",
                            "persons.state"
                        ],
                        "redaction": "PLAIN_TEXT"
                    }
                },
                {
                    "columnRuleParams": {
                        "vaultID": "'"$VAULT_ID"'",
                        "effect": "ALLOW",
                        "actions": [
                            "READ",
                            "LIST"
                        ],
                        "columns": [
                            "persons.date_of_birth"
                        ],
                        "redaction": "MASKED"
                    }
                },
                {
                    "columnRuleParams": {
                        "vaultID": "'"$VAULT_ID"'",
                        "effect": "ALLOW",
                        "actions": [
                            "READ",
                            "LIST"
                        ],
                        "columns": [
                            "persons.ssn"
                        ],
                        "redaction": "REDACTED"
                    }
                }
            ]
       }'
   ) && \
   echo $OUTPUT | jq && \
   export MARKETING_POLICY_ID=$(echo $OUTPUT | jq -r ".ID")
   ```

   The rules grant access to view person records in the **persons** table with different redaction levels. The `READ` and `LIST` actions allow accessing specific records as well as viewing all records in the table.

3. Assign the Marketing policy to the Marketing role:

   ```bash
   curl -s -X POST "$MANAGEMENT_URL/v1/policies/assign" \
   -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
   -H "Content-Type: application/json" \
   -H "Authorization: Bearer $TOKEN" \
   -d '{
       "ID": "'"$MARKETING_POLICY_ID"'",
       "roleIDs": [
           "'"$MARKETING_ROLE_ID"'"
       ]
   }' | jq
   ```

### Create a customer support role

While the marketing role and policy have limited access to the vault, the customer support role and policies are even more restrictive.

#### Studio

1. Click **Add new role**.

2. For **Name**, enter "Customer Support Role".

3. For **Description**, enter a value. For example, "Restrictive vault access".

4. Click **Create**.

5. Click **Attach Policies**, and replace the placeholder content with the following policies:

   ```policy
   ALLOW READ, LIST ON persons.name, persons.state WITH REDACTION = PLAIN_TEXT
   ALLOW READ, LIST ON persons.ssn WITH REDACTION = MASKED
   ALLOW READ, LIST ON persons.date_of_birth, persons.email_address WITH REDACTION = REDACTED
   ```

   The policies grant access to view person records in the **persons** table with different redaction levels. The `READ` permissions allow accessing specific records by skyflow\_id or column\_values, while the `LIST` permissions allow viewing all records in Studio or through SQL queries.

6. Click **Create**, enter "Customer Support Policy" for the policy name, then click **Save**.

7. Click **Enable**, then close the dialog.

#### API

1. Create the Customer Support role and set the role's ID to a variable:

   ```bash
   export OUTPUT=$( \
       curl -s -X POST "$MANAGEMENT_URL/v1/roles" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "roleDefinition": {
               "name": "Customer Support Role"
           },
           "resource": {
               "type": "VAULT",
               "ID": "'"$VAULT_ID"'"
           }
       }'
   ) && \
   echo $OUTPUT | jq && \
   export SUPPORT_ROLE_ID=$(echo $OUTPUT | jq -r ".ID")
   ```

2. Create the Customer Support policy and set the policy's ID to a variable:

   ```bash
   export OUTPUT=$( \
       curl -s -X POST "$MANAGEMENT_URL/v1/policies" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "name": "Customer Support Policy",
           "activated": true,
           "resource": {
               "type": "VAULT",
               "ID": "'"$VAULT_ID"'"
           },
            "ruleParams": [
                {
                    "columnRuleParams": {
                        "vaultID": "'"$VAULT_ID"'",
                        "effect": "ALLOW",
                        "actions": [
                            "READ",
                            "LIST"
                        ],
                        "columns": [
                            "persons.name",
                            "persons.state"
                        ],
                        "redaction": "PLAIN_TEXT"
                    }
                },
                {
                    "columnRuleParams": {
                        "vaultID": "'"$VAULT_ID"'",
                        "effect": "ALLOW",
                        "actions": [
                            "READ",
                            "LIST"
                        ],
                        "columns": [
                            "persons.ssn"
                        ],
                        "redaction": "MASKED"
                    }
                },
                {
                    "columnRuleParams": {
                        "vaultID": "'"$VAULT_ID"'",
                        "effect": "ALLOW",
                        "actions": [
                            "READ",
                            "LIST"
                        ],
                        "columns": [
                            "persons.date_of_birth",
                            "persons.email_address"
                        ],
                        "redaction": "REDACTED"
                    }
                }
            ]
       }'
   ) && \
   echo $OUTPUT | jq && \
   export SUPPORT_POLICY_ID=$(echo $OUTPUT | jq -r ".ID")
   ```

   The rules grant access to view person records in the **persons** table with different redaction levels. The `READ` and `LIST` actions allow accessing specific records as well as viewing all records in the table.

3. Assign the Customer Support policy to the Customer Support role:

   ```bash
   curl -s -X POST "$MANAGEMENT_URL/v1/policies/assign" \
   -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
   -H "Content-Type: application/json" \
   -H "Authorization: Bearer $TOKEN" \
   -d '{
       "ID": "'"$SUPPORT_POLICY_ID"'",
       "roleIDs": [
           "'"$SUPPORT_ROLE_ID"'"
       ]
   }' | jq
   ```

### Share the vault

To see these policies in action, add a user with the Marketing role and add a user with the Customer Support role, then sign into those accounts in Incognito browser windows.

#### Add users

#### Studio

1. In the **Access** section, click the **People** tab.
2. Click **Add people**.
3. Invite an email address to add to your vault. You might add "+marketing" to
   your email username depending on your email provider, like in
   "[jane.doe+marketing@acme.com](mailto\:jane.doe+marketing@acme.com)".
4. For **Roles**, select **Marketing Role**, then click **Add**.
5. Click **Add people**.
6. Invite an email address to add to your vault. Depending on your email
   provider, you might add "+customer-support" to your email username, like in
   "[jane.doe+customer-support@acme.com](mailto\:jane.doe+customer-support@acme.com)".
7. For **Roles**, select **Customer Support Role**, then click **Add**.

#### API

1. Update the following command with the email addresses you want to invite,
   then run it. You might add "+marketing" and "+customer-support" to your
   email username depending on your email provider, like in
   "[jane.doe+marketing@acme.com](mailto\:jane.doe+marketing@acme.com)" and "[jane.doe+customer-support@acme.com](mailto\:jane.doe+customer-support@acme.com)".

   ```bash
   export MARKETING_EMAIL=$MARKETING_EMAIL
   export SUPPORT_EMAIL=$SUPPORT_EMAIL
   ```

2. Create the Marketing user entity and set the ID to a variable:

   ```bash
   export OUTPUT=$( \
       curl -s -X POST "$MANAGEMENT_URL/v1/users" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "user": {
               "name": "Marketing User",
               "userIdentity": {
                   "email": "'"$MARKETING_EMAIL"'"
               }
           },
           "accountID": "'"$ACCOUNT_ID"'"
       }'
   ) && \
   echo $OUTPUT | jq && \
   export MARKETING_USER_ID=$(echo $OUTPUT | jq -r ".ID")
   ```

3. Assign the Marketing role to the Marketing user:

   ```bash
   curl -s -X POST "$MANAGEMENT_URL/v1/roles/assign" \
   -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
   -H "Content-Type: application/json" \
   -H "Authorization: Bearer $TOKEN" \
   -d '{
       "ID": "'"$MARKETING_ROLE_ID"'",
       "members": [{
           "ID": "'"$MARKETING_USER_ID"'",
           "type": "USER"
       }]
   }' | jq
   ```

4. Create the Customer Support user entity and set the ID to a variable:

   ```bash
   export OUTPUT=$( \
       curl -s -X POST "$MANAGEMENT_URL/v1/users" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "user": {
               "name": "Customer Support User",
               "userIdentity": {
                   "email": "'"$SUPPORT_EMAIL"'"
               }
           },
           "accountID": "'"$ACCOUNT_ID"'"
       }'
   ) && \
   echo $OUTPUT | jq && \
   export SUPPORT_USER_ID=$(echo $OUTPUT | jq -r ".ID")
   ```

5. Assign the Customer Support role to the Customer Support user:

   ```bash
   curl -s -X POST "$MANAGEMENT_URL/v1/roles/assign" \
   -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
   -H "Content-Type: application/json" \
   -H "Authorization: Bearer $TOKEN" \
   -d '{
       "ID": "'"$SUPPORT_ROLE_ID"'",
       "members": [{
           "ID": "'"$SUPPORT_USER_ID"'",
           "type": "USER"
       }]
   }' | jq
   ```

#### View the marketing policies in action

1. Open an incognito browser window.

2. Sign in to Skyflow Studio using your account sign-in URL and the marketing email address you just added to your vault.

3. Click **Open** on the Quickstart vault.

   Skyflow restricts the view of the data based on the Marketing policy you created and assigned to this user.

4. When you're done browsing the vault as this user, close the incognito window.

#### View the customer support policies in action

1. Open another incognito browser window.

2. Sign in to Skyflow Studio using your account sign-in URL and the customer support email address you just added to your vault.

3. Click **Open** on the Quickstart vault.

   Skyflow restricts the view of the data based on the Customer Support policy you created and assigned to this user.

4. Keep this window open.

### Edit the policy

With Skyflow's governance engine, you control how much data a user or service can access in a vault. You can update the rules at any time as business requirements change, and changes go into effect without any code deployments or implementation changes.

#### Studio

1. Back in your first window, navigate to the **Access** section, then click **Roles**.

2. Find the **Customer Support Role** row, then click **View**.

3. Find the **Customer Support Policy** row, then click **Edit**.

4. Move "persons.date\_of\_birth" from the "REDACTED" policy into the "MASKED" policy. Your policies should look like the following:

   ```policy
   ALLOW READ, LIST ON persons.name, persons.state WITH REDACTION = PLAIN_TEXT
   ALLOW READ, LIST ON persons.ssn, persons.date_of_birth WITH REDACTION = MASKED
   ALLOW READ, LIST ON persons.email_address WITH REDACTION = REDACTED
   ```

5. Click **Save**, then close the dialog.

#### API

1. First, get the Customer Support policy entity, parse it for Rule IDs, and load those IDs into variables:

   ```bash
   export OUTPUT=$( \
       curl -s -X GET "$MANAGEMENT_URL/v1/policies/$SUPPORT_POLICY_ID?resource.type=VAULT&resource.ID=$VAULT_ID" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN"
   ) && \
   echo $OUTPUT | jq && \
   export SUPPORT_PLAINTEXT_RULE_ID=$(echo $OUTPUT | jq -r '.. | select( .redaction == "PLAIN_TEXT" // empty )? | .ID') && \
   export SUPPORT_MASKED_RULE_ID=$(echo $OUTPUT | jq -r '.. | select( .redaction == "MASKED" // empty )? | .ID') && \
   export SUPPORT_REDACTED_RULE_ID=$(echo $OUTPUT | jq -r '.. | select( .redaction == "REDACTED" // empty )? | .ID')
   ```

2. Update the Masked and Redacted rules to make the **date\_of\_birth** column masked instead of redacted:

   ```bash
   curl -s -X PATCH "$MANAGEMENT_URL/v1/policies/rules/$SUPPORT_MASKED_RULE_ID" \
       -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
       -H "Content-Type: application/json" \
       -H "Authorization: Bearer $TOKEN" \
       -d '{
           "policyID": "'"$SUPPORT_POLICY_ID"'",
           "ruleParams": {
                "columnRuleParams": {
                    "vaultID": "'"$VAULT_ID"'",
                    "effect": "ALLOW",
                    "actions": [
                        "READ",
                        "LIST"
                    ],
                    "columns": [
                        "persons.ssn",
                        "persons.date_of_birth"
                    ],
                    "redaction": "MASKED"
                }
            }
        }' | jq && \
    curl -s -X PATCH "$MANAGEMENT_URL/v1/policies/rules/$SUPPORT_REDACTED_RULE_ID" \
        -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $TOKEN" \
        -d '{
            "policyID": "'"$SUPPORT_POLICY_ID"'",
            "ruleParams": {
                "columnRuleParams": {
                    "vaultID": "'"$VAULT_ID"'",
                    "effect": "ALLOW",
                    "actions": [
                        "READ",
                        "LIST"
                    ],
                    "columns": [
                        "persons.email_address"
                    ],
                    "redaction": "REDACTED"
                }
           }
       }' | jq
   ```

3. In your incognito window, refresh the vault schema page. The **date\_of\_birth** column data is now masked instead of redacted.

### Add a row restriction

You can restrict view access to records based on record data. For example, you can restrict the customer support role to only be able to view customer records in one state by adding a row restriction.

#### Studio

1. Back in your first window, navigate to the **Access** section, then click **Roles**.

2. Find the **Customer Support Role** row, then click **View**.

3. Find the **Customer Support Policy** row, then click **Edit**.

4. Add a row restriction policy with "WHERE" statements so customer support agents can view only persons in the state of Arizona:

   ```policy
   ALLOW READ, LIST ON persons.name, persons.state WITH REDACTION = PLAIN_TEXT WHERE persons.state = 'Arizona'
   ALLOW READ, LIST ON persons.ssn, persons.date_of_birth WITH REDACTION = MASKED WHERE persons.state = 'Arizona'
   ALLOW READ, LIST ON persons.email_address WITH REDACTION = REDACTED WHERE persons.state = 'Arizona'
   ```

   The policies restrict access to only view persons in the state of Arizona. The `READ` permissions allow accessing specific records by skyflow\_id or column\_values, while the `LIST` permissions allow viewing all records that match the WHERE clause in Studio or through SQL queries.

5. Click **Save**, then close the dialog.

#### API

```bash
curl -s -X PATCH "$MANAGEMENT_URL/v1/policies/rules/$SUPPORT_PLAINTEXT_RULE_ID" \
    -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    -d '{
        "policyID": "'"$SUPPORT_POLICY_ID"'",
        "ruleParams": {
            "columnRuleParams": {
                "vaultID": "'"$VAULT_ID"'",
                "effect": "ALLOW",
                "actions": [
                    "READ",
                    "LIST"
                ],
                "columns": [
                    "persons.name",
                    "persons.state"
                ],
                "redaction": "PLAIN_TEXT",
                "rowFilter": "persons.state = '\''Arizona'\''"
            }
        }
    }' | jq && \
curl -s -X PATCH "$MANAGEMENT_URL/v1/policies/rules/$SUPPORT_MASKED_RULE_ID" \
    -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    -d '{
        "policyID": "'"$SUPPORT_POLICY_ID"'",
        "ruleParams": {
            "columnRuleParams": {
                "vaultID": "'"$VAULT_ID"'",
                "effect": "ALLOW",
                "actions": [
                    "READ",
                    "LIST"
                ],
                "columns": [
                    "persons.ssn",
                    "persons.date_of_birth"
                ],
                "redaction": "MASKED",
                "rowFilter": "persons.state = '\''Arizona'\''"
            }
        }
    }' | jq && \
curl -s -X PATCH "$MANAGEMENT_URL/v1/policies/rules/$SUPPORT_REDACTED_RULE_ID" \
    -H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $TOKEN" \
    -d '{
        "policyID": "'"$SUPPORT_POLICY_ID"'",
        "ruleParams": {
            "columnRuleParams": {
                "vaultID": "'"$VAULT_ID"'",
                "effect": "ALLOW",
                "actions": [
                    "READ",
                    "LIST"
                ],
                "columns": [
                    "persons.email_address"
                ],
                "redaction": "REDACTED",
                "rowFilter": "persons.state = '\''Arizona'\''"
            }
        }
    }' | jq
```

In your incognito window, refresh the vault schema page. The vault data now only shows records matching the **state** of Arizona.

By using a combination of column and row level restrictions, you can severely
reduce the scope of a potential data breach, even in a worst-case scenario
where someone's credentials become compromised.

## Manipulate vault data

A data privacy vault needs data, and you can perform a full suite of CRUD (Create, Read, Update, Delete) operations on the records in your vault. See the full list of data operations in the [Data API](/api/data/).

**Note**: Need a quick tutorial? [Watch a short video](https://youtu.be/a5B61ugbzRI) that shows you how to use both Studio and
Data APIs to manipulate data in your vault.

Performing data operations with the Data API requires the table name and Skyflow ID of the record you want to operate on:

```bash
export TABLE_NAME=$TABLE_NAME
export SKYFLOW_ID=$SKYFLOW_ID
```

### Insert data

#### Studio

1. In the vault schema page, right-click anywhere in the records area, then choose **Insert Record**.
2. Enter field values, then click **Save**.

#### API

The following command inserts a record and returns tokens instead of data values. To return data values, set `tokenization` to `false`.

```bash
curl -s -X POST "$VAULT_URL/v1/vaults/$VAULT_ID/$TABLE_NAME" \
-H "Content-Type: application/json" \
-H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
-H "Authorization: Bearer $TOKEN" \
-d '{
    "records": [
        {
            "fields": {
                "card_number": "7483905725643605",
                "cardholder_name": "Jane Doe",
                "expiry_month": "08",
                "expiry_year": "29"
            }
        }
    ],
    "tokenization": true
}' | jq
```

### Get data

#### Studio

Getting data from a vault is as straightforward as browsing the vault schema page and viewing the records there.

To find specific records, use the SQL filter as described in [Perform an encrypted operation](/docs/fundamentals/get-started/). For a list of available SQL statements, see [Execute Query](/api/data/query/execute-query/).

#### API

The following command returns tokens for the specified record. To return data values, set the "tokenization" URL parameter to "false".

```bash
curl -s -X GET "$VAULT_URL/v1/vaults/$VAULT_ID/$TABLE_NAME/$SKYFLOW_ID?tokenization=true" \
-H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
-H "Authorization: Bearer $TOKEN" | jq
```

### Update data

#### Studio

1. In the vault schema page, find the record and column you want to update.
2. Right-click the record row, then choose **Update Record**.
3. Update the fields with new values, then click **Save**.

#### API

The following command updates the specified record and returns tokens instead of data values. To return data values, set "tokenization" to "false".

```bash
curl -s -X PUT "$VAULT_URL/v1/vaults/$VAULT_ID/$TABLE_NAME/$SKYFLOW_ID" \
-H "Content-Type: application/json" \
-H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
-H "Authorization: Bearer $TOKEN" \
-d '{
    "record": {
        "fields": {
            "card_number": "7483905725643605",
            "cardholder_name": "John Doe",
            "expiry_month": "04",
            "expiry_year": "27"
        }
    },
    "tokenization": true
}' | jq
```

### Delete data

#### Studio

1. In the vault schema page, find the record and column you want to update.
2. Right-click the record row, then choose **Delete Record**.
3. Click **Yes, delete**.

#### API

The following command deletes the specified record.

```bash
curl -s -X DELETE "$VAULT_URL/v1/vaults/$VAULT_ID/$TABLE_NAME/$SKYFLOW_ID" \
-H "X-SKYFLOW-ACCOUNT-ID: $ACCOUNT_ID" \
-H "Authorization: Bearer $TOKEN" | jq
```

## Next steps

Continue exploring what Skyflow can do by

- [creating a vault](https://docs.skyflow.com/docs/vaults/create-a-vault)
- discovering Skyflow's [governance](/docs/governance/) and [tokenization](/docs/tokenization/) capabilities
- integrating with [server-side](/docs/fundamentals/api-authentication/) and [client-side](https://docs.skyflow.com/docs/sdks/client-side/handling-data-client-side) SDKs
- seeing how [Skyflow Connections](/docs/connections/) can help you securely pass data between Skyflow and other vendors you partner with