Skip to content

Commit

Permalink
Add guide for all policy types
Browse files Browse the repository at this point in the history
  • Loading branch information
gabfelp committed Jan 18, 2024
1 parent 1996e69 commit 2765118
Show file tree
Hide file tree
Showing 13 changed files with 603 additions and 129 deletions.
337 changes: 279 additions & 58 deletions docs/guides/repo_level_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,97 +3,318 @@ page_title: "Setup repo-level policy"
---

In this guide, we will attach repo-level data access policies to PostgreSQL and MySQL data
repositories. After reading the guide, you will understand how to setup repo-level policies
and use Cyral policy templates to control data access.
repositories. After reading this guide, you will understand how to setup repo-level policies
and use Cyral's built-in policy templates to control data access.

We recommend that you also read the [Cyral policies](https://cyral.com/docs/policy/overview/)
documentation for more information.

## Prerequisites
## Repo-level policy types

Follow [this
guide](https://registry.terraform.io/providers/cyralinc/cyral/latest/docs/guides/setup_cp_and_deploy_sidecar)
to deploy the repositories and the sidecar.
Cyral offers nine pre-built repo-level policy types. Learn more about them [here](https://cyral.com/docs/policy/repo-level/).
This guide demonstrates creating instances of each type.
Additionally, review the [cyral_rego_policy_instance](https://registry.terraform.io/providers/cyralinc/cyral/latest/docs/resources/rego_policy_instance) resource for clarity in parameters.

## Table-level access policy
## Dataset Protection policy

The following example will add a repo-level policy to restrict access to
specific tables in the repositories:
Add a Dataset Protection policy to restrict access to
specific tables or schemas in the data repositories:

-> **Note** The table-level policy template is only enabled by default in control planes
-> **Note** The Dataset Protection policy template is only enabled by default in control planes
`v4.13` and later. If you have a previous version, please reach out to our customer success
team to enable it.

### Example Usage

```terraform
# Creates pg data repository
resource "cyral_repository" "repo" {
type = "postgresql"
name = "my_pg"
repo_node {
host = "pg.cyral.com"
port = 5432
}
}
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "dataset-protection"
category = "SECURITY"
description = "Blocks reads and updates over schema 'finance' and dataset 'cyral.customers'."
template_id = "dataset-protection"
parameters = "{ \"block\": true, \"alertSeverity\": \"high\", \"monitorUpdates\": true, \"monitorReads\": true, \"datasets\": {\"disallowed\": [\"finance.*\", \"cyral.customers\"]}}"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
}
```

## Data Masking policy

Implement a repo-level policy to mask fields for specific users:

### Example Usage

```terraform
# Creates MySQL data repository
resource "cyral_repository" "repo" {
type = "mysql"
name = "my_mysql"
repo_node {
host = "mysql.cyral.com"
port = 3306
}
}
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "data-masking-policy"
category = "SECURITY"
description = "Masks label CCN for identities in Marketing group"
template_id = "data-masking"
parameters = "{ \"maskType\": \"NULL_MASK\", \"labels\": [\"CCN\"], \"identities\": { \"included\": { \"groups\": [\"Marketing\"] } }}"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
tags = ["tag1", "tag2"]
}
```

## Data Protection policy

Add a repo-level policy to guard against unauthorized updates:

### Example Usage

```terraform
# Creates MySQL data repository
resource "cyral_repository" "repo" {
type = "mysql"
name = "my_mysql"
repo_node {
host = "mysql.cyral.com"
port = 3306
}
}
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "data-protection-policy"
category = "SECURITY"
description = "Protect label CCN for update and delete queries"
template_id = "data-protection"
parameters = "{ \"block\": true, \"alertSeverity\": \"high\", \"monitorUpdates\": true, \"monitorDeletes\": true, \"labels\": [\"CCN\"]}"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
tags = ["tag1", "tag2"]
}
```

## Data Firewall policy

Set up a repo-level policy to limit which rows users can read from a table:

### Example Usage

```terraform
# Creates MySQL data repository
resource "cyral_repository" "repo" {
type = "mysql"
name = "my_mysql"
repo_node {
host = "mysql.cyral.com"
port = 3306
}
}
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "data-firewall-policy"
category = "SECURITY"
description = "Filter 'finance.cards' when someone (except 'Admin' group) reads it"
template_id = "data-firewall"
parameters = "{ \"dataSet\": \"finance.cards\", \"dataFilter\": \" finance.cards.country = 'US' \", \"labels\": [\"CCN\"], \"excludedIdentities\": { \"groups\": [\"Admin\"] } }"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
tags = ["tag1", "tag2"]
}
```

## User Segmentation policy

Implement a repo-level policy to limit which rows a set of users can read from your database:

### Example Usage

```terraform
locals {
# PHONE is a predefined label. It exists by default in your control
# plane.
phone_label = "PHONE"
# Creates MySQL data repository
resource "cyral_repository" "repo" {
type = "mysql"
name = "my_mysql"
repo_node {
host = "mysql.cyral.com"
port = 3306
}
}
resource "cyral_datalabel" "custom_label" {
name = "CUSTOM_LABEL"
description = "This is a custom label."
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "user-segmentation-policy"
category = "SECURITY"
description = "Applies a data filter in 'finance.cards' when someone from group 'Marketing' reads data labeled as 'CCN'"
template_id = "user-sementation"
parameters = "{ \"dataSet\": \"finance.cards\", \"dataFilter\": \" finance.cards.country = 'US' \", \"labels\": [\"CCN\"], \"includedIdentities\": { \"groups\": [\"Marketing\"] } }"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
tags = ["tag1", "tag2"]
}
```

resource "cyral_repository_datamap" "pg_datamap" {
repository_id = cyral_repository.pg_repo.id
mapping {
label = cyral_datalabel.custom_label.name
attributes = ["customer_schema.table1.col1", "customer_schema.table1.col2"]
## Rate Limit policy

Add a repo-level policy to implement a threshold on sensitive data reads over time:

### Example Usage

```terraform
# Creates pg data repository
resource "cyral_repository" "repo" {
type = "postgresql"
name = "my_pg"
repo_node {
host = "pg.cyral.com"
port = 5432
}
}
resource "cyral_repository_datamap" "mysql_datamap" {
repository_id = cyral_repository.mysql_repo.id
mapping {
label = local.phone_label
attributes = ["customer_schema.phone.number"]
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "rate-limit-policy"
category = "SECURITY"
description = "Implement a threshold on label CCN for group Marketing of 500 rows per hour"
template_id = "rate-limit"
parameters = "{ \"rateLimit\": 500, \"block\": true, \"alertSeverity\": \"high\", \"labels\": [\"CCN\"], \"identities\": { \"included\": { \"groups\": [\"Marketing\"] } }}"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
tags = ["tag1", "tag2"]
}
```

## Read Limit policy

Implement a repo-level policy to prevent certain records from being read beyond a specified limit:

### Example Usage

```terraform
# Creates pg data repository
resource "cyral_repository" "repo" {
type = "postgresql"
name = "my_pg"
repo_node {
host = "pg.cyral.com"
port = 5432
}
}
resource "cyral_policy" "customer_data" {
name = "customerData"
data = [local.phone_label, cyral_datalabel.custom_label.name]
description = "Control how customer data is handled."
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "read-limit-policy"
category = "SECURITY"
description = "Limits to 100 the amount of rows that can be read per query on all repository data for group 'Devs'"
template_id = "read-limit"
parameters = "{ \"rowLimit\": 100, \"block\": true, \"alertSeverity\": \"high\", \"appliesToAllData\": true, \"identities\": { \"included\": { \"groups\": [\"Devs\"] } }}"
enabled = true
tags = ["customer"]
scope {
repo_ids = [cyral_repository.repo.id]
}
}
```

# To learn more about Cyral policies, see:
#
# * https://cyral.com/docs/policy/overview
#
resource "cyral_policy_rule" "customer_data_rule" {
policy_id = cyral_policy.customer_data.id
## Repository Protection policy

identities {
groups = ["client_support", "client_onboarding"]
Set up a repo-level policy to alert when more than a specified number of records are updated or deleted:

### Example Usage

```terraform
# Creates MySQL data repository
resource "cyral_repository" "repo" {
type = "mysql"
name = "my_mysql"
repo_node {
host = "mysql.cyral.com"
port = 5432
}
}
# Expect max one entry to be deleted per operation.
deletes {
data = [local.phone_label, cyral_datalabel.custom_label.name]
rows = 1
severity = "high"
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "repository-protection-policy"
category = "SECURITY"
description = "Limits to 100 the amount of rows that can be updated or deleted per query on all repository data for anyone except group 'Admin'"
template_id = "repository-protection"
parameters = "{ \"rowLimit\": 100, \"block\": true, \"alertSeverity\": \"high\", \"monitorUpdates\": true, \"monitorDeletes\": true, \"identities\": { \"excluded\": { \"groups\": [\"Admin\"] } }}"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
# Expect max one entry updated per operation.
updates {
data = [local.phone_label, cyral_datalabel.custom_label.name]
rows = 1
severity = "high"
}
```

## Service Account Abuse policy

Implement a repo-level policy to ensure service accounts can only be used by intended applications:

### Example Usage

```terraform
# Creates pg data repository
resource "cyral_repository" "repo" {
type = "postgresql"
name = "my_pg"
repo_node {
host = "pg.cyral.com"
port = 5432
}
# A query to read more than 100 entries is not considered normal.
reads {
data = [local.phone_label, cyral_datalabel.custom_label.name]
rows = 100
severity = "medium"
}
# create policy instance from template
resource "cyral_rego_policy_instance" "policy" {
name = "service account abuse policy"
category = "SECURITY"
description = "Always require user attribution for service acount 'john'"
template_id = "service-account-abuse"
parameters = "{ \"block\": true, \"alertSeverity\": \"high\", \"serviceAccounts\": [\"john\"]}"
enabled = true
scope {
repo_ids = [cyral_repository.repo.id]
}
}
```

## Next steps

This guide presents a very simple Cyral repo-level policy. Cyral policies have many more
capabilities. Check out all attributes that the policy rule resource supports:
[cyral_policy_rule](https://registry.terraform.io/providers/cyralinc/cyral/latest/docs/resources/policy_rule).
This guide presents a very simple example of Cyral repo-level policy for each one of the pre-built templates.
Cyral policies have many more capabilities. Check out all parameters that each repo-level policy type supports and use them however you see fit:
[template_parameters in cyral_rego_policy_instance](https://registry.terraform.io/providers/cyralinc/cyral/latest/docs/resources/rego_policy_instance#template-parameters).
Loading

0 comments on commit 2765118

Please sign in to comment.