Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(docs): Update docs #1489

Merged
merged 4 commits into from
Nov 4, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/images/defsec-components.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ graph TD;
dfparser --> rules
```

## Component breakdown

defsec is further divided into 3 high level components as shown below
![defsec-components.png](.github/images/defsec-components.png)

## Scanning Overview

The diagram below shows the process for parsing -> adapting -> scanning -> reporting.
Expand Down
97 changes: 10 additions & 87 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,103 +3,26 @@

Welcome, and thank you for considering contributing to defsec!

The following guide gives an overview of the project and some directions on how to make common types of contribution. If something is missing or you get stuck, please [jump on Slack](https://slack.aquasec.com/) or [start a discussion](https://github.com/aquasecurity/defsec/discussions/new) and we'll do our best to help.
The following guide gives an overview of the project and some directions on how to make common types of contribution. If something is missing, or you get stuck, please [start a discussion](https://github.com/aquasecurity/trivy/discussions/new) and we'll do our best to help.

## Project Overview

_defsec_ is a library for defining security rules and policies in code, and the tools to apply those rules/cloud/policies to a variety of sources. The general architecture and project layout are defined in [ARCHITECTURE.md](ARCHITECTURE.md) - this is a great place to start exploring.
_defsec_ repo is a collection of shared libraries and packages that are imported by other useful packages such as `trivy-iac`, `trivy-aws` and also `Trivy` directly.

_defsec_ is also the misconfiguration/IaC/Cloud scanning engine for Trivy. Trivy uses defsec internally as a library to perform various scans.
_trivy-iac_ is the collection of all Infrastructure-as-code libraries and packages that Trivy uses to perform IaC scanning. It also where you can find `schemas` to write custom polices.

## Guides

The following are guides for contributing to the project in specific ways. If you're not sure where to start, these are a good place to look. If you need some tips on getting started with contributing to open source in general, check out this useful [GitHub contribution guide](https://docs.github.com/en/get-started/quickstart/contributing-to-projects).

### Writing Rules

Writing a new rule can be relatively simple, but there are a few things to keep in mind. The following guide will help you get started.

First of all, you should check if the provider your rule targets is supported by _defsec_. If it's not, you'll need to add support for it. See [Adding Support for a New Cloud Provider](#adding-support-for-a-new-cloud-provider) for more information. You can check if support exists by looking for a directory with the provider name in `pkg/providers`. If you find your provider, navigate into the directory and check for a directory with the name of the service you're targeting. If you can't find that, you'll need to add support for it. See [Adding Support for a New Service](#adding-support-for-a-new-service) for more information.
_trivy-aws_ is the AWS scanning component of Trivy.

Next up, you'll need to check if the properties you want to target are supported, and if not, add support for them. The guide on [Adding Support for a New Service](#adding-support-for-a-new-service) covers adding new properties.
_trivy-policies_ is the repo that holds all misconfiguration checks for `Trivy`. It also hosts the policy bundles for misconfiguration scanning that `Trivy` uses.

At last, it's time to write your rule code! Rules are defined using _OPA Rego_. You can find a number of examples in the `rules/cloud/policies` directory. The [OPA documentation](https://www.openpolicyagent.org/docs/latest/policy-language/) is a great place to start learning Rego. You can also check out the [Rego Playground](https://play.openpolicyagent.org/) to experiment with Rego, and [join the OPA Slack](https://slack.openpolicyagent.org/).
You can read more about the project overview on the [architecture](./ARCHITECTURE.md) page.

Create a new file in `rules/cloud/policies` with the name of your rule. You should nest it in the existing directory structure as applicable. The package name should be in the format `builtin.PROVIDER.SERVICE.ID`, e.g. `builtin.aws.rds.aws0176`.

Running `make id` will provide you with the next available _ID_ for your rule. You can use this ID in your rule code to identify it.

A simple rule looks like the following example:

```rego
# METADATA
# title: "RDS IAM Database Authentication Disabled"
# description: "Ensure IAM Database Authentication is enabled for RDS database instances to manage database access"
# scope: package
# schemas:
# - input: schema.input
# related_resources:
# - https://docs.aws.amazon.com/neptune/latest/userguide/iam-auth.html
# custom:
# avd_id: AVD-AWS-0176
# provider: aws
# service: rds
# severity: MEDIUM
# short_code: enable-iam-auth
# recommended_action: "Modify the PostgreSQL and MySQL type RDS instances to enable IAM database authentication."
# input:
# selector:
# - type: cloud
package builtin.aws.rds.aws0176

deny[res] {
instance := input.aws.rds.instances[_]
instance.engine.value == ["postgres", "mysql"][_]
not instance.iamauthenabled.value
res := result.new("Instance does not have IAM Authentication enabled", instance.iamauthenabled)
}
```

In fact, this is the code for an actual rule. You can find it in `rules/cloud/policies/aws/rds/enable_iam_auth.rego`.

The metadata is the top section that starts with `# METADATA`, and is fairly verbose. You can copy and paste from another rule as a starting point. This format is effectively _yaml_ within a Rego comment, and is [defined as part of Rego itself](https://www.openpolicyagent.org/docs/latest/policy-language/#metadata).

Let's break the metadata down.

- `title` is fairly self explanatory - it is a title for the rule. The title should clearly and succinctly state the problem which is being detected.
- `description` is also fairly self explanatory - it is a description of the problem which is being detected. The description should be a little more verbose than the title, and should describe what the rule is trying to achieve. Imagine it completing a sentence starting with `You should...`.
- `scope` is used to define the scope of the policy. In this case, we are defining a policy that applies to the entire package. _defsec_ only supports using package scope for metadata at the moment, so this should always be the same.
- `schemas` tells Rego that it should use the `schema.input` to validate the use of the input data in the policy. Generally you can use this as-is in order to detect errors in your policy, such as referencing a policy which doesn't exist in the defsec schema.
- `custom` is used to define custom fields that can be used by defsec to provide additional context to the policy and any related detections. This can contain the following:
- `avd_id` is the ID of the rule in the [AWS Vulnerability Database](https://avd.aquasec.com/). This is used to link the rule to the AVD entry. You can generate an ID to use for this field using `make id`.
- `provider` is the name of the provider the rule targets. This should be the same as the provider name in the `pkg/providers` directory, e.g. `aws`.
- `service` is the name of the service the rule targets. This should be the same as the service name in the `pkg/providers` directory, e.g. `rds`.
- `severity` is the severity of the rule. This should be one of `LOW`, `MEDIUM`, `HIGH`, or `CRITICAL`.
- `short_code` is a short code for the rule. This should be a short, descriptive name for the rule, separating words with hyphens. You should omit provider/service from this.
- `recommended_action` is a recommended remediation action for the rule. This should be a short, descriptive sentence describing what the user should do to resolve the issue.
- `input` tells _defsec_ what inputs this rule should be applied to. Cloud provider rules should always use the `selector` input, and should always use the `type` selector with `cloud`. Rules targeting Kubernetes yaml can use `kubenetes`, RBAC can use `rbac`, and so on.

Now you'll need to write the rule logic. This is the code that will be executed to detect the issue. You should define a rule named `deny` and place your code inside this.

```rego
deny[res] {
instance := input.aws.rds.instances[_]
instance.engine.value == ["postgres", "mysql"][_]
not instance.iamauthenabled.value
res := result.new("Instance does not have IAM Authentication enabled", instance.iamauthenabled)
}
```

The rule should return a result, which can be created using `result.new` (this function does not need to be imported, it is defined internally and provided at runtime). The first argument is the message to display, and the second argument is the resource that the issue was detected on.

In the example above, you'll notice properties are being accessed from the `input.aws` object. The full set of schemas containing all of these properties is [available here](https://github.com/aquasecurity/defsec/tree/master/pkg/rego/schemas). You can match the schema name to the type of input you want to scan.

You should also write a test for your rule(s). There are many examples of these in the `rules/cloud/policies` directory.

Finally, you'll want to run `make docs` to generate the documentation for your new policy.
## Guides

You can see a full example PR for a new rule being added here: [https://github.com/aquasecurity/defsec/pull/1000](https://github.com/aquasecurity/defsec/pull/1000).
The following are guides for contributing to the project in specific ways. If you're not sure where to start, these are a good place to look. If you need some tips on getting started with contributing to open source in general, check out this useful [GitHub contribution guide](https://docs.github.com/en/get-started/quickstart/contributing-to-projects).

### Writing New Policies
You can find a guide to writing new policies [insert link here from trivy-policies repo]()
simar7 marked this conversation as resolved.
Show resolved Hide resolved

### Adding Support for a New Cloud Provider

Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[![GoReportCard](https://goreportcard.com/badge/github.com/aquasecurity/defsec)](https://goreportcard.com/report/github.com/aquasecurity/defsec)
[![Join Our Slack](https://img.shields.io/badge/Slack-Join-green)](https://slack.aquasec.com/)

# defsec

_defsec_ is a cloud security rules engine.
Expand All @@ -9,4 +6,4 @@ Please see [CONTRIBUTING.md](CONTRIBUTING.md) and [ARCHITECTURE.md](ARCHITECTURE

_defsec_ is an [Aqua Security](https://aquasec.com) open source project.
Learn about our open source work and portfolio [here](https://www.aquasec.com/products/open-source-projects/).
Join the community, and talk to us about any matter in [GitHub Discussion](https://github.com/aquasecurity/defsec/discussions) or [Slack](https://slack.aquasec.com).
Join the community, and talk to us about any matter in [GitHub Discussion](https://github.com/aquasecurity/trivy/discussions)