# Policies

Terrascan policies are written using the [Rego policy language](https://www.openpolicyagent.org/docs/latest/policy-language/). With each rego policy a JSON "rule" file is included which defines metadata for the policy. Policies included within Terrascan are stored in the [pkg/policies/opa/rego](https://github.com/accurics/terrascan/tree/master/pkg/policies/opa/rego) directory.


## Updating Terrascan with the latest policies

The first time using Terrascan, if the `-p` flag is not specified, Terrascan will download the latest policies from the Terrascan repository. To update with the latest policies remove the `~/.terrascan` directory from your system and run `terrascan init`.

## Ignoring Policies on a scan

Terrascan keeps a copy of policies on your local filesystem on the `~/.terrascan/pkg/policies/opa/rego` directory. You can also specify a particular directory with rego policies to scan by using the `-p` flag. To ignore a particular policy from a scan, you can remove the rule `.json` file for the policy you would like to ignore from the scan. Note that this policy would be ignored until the `.json` file is added again to the directory.

In a future enhancement, Terrascan will have a better way to ignore individual policies from scans without having to modify the policies stored in the file system [#367](https://github.com/accurics/terrascan/issues/367).

## Adding policies

For each policy there are 2 files required by Terrascan, a rule `.json` file with metadata for the policy and a `.opa` [rego](https://www.openpolicyagent.org/docs/latest/policy-language/) file for the policy itself.

### Writing an OPA rego policy file
The input for the rego policies is the normalized input from the IaC provider. When writing policies you can obtain this as a normalized `.json` by using the `--config-only` flag of the scan command in combination with `-o json`. Let's use this Terraform HCL file for example:

``` hcl
resource "github_repository" "example" {
  name        = "example"
  description = "My awesome codebase"

  private = false

  template {
    owner = "github"
    repository = "terraform-module-template"
  }
}
```

Here's the output of the `--config-only` flag.

``` json
$ terrascan scan -i terraform --config-only -o json
{
  "github_repository": [
    {
      "id": "github_repository.example",
      "name": "example",
      "source": "main.tf",
      "line": 1,
      "type": "github_repository",
      "config": {
        "description": "My awesome codebase",
        "name": "example",
        "private": false,
        "template": [
          {
            "owner": "github",
            "repository": "terraform-module-template"
          }
        ]
      }
    }
  ]
}
```


You can use this `.json` output as the input in the [rego playgound](https://play.openpolicyagent.org/). The following policy can be used on the above Terraform to flag if the GitHub repository has been created with `private = false`.

```
package accurics

privateRepoEnabled[api.id] {
    api := input.github_repository[_]
    not api.config.private == true
    not api.config.visibility == "private"
}
```

A successful policy will trigger the following output:

``` json
{
    "privateRepoEnabled": [
        "github_repository.example"
    ]
}
```

### The Rule JSON file

The rule files follow this naming convention: `<cloud-provider>.<resource-type>.<rule-category>.<severity>.<next-available-rule-number>.json`

Here's an example of the contents of a rule file:

``` json
{
    "name": "unrestrictedIngressAccess",
    "file": "unrestrictedIngressAccess.rego",
    "template_args": {
        "prefix": ""
    },
    "severity": "HIGH",
    "description": " It is recommended that no security group allows unrestricted ingress access",
    "reference_id": "AWS.SecurityGroup.NetworkSecurity.High.0094",
    "category": "Network Ports Security",
    "version": 2
}
```

| Key                  | Value                                         |
| -------------------- | --------------------------------------------- |
| name                 | Short name for the rule                       |
| file                 | File name of the Rego policy                  |
| template_args.prefix | Used for making rego policies unique          |
| severity             | Likelihood * impact of issue                  |
| description          | Description of the issue found with this rule |
| ruleReferenceId      | Unique ID of the rule in the format `<cloud-provider>.<resource-type>.<rule-category>.<severity>.<next-available-rule-number>` |
| category            | Descriptive category for this rule    |
| version             | Version number for the rule/rego      |

--8<-- "docs/policies/aws.md"

--8<-- "docs/policies/azure.md"

--8<-- "docs/policies/gcp.md"

--8<-- "docs/policies/github.md"

--8<-- "docs/policies/k8s.md"

--8<-- "docs/policies/github.md"
