diff --git a/docs/devel/RELEASE.md b/docs/devel/RELEASE.md
index 12f81cc761..5b2c115744 100644
--- a/docs/devel/RELEASE.md
+++ b/docs/devel/RELEASE.md
@@ -48,7 +48,7 @@ standard GitHub fork workflow. See [OPA Dev Instructions](DEVELOPMENT.md)
```
Note: This stage can fail if you have not registered an [SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
- on your Github account.
+ on your GitHub account.
1. Create a release branch off of `main`, to ensure you don't mangle your
fork while creating the release:
diff --git a/docs/docs/aws-cloudformation-hooks.md b/docs/docs/aws-cloudformation-hooks.md
index a828e1ee6e..c4cf67b016 100644
--- a/docs/docs/aws-cloudformation-hooks.md
+++ b/docs/docs/aws-cloudformation-hooks.md
@@ -10,7 +10,7 @@ invoked before a resource is created, updated or deleted.
AWS currently supports hooks written in either Java or Python, and provides a
[sample repository](https://github.com/aws-cloudformation/aws-cloudformation-samples), which includes example hooks
-written in both languages. Since we'd rather use OPA for this purpose, we'd need some code to process the requests
+written in both languages. Since OPA is preferred for this purpose, some code is needed to process the requests
handled by the hook and send them forward to OPA for policy decisions via its
[REST API](https://www.openpolicyagent.org/docs/rest-api) using
the [OPA AWS CloudFormation Hook](https://github.com/StyraOSS/opa-aws-cloudformation-hook).
@@ -19,10 +19,10 @@ the [OPA AWS CloudFormation Hook](https://github.com/StyraOSS/opa-aws-cloudforma
This tutorial shows how to deploy an AWS CloudFormation Hook that forwards requests to OPA for policy decisions,
allowing us to use policy to determine whether a request to create, update or delete a resource should be
-allowed or denied. We'll learn how to author policies that take the input structure of CloudFormation Templates into
+allowed or denied. This tutorial covers authoring policies that take the input structure of CloudFormation Templates into
account, and some special considerations to be aware of in this environment.
-In addition, this tutorial shows how we can leverage dynamic policy composition to group and structure our policies in a
+In addition, this tutorial shows how dynamic policy composition can group and structure policies in a
way that follows the domain to which they apply.
## Prerequisites
@@ -106,7 +106,7 @@ The hook is now installed, configured and activated!
### 3. Learn the Domain
-Before we proceed to write our first policy, let's take a closer look at the data we'll be working with.
+Before writing the first policy, take a closer look at the data used in this tutorial.
#### AWS CloudFormation Templates
@@ -167,9 +167,9 @@ Any request denied will be logged in [AWS CloudWatch](https://aws.amazon.com/clo
### 4. Write a CloudFormation Hook Policy
-With knowledge of the domain and the data model, we're ready to write our first CloudFormation Hook policy. Since we'll
-have a single OPA endpoint servicing requests for all types of resources, we'll use the
-[default decision](./configuration/#miscellaneous) policy, which by default queries the `system.main` rule. Let's add a
+With knowledge of the domain and the data model, it is time to write the first CloudFormation Hook policy. Since
+a single OPA endpoint services requests for all types of resources, the tutorial uses the
+[default decision](./configuration/#miscellaneous) policy, which by default queries the `system.main` rule. Add a
simple policy to block an S3 Bucket unless it has an `AccessControl` attribute set to `Private`:
```rego
@@ -197,8 +197,8 @@ bucket_is_private if {
}
```
-Since we know that CloudFormation Templates may contain only the bare minimum of information, we can't assume that there
-will be an `AccessControl` attribute present in the input at all. Using negation of boolean rules inside of our `deny`
+Since CloudFormation Templates may contain only the bare minimum of information, it is not safe to assume that there
+will be an `AccessControl` attribute present in the input at all. Using negation of boolean rules inside the `deny`
rules help alleviate the problem of values potentially being undefined. Compare to the following deny rule, which might
look correct at a first glance:
@@ -240,7 +240,7 @@ block_public_acls if {
### 5. Policy Enforcement Testing
-With the above policy loaded into OPA, we may proceed to try it out. Let's deploy the minimal S3 Bucket from the
+With the above policy loaded into OPA, deploy the minimal S3 Bucket from the
previous template example. Save the below minimal template to a file called `s3bucket.yaml`:
```yaml
@@ -249,15 +249,15 @@ Resources:
Type: AWS::S3::Bucket
```
-Since our S3 bucket doesn't have an `AccessControl` attribute, it should be denied by the hook. We
-deploy a template by creating a **stack**:
+Since the S3 bucket doesn't have an `AccessControl` attribute, it should be denied by the hook.
+Deploy a template by creating a **stack**:
```shell
aws cloudformation create-stack --stack-name cfn-s3 --template-body file://s3bucket.yaml
```
The output of the above command will simply be a confirmation that the stack was deployed. It won't tell us whether the
-deployment was successful or not. In order to know that, we'll need to check the stack events:
+deployment was successful or not. In order to know that, check the stack events:
```shell
aws cloudformation describe-stack-events --stack-name cfn-s3
@@ -288,8 +288,7 @@ should now find an item describing that the hook denied the request, and its rea
}
```
-Congratulations! You've just successfully enforced your first CloudFormation Hook policy using OPA. Let's update the
-template so that it passes our policy requirement:
+The policy is now enforced. Update the template so that it passes the policy requirement:
**s3bucket.yaml**
@@ -301,14 +300,14 @@ Resources:
AccessControl: Private
```
-Even though our stack did not create an S3 bucket (as the change got rolled back), the **stack** still exists.
-In order to try again, we'll first need to delete the existing stack:
+Even though the stack did not create an S3 bucket (as the change got rolled back), the **stack** still exists.
+To try again, first delete the existing stack:
```shell
aws cloudformation delete-stack --stack-name cfn-s3
```
-Now, let's try again:
+Try again:
```shell
aws cloudformation create-stack --stack-name cfn-s3 --template-body file://s3bucket.yaml
@@ -335,7 +334,7 @@ a bit later.
}
```
-Note: once our stack is successfully deployed, we can use the `update-stack` command after we've made changes to our
+Note: once the stack is successfully deployed, the `update-stack` command can be used after changes are made to
templates:
```shell
@@ -346,11 +345,11 @@ aws cloudformation update-stack --stack-name cfn-s3 --template-body file://s3buc
### Dynamic Policy Composition
-Having a single policy file for all rules will quickly become unwieldy. Could we improve this somehow? One way of doing
+Having a single policy file for all rules will quickly become unwieldy. Is there room for improvement? One way of doing
that would be to use dynamic policy composition, where a single main policy acts as a "router", and forwards queries to
other packages based on attributes from the input. A natural attribute to use for CloudFormation templates might for
-example be the resource type, allowing us to group our policies by the resource type they're meant to act on. Let's
-take a look at what such a main policy might look like:
+example be the resource type, allowing policies to be grouped by the resource type they are meant to act on.
+Here is what such a main policy might look like:
```rego title="main.rego"
# METADATA
@@ -422,15 +421,15 @@ The above policy will invoke the `route` rule to determine which package should
`input.resource.type`, transforming a value such as `AWS::S3::Bucket` into a call to the `data.aws.s3.bucket` package,
where each rule named `deny` will be evaluated, and the result aggregated into the final decision.
-Since most of our policies will only deal with `CREATE` or `UPDATE` actions, we'd rather want to avoid having to check
-for this in all of our rules. Instead, we'll have the router append `.delete` to the package name for `DELETE`
+Since most policies only deal with `CREATE` or `UPDATE` actions, it is better to avoid checking
+for this in all rules. Instead, the router appends `.delete` to the package name for `DELETE`
operations, so that a request to delete e.g. an S3 bucket would invoke the `data.aws.s3.bucket.delete` package (if it
exists).
-Additionally, we'll also do some simple input validation at this stage, so that we may avoid doing so in our resource
-specific policies.
+Additionally, some simple input validation is done at this stage, to avoid repeating it in each
+resource-specific policy.
-We can now modify our original policy to verify S3 bucket resources only:
+Modify the original policy to verify S3 bucket resources only:
```rego
package aws.s3.bucket
@@ -444,7 +443,7 @@ bucket_is_private if {
}
```
-Note how we no longer need the `bucket_create_or_update` rule, as that is already asserted by the main policy.
+Note that the `bucket_create_or_update` rule is no longer needed, as that is already asserted by the main policy.
Quite an improvement in terms of readability, and a good foundation for further policy authoring. If you'd like to see
more examples of policy utilizing this pattern, check out the
[policy directory](https://github.com/StyraOSS/opa-aws-cloudformation-hook/tree/main/examples/policy) in the OPA AWS
diff --git a/docs/docs/cicd/index.md b/docs/docs/cicd/index.md
index 1a5cab7203..2fc07389a7 100644
--- a/docs/docs/cicd/index.md
+++ b/docs/docs/cicd/index.md
@@ -5,13 +5,12 @@ sidebar_position: 1
# Using OPA in CI/CD Pipelines
-OPA is a great tool for implementing policy-as-code guardrails in
+OPA supports implementing policy-as-code guardrails in
CI/CD
pipelines. With OPA, you can automatically verify configurations, validate
outputs, and enforce organizational policies before code reaches production. OPA
-serves as a powerful 'swiss army knife' for implementing custom checks required
-by your organization that might be difficult to implement in a script or in
-another tool.
+can implement custom checks required by your organization that might be
+difficult to implement in a script or in another tool.
For users looking to parse and validate configuration files or Infrastructure as
Code (IaC) committed to git, [Conftest](https://www.conftest.dev) is typically
@@ -19,8 +18,8 @@ the better choice as it supports many file formats (HCL, Jsonnet etc.).
However, OPA's `eval` command excels at connecting other tools and making checks
against runtime data, as it can only parse JSON and YAML formats.
-OPA as a CLI tool provides powerful capabilities for testing and validating
-various types of data in your continuous integration workflows:
+OPA's CLI supports testing and validating various types of data in your
+continuous integration workflows:
- **Repository governance** - Use OPA to call GitHub APIs to validate commit
message formats and pull request metadata compliance.
@@ -89,7 +88,7 @@ jobs:
'input.results[_].coverage < 0.7'
```
-Here's some examples of how we use these actions in our own CI/CD pipelines for OPA!
+Here are some examples of how these actions are used in OPA's CI/CD pipelines:
- [Pull Request Workflow File](https://github.com/open-policy-agent/opa/blob/main/.github/workflows/pull-request.yaml)
- [PR Where Action was Introduced](https://github.com/open-policy-agent/opa/pull/8183/files#diff-a8619735ff14304aa0514284f86ff5145b0a6bae2e76a37faeb0ad899a3d8db4R27-R30)
diff --git a/docs/docs/comparisons/access-control-systems.md b/docs/docs/comparisons/access-control-systems.md
index bd5ede3a45..25a5fe65e9 100644
--- a/docs/docs/comparisons/access-control-systems.md
+++ b/docs/docs/comparisons/access-control-systems.md
@@ -2,13 +2,12 @@
title: Access Control Systems
---
-Often the easiest way to understand a new tool or language is by comparing it to
-what you already know. Here we show how policies from several existing policy
+Comparing a new tool or language to what you already know can help build familiarity. This page shows how policies from several existing policy
systems can be implemented with the Open Policy Agent and Rego.
:::tip
Looking for comparisons between OPA's Rego language and languages like Go, Java
-and Python? Head to our [language comparison](../comparisons/languages)
+and Python? See the [language comparison](../comparisons/languages)
documentation.
:::
@@ -25,7 +24,7 @@ Once you provide RBAC with both those assignments, RBAC tells you
how to make an authorization decision. A user is authorized for
all those permissions assigned to any of the roles she is assigned to.
-For example, we might have the following user/role assignments:
+For example, consider the following user/role assignments:
| User | Role |
| ------- | ------------- |
@@ -115,8 +114,7 @@ in each pair below would violate SOD.
OPA's API does not yet let you enforce SOD by rejecting improper role-assignments,
but it does let you express SOD constraints and ask for all SOD violations,
-as shown below. (Here we assume the statements below are added to the RBAC
-statements above.)
+as shown below. (The statements below extend the RBAC statements above.)
```rego
# Pairs of roles that no user can be assigned to simultaneously
@@ -152,7 +150,7 @@ It has three main components:
- Attributes for objects
- Logic dictating which attribute combinations are authorized
-For example, we might know the following attributes for our users
+For example, consider the following attributes for users
- alice
- joined the company 15 years ago
@@ -161,7 +159,7 @@ For example, we might know the following attributes for our users
- joined the company 5 years ago
- is an analyst
-We would also have attributes for the objects, in this case stock ticker symbols.
+Attributes for the objects, in this case stock ticker symbols, are also needed.
- MSFT
- is sold on NASDAQ
@@ -237,7 +235,7 @@ allow if {
In OPA, there's nothing special about users and objects. You can attach
attributes to anything. And the attributes can themselves be structured JSON objects
and have attributes on attributes on attributes, etc. Because OPA was designed to work
-with arbitrarily nested JSON data, it supports incredibly rich ABAC policies.
+with arbitrarily nested JSON data, it supports expressive ABAC policies.
## Amazon Web Services IAM
@@ -246,7 +244,7 @@ and selected resources. You write `allow` and `deny` statements to enforce which
execute which API calls on which resources under certain conditions.
By default all API access requests are implicitly denied (i.e., not allowed). Policy statements
can explicitly allow or deny API requests. If a request is both allowed and denied, it is always denied.
-Let's assume that the following [customer managed policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies) is defined in AWS:
+Assume that the following [customer managed policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#customer-managed-policies) is defined in AWS:
```json
{
diff --git a/docs/docs/configuration.md b/docs/docs/configuration.md
index 4360fea127..10b1723e78 100644
--- a/docs/docs/configuration.md
+++ b/docs/docs/configuration.md
@@ -441,7 +441,7 @@ request OPA will re-read the credentials from the file and use them for authenti
#### Using SSO Profile Credentials
If specifying `sso_credentials`, OPA will expect to find an sso profile configured as explained in [SSO Profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) and stored in the [config](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html) file on disk.
-On each request, Opa will try to use cached token acquired credentials using the SSO credentials. In case the current token has expired, OPA will try to refresh the token using the SSO refresh token, assuming the SSO session is still valid. New token will be cached in memory.
+On each request, OPA will try to use cached token acquired credentials using the SSO credentials. In case the current token has expired, OPA will try to refresh the token using the SSO refresh token, assuming the SSO session is still valid. New token will be cached in memory.
| Field | Type | Required | Description |
| --------------------------------------------------------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -657,7 +657,7 @@ signing requests to other AWS services.
A special case is that bearer authentication works differently to normal service authentication. The OCI downloader base64-encodes the credentials for you so that they need to be supplied in plain text.
-For _GHCR_ (Github Container Registry) you can use a developer PAT (personal access token) when downloading a private image. These can be supplied as:
+For _GHCR_ (GitHub Container Registry) you can use a developer PAT (personal access token) when downloading a private image. These can be supplied as:
```yaml
credentials:
@@ -863,10 +863,12 @@ included in the actual bundle gzipped tarball.
| `discovery.signing.exclude_files` | `array` | No | Files in the bundle to exclude during verification. |
| `discovery.persist` | `bool` | No | Persist activated discovery bundle to disk. |
-> β οΈ The plugin trigger mode configured on the discovery plugin will be inherited by the bundle, decision log
-> and status plugins. For example, if the discovery plugin is configured to use the manual trigger mode, all other
-> plugins will use manual triggering as well. If any of the plugins explicitly specify a different mode (for ex. periodic),
-> OPA will generate a configuration error.
+:::warning
+The plugin trigger mode configured on the discovery plugin will be inherited by the bundle, decision log
+and status plugins. For example, if the discovery plugin is configured to use the manual trigger mode, all other
+plugins will use manual triggering as well. If any of the plugins explicitly specify a different mode (for ex. periodic),
+OPA will generate a configuration error.
+:::
The following `discovery` configuration fields are supported but deprecated:
diff --git a/docs/docs/contrib-adding-builtin-functions.md b/docs/docs/contrib-adding-builtin-functions.md
index b4aab80c2f..53aa46a801 100644
--- a/docs/docs/contrib-adding-builtin-functions.md
+++ b/docs/docs/contrib-adding-builtin-functions.md
@@ -27,7 +27,7 @@ The following example adds a simple built-in function, `repeat(string, int)`, th
### Declare and Register
-In `ast/builtins.go`, we declare the structure of our built-in function with a `Builtin` struct instance:
+In `ast/builtins.go`, declare the structure of the built-in function with a `Builtin` struct instance:
```go
var Repeat = &Builtin{
@@ -44,7 +44,7 @@ var Repeat = &Builtin{
}
```
-To register the new built-in function, we locate the `DefaultBuiltins` array in `ast/builtins.go`, and add the `Builtin` instance to it:
+To register the new built-in function, locate the `DefaultBuiltins` array in `ast/builtins.go` and add the `Builtin` instance to it:
```go
var DefaultBuiltins = [...]*Builtin{
@@ -56,9 +56,9 @@ var DefaultBuiltins = [...]*Builtin{
### Implement
-In the `topdown` package, we locate a suitable source file for our new built-in function, or add a new file, as appropriate.
+In the `topdown` package, locate a suitable source file for the new built-in function, or add a new file, as appropriate.
-In this example, we introduce a new source file, `topdown/repeat.go`:
+This example introduces a new source file, `topdown/repeat.go`:
```go
package topdown
@@ -105,7 +105,7 @@ The call to `RegisterBuiltinFunc(...)` in `init()` adds the built-in function to
All built-in function implementations must include a test suite.
Test cases for built-in functions are written in YAML and located under `test/cases/testdata/v1`.
-We create two new test cases (one positive, expecting a string output; and one negative, expecting an error) for our built-in function:
+Create two new test cases (one positive, expecting a string output; and one negative, expecting an error) for the built-in function:
```yaml
cases:
@@ -142,7 +142,7 @@ See [test/cases/testdata/helloworld](https://github.com/open-policy-agent/opa/tr
for a more detailed example of how to implement tests for your built-in functions.
:::info
-Note: We can manually test our new built-in function by [building](./contrib-development#getting-started)
+Note: The new built-in function can be manually tested by [building](./contrib-development#getting-started)
and running the `eval` command. E.g.: `$./opa__ eval 'repeat("Foo", 3)'`
:::
@@ -150,7 +150,7 @@ and running the `eval` command. E.g.: `$./opa__ eval 'repeat("Foo", 3)
All built-in functions will automatically be documented in `docs/content/policy-reference.md` under an appropriate subsection.
-For this example, we'll get an entry for our new function under the `Strings` section.
+For this example, the new function appears as an entry under the `Strings` section.
### Add a capability
@@ -159,10 +159,10 @@ Read more about extending the default capabilities list for built-ins [in the Op
:::
One of the security features of OPA is [capabilities](./operations#capabilities) checks on policies, allowing users to restrict which built-in functions will be available to policies at runtime.
-To ensure that our new `repeat` function will be available to callers, we'll need to add it to the `capabilities.json` file at the root of the repo.
-We can have this entry auto-generated for us by running `make generate`.
+To ensure the new `repeat` function is available to callers, add it to the `capabilities.json` file at the root of the repo.
+This entry can be auto-generated by running `make generate`.
-After running `make generate` we should see a new JSON object entry in the list under the `"builtins"` key:
+After running `make generate`, a new JSON object entry appears in the list under the `"builtins"` key:
```json
...
diff --git a/docs/docs/contrib-code.md b/docs/docs/contrib-code.md
index 6c69d5954c..50ea8e024c 100644
--- a/docs/docs/contrib-code.md
+++ b/docs/docs/contrib-code.md
@@ -2,7 +2,7 @@
title: Contributing Code
---
-We are thrilled that you're interested in contributing to OPA! This document
+Thanks for your interest in contributing to OPA! This document
outlines some of the important guidelines when getting started as a new
contributor.
@@ -28,7 +28,7 @@ When contributing please consider the following pointers:
implement however they come with their own cost for both OPA developers and
OPA users (e.g., vendoring conflicts, security, debugging, etc.)
- **AI Tooling**: You can use generative AI tooling to assist your work on OPA,
- but please review our project's [AI Guidelines](#ai-guidelines) below before doing so to
+ but please review the project's [AI Guidelines](#ai-guidelines) below before doing so to
help us help you.
:::tip
@@ -121,7 +121,7 @@ off by a human author.
The OPA maintainers reserve the right to request additional information about
patches and reject PRs where code origin cannot be verified.
-See more in our [AI Guidelines](#ai-guidelines).
+See more in the [AI Guidelines](#ai-guidelines).
:::
## Code Review
@@ -151,7 +151,7 @@ their own commit and added to the PR.
If your Pull Request is small though, it is acceptable to squash changes during
the review process. Use your judgement about what constitutes a small Pull
-Request. If you aren't sure, send a message to the OPA slack or post a comment
+Request. If you aren't sure, send a message to the OPA Slack or post a comment
on the Pull Request.
## Vulnerability scanning
@@ -180,9 +180,8 @@ in the `.trivyignore` file.
## AI Guidelines
-We are really excited for you to contribute to OPA! In order for us (the OPA
-maintainers) to help you effectively, we have some guidelines that we request
-you follow:
+Contributing to OPA is encouraged! In order for the OPA
+maintainers to help effectively, please follow these guidelines:
1. Follow the
[Linux Foundation Guidelines](https://www.linuxfoundation.org/legal/generative-ai)
@@ -207,15 +206,15 @@ you follow:
members who took the time to review your code and provide you with personal
feedback is considered disrespectful and will have your PR rejected.
-3. Don't be afraid to get it wrong! We are friendly, and will answer questions
- you might have about contributing to our project. You can always:
+3. Don't be afraid to get it wrong! The team is friendly and will answer questions
+ you might have about contributing to the project. You can always:
- Ask for clarification of a review comment if you don't understand it.
- Ask for input on a technical implementation, ideally before investing your
time into it.
- Correct maintainers when you think they've misunderstood something.
- Together we can learn and build a better OPA!
+ Together the community can learn and build a better OPA!
## Contribution process
diff --git a/docs/docs/contrib-development.md b/docs/docs/contrib-development.md
index f63ef4d8c8..ac580bb0eb 100644
--- a/docs/docs/contrib-development.md
+++ b/docs/docs/contrib-development.md
@@ -3,7 +3,7 @@ title: Development
---
This page details the process for getting up and running locally for OPA
-development. If you're a first time contributor, we recommend you read through
+development. First-time contributors are encouraged to read through
the [Contributing to OPA](./contrib-code) page first.
OPA is written in the [Go](https://go.dev/) programming language.
@@ -126,8 +126,8 @@ Pull Request, please mention it in the discussion.
## Benchmarks
Several packages in this repository implement benchmark tests. To execute the
-benchmarks you can run `make perf` in the top-level directory. We use the Go
-benchmarking framework for all benchmarks.
+benchmarks, run `make perf` in the top-level directory. The Go
+benchmarking framework is used for all benchmarks.
## Dependencies
@@ -138,7 +138,7 @@ All `go` commands from the [Makefile](https://github.com/open-policy-agent/opa/b
module mode by setting `GO111MODULE=on`.
To update a dependency ensure that `GO111MODULE` is either on, or the repository
-qualifies for `auto` to enable module mode. Then simply use `go get ..` to get
+qualifies for `auto` to enable module mode. Then use `go get ..` to get
the version desired. This should update the [go.mod](https://github.com/open-policy-agent/opa/blob/main/go.mod) and (potentially)
[go.sum](https://github.com/open-policy-agent/opa/blob/main/go.sum) files.
@@ -176,9 +176,9 @@ performant, that's great! Some things should however be considered before you su
OPA uses Github Actions defined in the [.github/workflows](https://github.com/open-policy-agent/opa/tree/main/.github/workflows)
directory.
-### Github Action Secrets
+### GitHub Action Secrets
-The following secrets are used by the Github Action workflows:
+The following secrets are used by the GitHub Action workflows:
| Name | Description |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -186,7 +186,7 @@ The following secrets are used by the Github Action workflows:
| AWS_ACCESS_KEY_ID | AWS credentials required to upload to the configured `S3_RELEASE_BUCKET`. Optional -- If not provided the release upload steps are skipped. |
| AWS_SECRET_ACCESS_KEY | AWS credentials required to upload to the configured `S3_RELEASE_BUCKET`. Optional -- If not provided the release upload steps are skipped. |
| DOCKER_IMAGE | Full docker image name (with org) to tag and publish OPA images. Optional -- If not provided the image defaults to `openpolicyagent/opa`. |
-| DOCKER_WASM_BUILDER_IMAGE | Full docker image name (with org) to tag and publish WASM builder images. Optional -- If not provided the image defaults to `openpolicyagent/opa-wasm-builder`. |
+| DOCKER_WASM_BUILDER_IMAGE | Full docker image name (with org) to tag and publish Wasm builder images. Optional -- If not provided the image defaults to `openpolicyagent/opa-wasm-builder`. |
| DOCKER_USER | Docker username for uploading release images. Will be used with `docker login`. Optional -- If not provided the image push steps are skipped. |
| DOCKER_PASSWORD | Docker password or API token for the configured `DOCKER_USER`. Will be used with `docker login`. Optional -- If not provided the image push steps are skipped. |
| SLACK_NOTIFICATION_WEBHOOK | Slack webhook for sending notifications. Optional -- If not provided the notification steps are skipped. |
@@ -194,7 +194,7 @@ The following secrets are used by the Github Action workflows:
### Periodic Workflows
-Some of the Github Action workflows are triggered on a schedule, and not included in the
+Some of the GitHub Action workflows are triggered on a schedule, and not included in the
post-merge, pull-request, etc actions. These are reserved for time consuming or potentially
non-deterministic jobs (race detection tests, fuzzing, etc).
diff --git a/docs/docs/contrib-docs.md b/docs/docs/contrib-docs.md
index f59632d1b7..6f85cf1c66 100644
--- a/docs/docs/contrib-docs.md
+++ b/docs/docs/contrib-docs.md
@@ -2,10 +2,10 @@
title: Contributing Documentation
---
-Contributing to our documentation is one of the best ways to get started
+Contributing to the documentation is one of the best ways to get started
contributing to the OPA project. The OPA documentation is often the first place
people go for help and so any improvements can be very impactful.
-**Thank you in advance for contributing to our documentation!**
+**Thank you in advance for contributing to the documentation!**
## Local Development
diff --git a/docs/docs/contributing.md b/docs/docs/contributing.md
index b3ad9718d6..381141450b 100644
--- a/docs/docs/contributing.md
+++ b/docs/docs/contributing.md
@@ -25,13 +25,10 @@ Overflow.
## I'd like to contribute code
-If you have found a bug and would like to work on a fix, **we always encourage you
-file a [GitHub Issue](https://github.com/open-policy-agent/opa/issues)** to talk
-about the problem and the solution you have in mind. This allows you to get
-feedback from maintainers before committing time to something that might already
+If you have found a bug and would like to work on a fix, **filing a [GitHub Issue](https://github.com/open-policy-agent/opa/issues)** is always encouraged. It is a good way to discuss the problem and your proposed solution, and gather feedback from maintainers before committing time to something that might already
have a solution or might not be the right approach.
-If you have an idea for a new feature, we also **request that you file an
+If you have an idea for a new feature, **file an
issue** to discuss it first. This again allows you to get feedback from
the maintainer team and the community before you start working on it.
@@ -45,19 +42,19 @@ else, head over to
Slack. This is also a great place to ask for ideas if you want to contribute, but
aren't sure what to work on!
-If you are ready to start contributing code, please see our
+If you are ready to start contributing code, please see the
[Contributing Code](./contrib-code/) guide for pointers on how to get
-started. Please note we have some restrictions around the use of AI tooling
+started. Please note there are some restrictions around the use of AI tooling
which are documented here.
## I'd like to help improve the documentation
-Great! Please see our [Contributing Documentation](./contrib-docs) guide for
+See the [Contributing Documentation](./contrib-docs) guide for
more details.
## I have an OPA project or talk I'd like to share
-Awesome! For OPA-based projects, we have our [Ecosystem page](/ecosystem/).
+Awesome! For OPA-based projects, the [Ecosystem page](/ecosystem/) is available.
This is a great place to showcase your project and how it uses OPA.
You can create a markdown file in:
@@ -73,8 +70,8 @@ If you have a talk or blog you'd like to share please feel free to post in:
## I'm interested in something else
-Sounds interesting, we'd love to hear all about it,
-[sign up for our Slack](https://slack.openpolicyagent.org/) and
+Sounds interesting, reach out to share it,
+[sign up for the OPA Slack](https://slack.openpolicyagent.org/) and
drop a message in the
[#contributors](https://openpolicyagent.slack.com/archives/C02L1TLPN59)
channel.
diff --git a/docs/docs/debugging/index.md b/docs/docs/debugging/index.md
index 730a1077a8..7ddeff48aa 100644
--- a/docs/docs/debugging/index.md
+++ b/docs/docs/debugging/index.md
@@ -27,8 +27,7 @@ Read more about the supported editors of this debugging method in the
## OPA REPL and Playground
-Often it can take a few tries to get a Rego policy correct, the OPA REPL and Playground are great tools for
-reducing the feedback loop when debugging policies.
+Often it can take a few tries to get a Rego policy correct, the OPA REPL and Playground help reduce the feedback loop when debugging policies.
The REPL can be run locally and loaded with the policy and data files you are working on:
@@ -38,7 +37,7 @@ opa run [policy-files] [data-files]
The [Rego Playground](http://play.openpolicyagent.org) is a web-based Rego development environment that can be
used to test policies with different inputs and data. If you are interested in asking for help in the
-[OPA Slack](https://slack.openpolicyagent.org), the playground is a great way to share your policy and data with
+[OPA Slack](https://slack.openpolicyagent.org), the playground can be used to share your policy and data with
others.
## Using the `print` Built-in Function
@@ -69,7 +68,7 @@ debugging OPA in these environments.
### OPA Logs
-OPA logs are a great place to start when debugging issues. The logs can be used to understand what OPA is doing
+OPA logs are a useful starting point when debugging issues. The logs can be used to understand what OPA is doing
at any given time. Common issues such as failing to load in policy or data bundles will be shown here.
You can also enable debug logging to get more detailed information about what OPA is doing with `--log-level debug`.
diff --git a/docs/docs/deploy/docker/index.md b/docs/docs/deploy/docker/index.md
index 8dd8ef03db..0ce0fef75b 100644
--- a/docs/docs/deploy/docker/index.md
+++ b/docs/docs/deploy/docker/index.md
@@ -4,11 +4,11 @@ sidebar_position: 2
title: Deploying OPA on Docker
---
-Docker makes OPA easy to deploy in different types of environments.
+Docker can be used to deploy OPA in different types of environments.
This section explains how to use the official OPA Docker images. If this is your
-first time deploying OPA and you plan to use one of the Docker images, we
-recommend you review this section to familiarize yourself with the basics.
+first time deploying OPA and you plan to use one of the Docker images, it is
+recommended that you review this section to familiarize yourself with the basics.
OPA releases are available as images on Docker Hub
([`openpolicyagent/opa`](https://hub.docker.com/r/openpolicyagent/opa/)).
@@ -18,7 +18,7 @@ OPA releases are available as images on Docker Hub
If you start OPA outside of Docker without any arguments, it prints a list of
available commands. By default, the official OPA Docker image executes the `run`
command which starts an instance of OPA as an interactive shell. This is nice
-for development, however, for deployments, we want to run OPA as a server.
+for development, however, for deployments, run OPA as a server.
The `run` command accepts a `--server` (or `-s`) flag that starts OPA as a
server. See `--help` for more information on other arguments. The most important
@@ -31,7 +31,7 @@ command line arguments for OPA's server mode are:
By default, OPA listens for normal HTTP connections on `localhost:8181`. To make
OPA listen for HTTPS connections, see [Security](../../security).
-We can run OPA as a server using Docker:
+Run OPA as a server using Docker:
```bash
docker run -p 8181:8181 openpolicyagent/opa \
@@ -39,7 +39,7 @@ docker run -p 8181:8181 openpolicyagent/opa \
```
:::info
-We have to use `--addr` here to bind to all interfaces to ensure OPA is
+Use `--addr` to bind to all interfaces to ensure OPA is
accessible from outside the container. This is not necessary when running OPA
in other environments.
@@ -74,7 +74,9 @@ If the log level is set to `debug` the request and response message bodies will
The default log format is json and intended for production use. For more human readable
formats use "json-pretty" or "text".
-> **Note:** The `text` log format is not performance optimized or intended for production use.
+:::note
+The `text` log format is not performance optimized or intended for production use.
+:::
### Volume Mounts
@@ -115,8 +117,8 @@ The Docker Hub repository contains tags for every release of OPA. For more
information on each release see the [GitHub Releases](https://github.com/open-policy-agent/opa/releases) page.
The "latest" tag refers to the most recent release. The latest tag is convenient
-if you want to quickly try out OPA however for production deployments, we
-recommend using an explicit version tag.
+if you want to quickly try out OPA however for production deployments, it is
+recommended to use an explicit version tag.
Development builds are also available on Docker Hub. For each version the
`{version}-dev` tag refers the most recent development build for that version.
@@ -147,7 +149,7 @@ First, create a ConfigMap containing a test policy.
In this case, the policy file does not contain sensitive information so it's
fine to store as a ConfigMap. If the file contained sensitive information, then
-we recommend you store it as a Secret.
+store it as a Secret.
```rego title="example.rego"
package example
diff --git a/docs/docs/docker-authorization.md b/docs/docs/docker-authorization.md
index f0660c16d6..85bcf86f8d 100644
--- a/docs/docs/docker-authorization.md
+++ b/docs/docs/docker-authorization.md
@@ -19,7 +19,7 @@ in OPA.
> application while still keeping up with the size, complexity, and dynamic
> nature of modern applications.
-For the purpose of this tutorial, we want to use OPA to enforce a policy that
+For the purpose of this tutorial, OPA is used to enforce a policy that
prevents users from running insecure containers.
This tutorial illustrates two key concepts:
@@ -64,15 +64,14 @@ allow := true
```
This policy defines a single rule named `allow` that always produces the
-decision `true`. Once all the components are running, we will come back to
-the policy.
+decision `true`. The tutorial returns to this policy once all the components are running.
### 2. Create policy bundle and OPA configuration
-For the purpose of this example, we are going to use [Nginx](https://www.openpolicyagent.org/docs/management-bundles#nginx)
+For the purpose of this example, [Nginx](https://www.openpolicyagent.org/docs/management-bundles#nginx) is used
to serve bundles from the same machine Docker is running on.
-With nginx running, simply build the policy bundle placed into the nginx web root directory.
+With Nginx running, build the policy bundle placed into the Nginx web root directory.
```shell
opa build --bundle --output /var/www/html/bundle.tar.gz .
@@ -95,9 +94,9 @@ decision_logs:
console: true
```
-Save the above file as `opa-config.yaml`. We'll need to place this somewhere where the plugin can find it.
-The `/etc/docker` directory will be mounted as `/opa` in the container running the plugin, so let's create a
-sub-directory for our configuration file there.
+Save the above file as `opa-config.yaml`. Place this file somewhere the plugin can find it.
+The `/etc/docker` directory will be mounted as `/opa` in the container running the plugin, so create a
+sub-directory for the configuration file there.
```shell
sudo mkdir -p /etc/docker/config
@@ -139,7 +138,7 @@ expect to see log messages from OPA and the plugin.
### 5. Test that the policy definition is working
-Letβs modify our policy to **deny** all requests:
+Modify the policy to **deny** all requests:
**authz.rego**:
@@ -159,7 +158,7 @@ In OPA, rules defines the content of documents. Documents be boolean values
(true/false) or they can represent more complex structures using arrays,
objects, strings, etc.
-In the example above we modified the policy to always return `false` so that
+In the example above, the policy was modified to always return `false` so that
requests will be rejected.
```shell
@@ -178,7 +177,7 @@ With this policy in place, users will not be able to run any Docker commands. Go
ahead and try other commands such as `docker run` or `docker pull`. They will
all be rejected.
-Now let's change the policy so that it's a bit more useful.
+Now change the policy to be more useful.
### 6. Update the policy to reject requests with the unconfined [seccomp](https://en.wikipedia.org/wiki/Seccomp) profile
@@ -353,8 +352,7 @@ prevented by the policy):
docker run --security-opt seccomp:unconfined hello-world
```
-Congratulations! You have successfully prevented containers from running without
-seccomp!
+Containers without a seccomp profile are now blocked.
The rest of the tutorial shows how you can grant fine-grained access to specific
clients.
@@ -384,7 +382,7 @@ EOF
> Docker does not currently provide a way to authenticate clients. But in Docker
> 1.12, clients can be authenticated using TLS and there are plans to include
-> other means of authentication. For the purpose of this tutorial, we assume that
+> other means of authentication. For the purpose of this tutorial, assume that
> an authentication system is place.
### 9. Update the policy to include basic user access controls
@@ -441,5 +439,3 @@ Because the configured user is `"alice"`, the request will succeed:
```shell
docker run hello-world
```
-
-That's it!
diff --git a/docs/docs/editor-and-ide-support.md b/docs/docs/editor-and-ide-support.md
index eedd2b7c57..4107126e0a 100644
--- a/docs/docs/editor-and-ide-support.md
+++ b/docs/docs/editor-and-ide-support.md
@@ -22,7 +22,7 @@ evaluation, policy coverage, and more.
:::info
**Your editor missing? Built a Rego integration for your editor?** Drop us a
message on [Slack](https://slack.openpolicyagent.org)
-We also have our [Ecosystem page](/ecosystem/). This is a great place to
+The [Ecosystem page](/ecosystem/) is also a great place to
showcase your project. See
[these instructions](./contrib-docs#opa-ecosystem-additions)
to get it listed.
diff --git a/docs/docs/envoy/debugging.md b/docs/docs/envoy/debugging.md
index 5790290bf1..ec2689c044 100644
--- a/docs/docs/envoy/debugging.md
+++ b/docs/docs/envoy/debugging.md
@@ -5,7 +5,7 @@ sidebar_position: 6
This page provides some pointers that could assist in addressing issues encountered while using the
OPA-Envoy plugin. If none of these tips work, feel free to join
-[our slack](https://slack.openpolicyagent.org) and ask for help.
+[our Slack](https://slack.openpolicyagent.org) and ask for help.
## Debugging Performance Issues
diff --git a/docs/docs/envoy/index.md b/docs/docs/envoy/index.md
index 630485dbd0..732580a4ec 100644
--- a/docs/docs/envoy/index.md
+++ b/docs/docs/envoy/index.md
@@ -43,8 +43,10 @@ sequenceDiagram
Envoy->>+Client: Response (HTTP)
```
-> π‘ The OPA-Envoy plugin is frequently deployed in Kubernetes environments as a sidecar container however it can also
-> be used in other environments as a standalone process running next to Envoy.
+:::tip
+The OPA-Envoy plugin is frequently deployed in Kubernetes environments as a sidecar container however it can also
+be used in other environments as a standalone process running next to Envoy.
+:::
## Configuration
diff --git a/docs/docs/envoy/performance.md b/docs/docs/envoy/performance.md
index f128755ae6..e1134a1bbc 100644
--- a/docs/docs/envoy/performance.md
+++ b/docs/docs/envoy/performance.md
@@ -110,7 +110,7 @@ layered_runtime:
### OPA-Envoy Plugin
-Now let's deploy OPA as an External Authorization server. Below is a sample configuration for the OPA-Envoy container:
+Now deploy OPA as an External Authorization server. Below is a sample configuration for the OPA-Envoy container:
```yaml
@@ -145,14 +145,18 @@ containers:
```
-> π‘ Consider specifying CPU and memory resource requests and limits for the OPA and other containers to prevent
-> deployments from resource starvation.
-> OPA automatically sets `GOMAXPROCS` via [`automaxprocs`](https://github.com/uber-go/automaxprocs) and `GOMEMLIMIT`
-> via [`automemlimit`](https://github.com/KimMachineGun/automemlimit) based on cgroup limits. Both can be overridden
-> by setting the environment variables explicitly.
->
-> π‘ The OPA-Envoy plugin can be configured to listen on a UNIX Domain Socket. A complete example of such a setup
-> can be found [in the opa-envoy-plugin examples](https://github.com/open-policy-agent/opa-envoy-plugin/tree/main/examples/envoy-uds).
+::: tip
+Consider specifying CPU and memory resource requests and limits for the OPA and other containers to prevent
+deployments from resource starvation.
+OPA automatically sets `GOMAXPROCS` via [`automaxprocs`](https://github.com/uber-go/automaxprocs) and `GOMEMLIMIT`
+via [`automemlimit`](https://github.com/KimMachineGun/automemlimit) based on cgroup limits. Both can be overridden
+by setting the environment variables explicitly.
+:::
+
+::: tip
+The OPA-Envoy plugin can be configured to listen on a UNIX Domain Socket. A complete example of such a setup
+can be found [in the opa-envoy-plugin examples](https://github.com/open-policy-agent/opa-envoy-plugin/tree/main/examples/envoy-uds).
+:::
### Load Generator and Measurement Tool
diff --git a/docs/docs/envoy/primer.md b/docs/docs/envoy/primer.md
index cf84cba913..0842519a08 100644
--- a/docs/docs/envoy/primer.md
+++ b/docs/docs/envoy/primer.md
@@ -8,7 +8,7 @@ This page covers how to write policies for the content of the requests that are
## Writing Policies
-Let's start with an example policy that restricts access to an endpoint based on a user's role and permissions.
+Start with an example policy that restricts access to an endpoint based on a user's role and permissions.
```rego
package envoy.authz
@@ -65,7 +65,7 @@ The above policy uses the `io.jwt.decode_verify` builtin function to parse and v
information about the user making the request. It uses other builtins like `glob.match`, `lower`, `base64url.decode` etc.
OPA has 150+ builtins detailed in the [policy reference](../policy-reference).
-The dot notation seen in multiple places in the policy for ex. `input.parsed_body.firstname` simply descends through
+The dot notation seen in multiple places in the policy for ex. `input.parsed_body.firstname` descends through
the hierarchy to access the requested value. The dot (.) operator never throws any errors; if the path does not exist
the value of the expression is `undefined`.
@@ -213,7 +213,7 @@ When Envoy receives a policy decision, it expects a JSON object with the followi
- `query_parameters_to_remove` (optional): is an array containing the names of string query parameters to be removed.
- `query_parameters_to_set` (optional): an object mapping parameter names to values (string) or arrays of values (for multiple values with the same key)
-To construct that output object using the policies demonstrated in the last section, you can use the following Rego snippet. Notice that we are using partial object rules so that any variables with undefined values simply have no key in the `result` object.
+To construct that output object using the policies demonstrated in the last section, you can use the following Rego snippet. Note that partial object rules are used so that any variables with undefined values have no key in the `result` object.
```rego
result["allowed"] := allow
diff --git a/docs/docs/envoy/tutorial-gloo-edge.md b/docs/docs/envoy/tutorial-gloo-edge.md
index 33e73f9772..212d6206db 100644
--- a/docs/docs/envoy/tutorial-gloo-edge.md
+++ b/docs/docs/envoy/tutorial-gloo-edge.md
@@ -11,7 +11,7 @@ The purpose of this tutorial is to show how OPA could be used with Gloo Edge to
## Prerequisites
-This tutorial requires Kubernetes 1.14 or later. To run the tutorial locally, we recommend using [minikube](https://minikube.sigs.k8s.io/docs/start/) in version v1.0+ with Kubernetes 1.14+.
+This tutorial requires Kubernetes 1.14 or later. To run the tutorial locally, [minikube](https://minikube.sigs.k8s.io/docs/start/) (version v1.0+) with Kubernetes 1.14+ is recommended.
The tutorial also requires [Helm](https://helm.sh/docs/intro/install/) to install Gloo Edge on a Kubernetes cluster.
@@ -85,7 +85,7 @@ kubectl port-forward deployment/gateway-proxy 8080:8080
```
The `VirtualService` created in the previous step forwards requests to [httpbin.org](http://httpbin.org)
-Let's test that Gloo works properly by running the below command in the first terminal.
+Test that Gloo works properly by running the below command in the first terminal.
```bash
curl -XGET -Is localhost:8080/get | head -n 1
@@ -163,13 +163,13 @@ The sample input can be seen below using Alice's token, Alice should be able to
-Next we build an OPA bundle.
+Next, build an OPA bundle.
```bash
opa build policy.rego
```
-And now we serve the OPA bundle created above using Nginx.
+Serve the OPA bundle created above using Nginx.
```bash
docker run --rm --name bundle-server -d -p 8888:80 -v ${PWD}:/usr/share/nginx/html:ro nginx:latest
@@ -251,7 +251,7 @@ spec:
### 7. Configure Gloo Edge to use OPA
-To use OPA as a custom auth server, we need to add the `extauth` attribute as described below:
+To use OPA as a custom auth server, add the `extauth` attribute as described below:
**gloo.yaml**
@@ -282,7 +282,7 @@ spec:
customAuth: {}
```
-Then apply the patch to our `VirtualService` as shown below:
+Then apply the patch to the `VirtualService` as shown below:
```bash
kubectl patch vs httpbin --type=merge --patch "$(cat vs-patch.yaml)"
@@ -290,28 +290,28 @@ kubectl patch vs httpbin --type=merge --patch "$(cat vs-patch.yaml)"
### 8. Exercise the OPA Policy
-Before we exercise the policy, for convenience sake, we will want to store Alice and Bob's tokens in environment variables as such:
+Before exercising the policy, store Alice and Bob's tokens in environment variables:
```bash
export ALICE_TOKEN="eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJleHAiOiAyMjQxMDgxNTM5LCAibmJmIjogMTUxNDg1MTEzOSwgInJvbGUiOiAiZ3Vlc3QiLCAic3ViIjogIllXeHBZMlU9In0.Uk5hgUqMuUfDLvBLnlXMD0-X53aM_Hlziqg3vhOsCc8"
export BOB_TOKEN="eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJleHAiOiAyMjQxMDgxNTM5LCAibmJmIjogMTUxNDg1MTEzOSwgInJvbGUiOiAiYWRtaW4iLCAic3ViIjogIlltOWkifQ.5qsm7rRTvqFHAgiB6evX0a_hWnGbWquZC0HImVQPQo8"
```
-Now let's verify that OPA only allows **Alice** to perform `GET` requests.
+Verify that OPA only allows **Alice** to perform `GET` requests.
```bash
curl -XGET -Is -H "Authorization: Bearer $ALICE_TOKEN" localhost:8080/get
HTTP/1.1 200 OK
```
-And with a `POST` request, we get:
+With a `POST` request, the result is:
```bash
curl http -XPOST -Is -H "Authorization: Bearer $ALICE_TOKEN" localhost:8080/post
HTTP/1.1 403 Forbidden
```
-And for **Bob**, we should be able to `GET` and `POST`:
+For **Bob**, both `GET` and `POST` should succeed:
```bash
curl -XGET -Is -H "Authorization: Bearer $BOB_TOKEN" localhost:8080/get
@@ -331,8 +331,6 @@ Check OPA's decision logs to view the inputs received by OPA from Gloo Edge and
kubectl logs deployment/opa -n gloo-system
```
-## Wrap Up
-
-Congratulations for finishing the tutorial!
+## Summary
This tutorial showed how you can use OPA with [Gloo Edge](https://docs.solo.io/gloo-edge/latest/) to apply security policies for upstream services and how to create and test a policy that would allow `GET` or `POST` requests based on your user role.
diff --git a/docs/docs/envoy/tutorial-istio.md b/docs/docs/envoy/tutorial-istio.md
index 020885cfeb..f45925a5e2 100644
--- a/docs/docs/envoy/tutorial-istio.md
+++ b/docs/docs/envoy/tutorial-istio.md
@@ -206,9 +206,7 @@ curl --user bob:password -i http://$SERVICE_HOST/productpage
curl --user bob:password -i http://$SERVICE_HOST/api/v1/products
```
-## Wrap Up
-
-Congratulations for finishing the tutorial !
+## Summary
This tutorial showed how Istio's [AuthorizationPolicy API](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/)
can be configured to use OPA as an External authorization service.
diff --git a/docs/docs/envoy/tutorial-standalone-envoy.md b/docs/docs/envoy/tutorial-standalone-envoy.md
index 43642c0477..8b76d2c246 100644
--- a/docs/docs/envoy/tutorial-standalone-envoy.md
+++ b/docs/docs/envoy/tutorial-standalone-envoy.md
@@ -11,8 +11,8 @@ policies over the HTTP request body.
## Overview
-In this tutorial we'll see how to use OPA as an External
-Authorization service for the Envoy proxy. We'll do this by:
+In this tutorial, OPA is used as an External
+Authorization service for the Envoy proxy. The tutorial covers:
- Running a local Kubernetes cluster
- Creating a simple authorization policy in Rego and serving it via the Bundle API
@@ -24,7 +24,7 @@ are co-located in the same pod.
## Running a local Kubernetes cluster
-To start a local Kubernetes cluster to run our demo, we'll be using
+To start a local Kubernetes cluster to run the demo, use
[kind](https://kind.sigs.k8s.io/).
:::info
@@ -64,7 +64,7 @@ NAME STATUS ROLES AGE VERSION
opa-envoy-control-plane Ready control-plane 2m35s v1.33.1
```
-## Creating & Serving our Policy Bundle
+## Creating & Serving the Policy Bundle
This tutorial assumes you have some Rego knowledge, in summary the policy below does the following:
@@ -124,8 +124,8 @@ Create a file called `policy.rego` with the above content and store it in a Conf
kubectl create configmap authz-policy --from-file policy.rego
```
-Now that the policy is stored in a ConfigMap, we can spin up an HTTP server to make it
-available as a Bundle to OPA when it's making decisions for our application:
+Now that the policy is stored in a ConfigMap, spin up an HTTP server to make it
+available as a Bundle to OPA when it's making decisions for the application:
```yaml
# bundle-server.yaml
@@ -195,7 +195,7 @@ Create a file called `bundle-server.yaml` with the above content and apply it to
kubectl apply -f bundle-server.yaml
```
-Once the deployment is running, we can check that the bundle is available by running:
+Once the deployment is running, check that the bundle is available by running:
```shell
kubectl port-forward service/bundle-server 8080:80
@@ -214,12 +214,12 @@ from inside the cluster from now on.
## Deploying an application with Envoy and OPA sidecars
-In this tutorial, we are manually configuring the Envoy proxy sidecar to intermediate
-HTTP traffic from clients and our application. Envoy will consult OPA to
+In this tutorial, the Envoy proxy sidecar is manually configured to intermediate
+HTTP traffic from clients and the application. Envoy will consult OPA to
make authorization decisions for each request by sending `CheckRequest` messages over
a gRPC connection.
-We will use the following Envoy configuration to achieve this. In summary, this
+The following Envoy configuration achieves this. In summary, this
configures Envoy to:
- Listen on port `8000` for HTTP traffic
@@ -308,13 +308,13 @@ Create a `ConfigMap` containing the above configuration by running:
kubectl create configmap proxy-config --from-file envoy.yaml
```
-Our application will be configured using a `Deployment` and `Service`.
+The application is configured using a `Deployment` and `Service`.
There are a few things to note:
- the pods have an `initContainer` that configures the `iptables` rules to
redirect traffic to the Envoy proxy.
- the `demo-test-server` container is a simple user store using in-memory state.
-- the `envoy` container is configured to use the `proxy-config` `ConfigMap` we
+- the `envoy` container is configured to use the `proxy-config` `ConfigMap`
created earlier.
- The OPA container is configured to download policy bundles from
the in-cluster bundle server (`bundle-server.default.svc.cluster.local`).
@@ -432,7 +432,7 @@ example-app-74b4bc88-5d4wh 3/3 Running 0 1m
## See the Policy in Action
-Run a shell inside the cluster to use for testing. We will use this in-cluster
+Run a shell inside the cluster to use for testing. Use this in-cluster
shell for the rest of the tutorial.
```shell
@@ -440,7 +440,7 @@ kubectl run curl --restart=Never -it --rm --image curlimages/curl:8.1.2 -- sh
```
Set two tokens for two users, Alice and Bob with different permissions.
-As defined by our policy:
+As defined by the policy:
```shell
export ALICE_TOKEN="eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJleHAiOiAyMjQxMDgxNTM5LCAibmJmIjogMTUxNDg1MTEzOSwgInJvbGUiOiAiZ3Vlc3QiLCAic3ViIjogIllXeHBZMlU9In0.Uk5hgUqMuUfDLvBLnlXMD0-X53aM_Hlziqg3vhOsCc8"
@@ -515,7 +515,7 @@ server: envoy
### Creating People: Conflict
-Our policy also blocks users from creating users with the same name, test that
+The policy also blocks users from creating users with the same name. Test that
functionality with this request:
```shell
@@ -543,9 +543,7 @@ Deleting cluster "opa-envoy" ...
Deleted nodes: ["opa-envoy-control-plane"]
```
-## Wrap Up
-
-Congratulations on finishing the tutorial !
+## Summary
This tutorial showed how to use OPA as an External authorization service to
enforce custom policies by leveraging Envoyβs External authorization filter.
diff --git a/docs/docs/errors/eval-conflict-error/complete-rules-must-not-produce-multiple-outputs.md b/docs/docs/errors/eval-conflict-error/complete-rules-must-not-produce-multiple-outputs.md
index e5ecab6d9b..37aaefc12d 100644
--- a/docs/docs/errors/eval-conflict-error/complete-rules-must-not-produce-multiple-outputs.md
+++ b/docs/docs/errors/eval-conflict-error/complete-rules-must-not-produce-multiple-outputs.md
@@ -16,7 +16,7 @@ multiple outputs, or "return values".
## Examples
-The most trivial example of this would be to simply β and unconditionally β assign two different values to a rule:
+The clearest example of this is to unconditionally assign two different values to a rule:
```rego
package policy
@@ -62,7 +62,7 @@ should be considered a best practice to account for this type of scenario in you
## How To Fix It
-To fix this β simply ensure that the conditions for a rule to be assigned a conflicting value are mutually exclusive.
+To fix this, ensure that the conditions for a rule to be assigned a conflicting value are mutually exclusive.
A common way to do this is to use negation (i.e. `not`) in one of the rule bodies:
```rego
diff --git a/docs/docs/errors/eval-conflict-error/object-keys-must-be-unique.md b/docs/docs/errors/eval-conflict-error/object-keys-must-be-unique.md
index 9078ff321f..a908e25449 100644
--- a/docs/docs/errors/eval-conflict-error/object-keys-must-be-unique.md
+++ b/docs/docs/errors/eval-conflict-error/object-keys-must-be-unique.md
@@ -28,7 +28,7 @@ obj := {k: v |
}
```
-In this example, we are attempting to create an object like `{"foo": 1, "foo": 2}` which contains duplicate keys.
+In this example, the policy attempts to create an object like `{"foo": 1, "foo": 2}` which contains duplicate keys.
This issue is also commonly seen with partial rules constructing objects. For example:
```rego
@@ -125,7 +125,7 @@ Instead of the output being:
}
```
-We're trying to create an impossible output like this:
+The policy is trying to create an impossible output like this:
```json
{
@@ -146,8 +146,7 @@ construct objects, ensure that there are not duplicated values. If you're using
`some x in y` in rules to create values for an object, this is a common source of this error as any more than one
value in `y` could result in duplicate keys.
-Sometimes, you might need to restructure your policy to avoid this error. For example, in the policy above, we could
-change it to work like this:
+Sometimes, the policy needs to be restructured to avoid this error. For example, the policy above can be rewritten to work like this:
```rego
package policy
diff --git a/docs/docs/errors/index.md b/docs/docs/errors/index.md
index 6ffe8af7cc..3de0b79656 100644
--- a/docs/docs/errors/index.md
+++ b/docs/docs/errors/index.md
@@ -7,8 +7,7 @@ image: /img/opa-errors.png
# OPA Errors Guide
This guide is designed to help you understand the most common errors you'll encounter when working with OPA. Each
-document provides examples of the error, why it's an error, and how to fix it. A perfect companion for your debugging
-session!
+document provides examples of the error, why it's an error, and how to fix it.
The errors currently documented are:
@@ -52,7 +51,7 @@ any of these stages will stop the evaluation process and have the error(s) repor
The first stage is **parsing**. In this step, OPA takes the raw Rego policy and parses it into an abstract syntax tree
(AST), which is then handed to the compiler. Errors at this stage are normally syntax errors, meaning the Rego provided
-in a policy simply isn't valid. An example of this might be forgetting to terminate a string with a closing quote:
+in a policy isn't valid. An example of this might be forgetting to terminate a string with a closing quote:
```rego
package policy
@@ -79,11 +78,11 @@ policy.rego:9: rego_parse_error: illegal token
^
```
-At this point, further processing isn't possible, and the error must be fixed before we can proceed.
+At this point, further processing isn't possible, and the error must be fixed before proceeding.
#### Compilation
-While we may not think of Rego as a "compiled language", any policy passes through a compilation step before it can be
+While Rego may not seem like a "compiled language", any policy passes through a compilation step before it can be
evaluated. During compilation, OPA will run several stages of analysis on the policy (which is now an AST) to ensure
that it's valid. This includes things like checking that functions are called with the right number of arguments,
that types are used correctly, or that variables are defined before they're used. A typical example of a compilation
@@ -95,14 +94,14 @@ package policy
x := y
```
-Since `y` isn't defined in our policy, the compiler considers it unsafe:
+Since `y` isn't defined in the policy, the compiler considers it unsafe:
```txt
1 error occurred: policy.rego:3: rego_unsafe_var_error: var y is unsafe
```
**Tip:** when using `opa eval`, you can pass the `--strict` flag to enable additional compiler checks β like unused
-variables or function arguments. This is a great way to spot mistakes and errors as soon as possible, and is highly
+variables or function arguments. This helps catch mistakes and errors early, and is highly
recommended.
#### Evaluation
@@ -126,23 +125,22 @@ policy.rego:3: eval_conflict_error: complete rules must not produce multiple out
```
Important to know is that not all "errors" at this stage will be reported as errors! Some things that would be
-considered an error during compilation, like passing the wrong type of value in a function argument, would simply
-result in evaluation being undefined during evaluation time.
+considered an error during compilation, like passing the wrong type of value in a function argument, would instead leave the result undefined at evaluation time.
```rego
startswith("100", 1)
```
As the `startswith` function expects two strings β and this is known by the compiler β this would fail during
-compilation. But if we replace the `1` with a value from `input`:
+compilation. If the `1` is replaced with a value from `input`:
```rego
startswith("100", input.x)
```
-The compiler can't know the value of `input.x`. During evaluation, we _do_ know the value of `input.x`,
-but does it mean we want a malformed value to stop policy evaluation entirely? Probably not! By default, evaluation
-will simply consider that case to be _undefined_, and move on with evaluating the rest of the policy.
+The compiler can't know the value of `input.x`. At evaluation time, the value is known, but a
+malformed value does not stop policy evaluation entirely. By default, evaluation
+will consider that case to be _undefined_, and move on with evaluating the rest of the policy.
**Tip:** If you're using `opa eval` to evaluate policies, you can pass the `--strict-builtin-errors` flag to have
an error from a built-in function halt evaluation and have the error reported. Additionally, the
diff --git a/docs/docs/errors/rego-compile-error/assigned-var-name-unused.md b/docs/docs/errors/rego-compile-error/assigned-var-name-unused.md
index a72482aab7..a2beb8f162 100644
--- a/docs/docs/errors/rego-compile-error/assigned-var-name-unused.md
+++ b/docs/docs/errors/rego-compile-error/assigned-var-name-unused.md
@@ -52,15 +52,15 @@ deny contains message if {
}
```
-Here, we can see the intent, the `message` should be set to `user is not admin` if the user is not an admin. However,
+Here, the intent is that `message` should be set to `user is not admin` if the user is not an admin. However,
the variable `msg` is assigned instead.
## How To Fix It
-Based on the examples above, we can see that there are two main ways to fix this error:
+Based on the examples above, there are two main ways to fix this error:
-- Remove the assignments of unused variables. In the first example, we can simply remove the line `user := input.user`.
- The other option is of course to use the variable that was assigned. Often orphaned variables like this are the result
+- Remove the assignments of unused variables. In the first example, remove the line `user := input.user`.
+ The other option is to use the variable that was assigned. Often orphaned variables like this are the result
a refactoring and can be safely removed if they aren't making the rule more readable.
- Check for typos and mis-named variables. As well as normal typos, it's also easy to make mistakes and swap variables
for alternative names. For example, sometimes `msg` instead of `message` or `user` instead of `username`.
diff --git a/docs/docs/errors/rego-parse-error/unexpected-identifier-token.md b/docs/docs/errors/rego-parse-error/unexpected-identifier-token.md
index 5698e9e78c..942034d412 100644
--- a/docs/docs/errors/rego-parse-error/unexpected-identifier-token.md
+++ b/docs/docs/errors/rego-parse-error/unexpected-identifier-token.md
@@ -83,5 +83,5 @@ Typically, the way to resolve this to find and correct misplaced whitespace
using the location in the error message.
This can be tricky in larger files and often happens when moving code between
-files. We recommend migrating functions and rules incrementally to reduce the
+files. Migrating functions and rules incrementally is recommended to reduce the
risk of this happening.
diff --git a/docs/docs/errors/rego-parse-error/var-cannot-be-used-for-rule-name.md b/docs/docs/errors/rego-parse-error/var-cannot-be-used-for-rule-name.md
index 5a08ee67ed..ca1cd58c63 100644
--- a/docs/docs/errors/rego-parse-error/var-cannot-be-used-for-rule-name.md
+++ b/docs/docs/errors/rego-parse-error/var-cannot-be-used-for-rule-name.md
@@ -50,7 +50,7 @@ internal_user email if {
## How To Fix It
-If caused by a missing import like the `if` keyword, simply add the import at
+If caused by a missing import like the `if` keyword, add the import at
the top of your package. Other cases are likely caused by having forgotten to
add an assignment operator between the rule name and the value to assign. Once
you have identified the cause, fix the syntax error or adding the missing import
diff --git a/docs/docs/errors/rego-type-error/conflicting-rules-name-found.md b/docs/docs/errors/rego-type-error/conflicting-rules-name-found.md
index 25232a81c0..54bc2fc02c 100644
--- a/docs/docs/errors/rego-type-error/conflicting-rules-name-found.md
+++ b/docs/docs/errors/rego-type-error/conflicting-rules-name-found.md
@@ -65,7 +65,7 @@ While overloading functions on arity might work in some languages, it is not sup
## How To Fix It
Use a composite type, like objects, to return multiple values β like a boolean and a set of strings β from a rule.
-In the example below, we've added a `decision` rule, which compiles its value from both the boolean `deny` rule and
+In the example below, a `decision` rule has been added, which compiles its value from both the boolean `deny` rule and
the `reasons` set-generating rule:
```rego
@@ -93,7 +93,7 @@ reasons contains reason if {
}
```
-For the case of functions, simply ensure that the same arity is used for all declarations of the function. Use the
+For the case of functions, ensure that the same arity is used for all declarations of the function. Use the
wildcard operator (`_`) for arguments that are unused in any given declaration:
```rego
diff --git a/docs/docs/errors/rego-type-error/function-has-arity-got-argument.md b/docs/docs/errors/rego-type-error/function-has-arity-got-argument.md
index 661a8eee2f..8273fa77f3 100644
--- a/docs/docs/errors/rego-type-error/function-has-arity-got-argument.md
+++ b/docs/docs/errors/rego-type-error/function-has-arity-got-argument.md
@@ -48,7 +48,7 @@ When compiled, this will result in the following error:
## How To Fix It
In order to find the function that's being called with the wrong arity, you first need to find the line number
-in the error message - `16` in the example above. On that line, we need to update the function call to pass the
+in the error message - `16` in the example above. On that line, update the function call to pass the
correct number of arguments. The example above might be fixed like so:
```rego
diff --git a/docs/docs/errors/rego-type-error/match-error.md b/docs/docs/errors/rego-type-error/match-error.md
index 6b47d0412d..4fed039e85 100644
--- a/docs/docs/errors/rego-type-error/match-error.md
+++ b/docs/docs/errors/rego-type-error/match-error.md
@@ -5,7 +5,7 @@ image: /img/opa-errors.png
# `rego_type_error`: match error
-Just like the category suggests, this error is emitted by the _type checker_ during the compilation stage. This error
+As the category suggests, this error is emitted by the _type checker_ during the compilation stage. This error
is commonly triggered by comparing two values of different types, like a string and an integer (`"1" == 1`). In order
for the error to be reported, the compiler must be able to determine the types involved in the expression.
@@ -53,7 +53,7 @@ user2 := {"name": "jane"}
same_user if user1 == user2
```
-We're clearly comparing two objects, so should this really be a match error? The compiler would say yes:
+Two objects are being compared here. Should this really be a match error? The compiler would say yes:
```txt
1 error occurred: policy.rego:8: rego_type_error: match error
@@ -61,7 +61,7 @@ We're clearly comparing two objects, so should this really be a match error? The
right : object
```
-The reason for this is that while we may have objects on both sides, the type checker compares _recursively_. In doing
+The reason is that while objects appear on both sides, the type checker compares _recursively_. In doing
this it'll see that one object has an attribute (`age`) that the other doesn't, and hence considered to be of
different type after all. This is sometimes considered
[confusing](https://github.com/open-policy-agent/opa/issues/2132), but given that it also allows catching some bugs at
@@ -69,7 +69,7 @@ compile time, it's likely the right behavior.
## How To Fix It
-Fixing this is simple: just change the types to match on both sides of a comparison. For the few cases where one
+Fixing this requires changing the types to match on both sides of a comparison. For the few cases where one
_really_ wants to compare two values of different types, a helper function can be used to "wash" off the type
information from the comparison:
diff --git a/docs/docs/errors/rego-type-error/multiple-default-rules-name-found.md b/docs/docs/errors/rego-type-error/multiple-default-rules-name-found.md
index a2384c23a9..96d7a49be1 100644
--- a/docs/docs/errors/rego-type-error/multiple-default-rules-name-found.md
+++ b/docs/docs/errors/rego-type-error/multiple-default-rules-name-found.md
@@ -15,8 +15,8 @@ This error is raised when multiple `default` rules are found for a single rule.
## Examples
-A trivial example of a policy that contains this error is this one, where we have two `default`s
-defined for the `allow` rule:
+A trivial example of a policy that contains this error is this one, where two `default`s are defined
+for the `allow` rule:
```rego
package policy
@@ -58,7 +58,7 @@ allow if {
}
```
-If we were to run OPA loading these two files, we would see the error:
+Running OPA loading these two files produces the error:
```shell
$ opa run -s *.rego
@@ -70,5 +70,5 @@ $ opa run -s *.rego
In almost all cases, if you have an error like this: `multiple default rules data.policy.allow found`,
searching for `default allow` in your Rego files will show up the various duplicates.
-Just remember that they could be spread across multiple files, and you want to make sure to check only
-within the package in the error message, `policy` in our example above.
+Remember that they could be spread across multiple files, and you want to make sure to check only
+within the package in the error message, `policy` in the example above.
diff --git a/docs/docs/errors/rego-type-error/multiple-default-rules.md b/docs/docs/errors/rego-type-error/multiple-default-rules.md
index 28b25c4dab..66c7e24ecb 100644
--- a/docs/docs/errors/rego-type-error/multiple-default-rules.md
+++ b/docs/docs/errors/rego-type-error/multiple-default-rules.md
@@ -52,7 +52,7 @@ package example
default allow := true
```
-We would see an error like this when using the two files:
+Using the two files produces an error like this:
```shell
$ opa eval data.example.allow -d example1.rego -d example2.rego
@@ -66,6 +66,6 @@ search for the other definitions.
## How To Fix It
-Fixing this error is usually simple: just remove one of the repeated `default` definitions if they are setting the same
+Fixing this error is usually straightforward: remove one of the repeated `default` definitions if they are setting the same
default value. If the intention is to set different default values, this is trickier, but perhaps you'd be better served
by two different rules.
diff --git a/docs/docs/errors/rego-type-error/unsafe-built-in-function-calls-in-expression-name.md b/docs/docs/errors/rego-type-error/unsafe-built-in-function-calls-in-expression-name.md
index a3bf52e431..6b6c750a48 100644
--- a/docs/docs/errors/rego-type-error/unsafe-built-in-function-calls-in-expression-name.md
+++ b/docs/docs/errors/rego-type-error/unsafe-built-in-function-calls-in-expression-name.md
@@ -22,5 +22,5 @@ thought it would be a good idea to put certain restrictions in place.
## How To Fix It
Check the capabilities configuration provided to OPA when executed, and the `--capabilities` flag in particular.
-If you're encountering this on the Rego Playground, simply run the policy on your own machine using e.g. `opa eval`
+If you're encountering this on the Rego Playground, run the policy on your own machine using e.g. `opa eval`
or `opa run` instead.
diff --git a/docs/docs/errors/rego-unsafe-var-error/var-name-is-unsafe.md b/docs/docs/errors/rego-unsafe-var-error/var-name-is-unsafe.md
index 82ce6417ca..c4c4de1cda 100644
--- a/docs/docs/errors/rego-unsafe-var-error/var-name-is-unsafe.md
+++ b/docs/docs/errors/rego-unsafe-var-error/var-name-is-unsafe.md
@@ -5,7 +5,7 @@ image: /img/opa-errors.png
# `rego_unsafe_var_error`: var `{name}` is unsafe
-This is one of the most common errors reported by OPA. When a variable is "unsafe" it simply means that OPA wasn't able
+This is one of the most common errors reported by OPA. When a variable is "unsafe" it means that OPA wasn't able
to determine where to find it. This is commonly caused by misspelling the name of the variable, or perhaps by
referencing a rule or function that doesn't (yet) exist. Note that this check happens at _compile time_. This means that
references like `input.username` will not be considered unsafe even when there is no `username` attribute in the `input`
@@ -32,13 +32,13 @@ allow if user_is_admin
user_is_developer if "developer" in input.user.roles
```
-Not that easy! But luckily we won't have to, as the compiler does it for us:
+Fortunately the compiler reports it automatically:
```shell
1 error occurred: policy.rego:8: rego_unsafe_var_error: var user_is_admin is unsafe
```
-Of course! We had forgotten to provide an actual `user_is_admin` rule before we used it, and hence why it's
+The `user_is_admin` rule was not defined before use, which is why it's
considered unsafe.
Sometimes, the location of the errors isn't as clear-cut, even when reading the errors.
@@ -67,15 +67,15 @@ foo.rego:6: rego_unsafe_var_error: var title_upper is unsafe
```
Since `users` is unsafe, every variable that depend on `users` is _also_ considered unsafe. This means that _all_ the
-variables in our `allow` rule will be considered unsafe, and we'll have to do some investigative work to figure out
+variables in the `allow` rule will be considered unsafe, requiring some investigation to figure out
what the actual root cause was. Whether this should be needed or not is
-[up for debate](https://github.com/open-policy-agent/opa/issues/6393), and perhaps we'll be able to skip this in future
+[up for debate](https://github.com/open-policy-agent/opa/issues/6393), and this limitation may be removed in future
OPA versions.
## How To Fix It
-Once you've found the unsafe variable (the compiler should help here, as we see
-above), first we must figure out _why_ it's considered unsafe. There are two
+Once the unsafe variable is found (the compiler should help here, as shown
+above), determine _why_ it is considered unsafe. There are two
main reasons that a variable is considered unsafe:
- You have a typo in the policy pointing the compiler to the wrong place.
@@ -87,16 +87,15 @@ there too.
If the variable name and definition are correct, the issue is likely that the
definition of the rule has not been loaded into OPA. One thing to keep in mind
-is that all OPA commands that accept a file may just as well be provided a
-directory, which will be loaded recursively. This is often the best way to
-ensure all the files you may depend on are loaded and available during
-compilation.
+is that all OPA commands that accept a file can also be provided a
+directory, which will be loaded recursively. This is often the best way to ensure all the files you may depend on are
+loaded and available during compilation.
## More Information
-Remember how we said earlier that the compiler won't consider a reference like `input.usrname` (note the typo!)
-unsafe, even though we clearly intended to say `input.username`? Wouldn't it be great if we had some way to tell the
-OPA compiler what the `input` object should look like, and have it include that in this type of check? Luckily, there
-is! The desired structure (i.e. the _schema_) of both `input` and `data` may be provided to the compiler via OPA's
+Recall that the compiler won't consider a reference like `input.usrname` (note the typo!)
+unsafe, even though the intent was `input.username`. Schema annotations provide a way to tell the
+OPA compiler what the `input` object should look like, and have it include that in this type of check.
+The desired structure (i.e. the _schema_) of both `input` and `data` may be provided to the compiler via OPA's
[JSON schema capability](https://www.openpolicyagent.org/docs/policy-language/#schema), thus extending the
compiler and the type checker with this information. It'll take some work to set up, but it's well worth it!
diff --git a/docs/docs/extensions.md b/docs/docs/extensions.md
index 9f2f839fa0..93016bee0c 100644
--- a/docs/docs/extensions.md
+++ b/docs/docs/extensions.md
@@ -94,7 +94,7 @@ The example above highlights a few important points.
- The function indicates it's undefined by returning `nil` for the first return
argument.
-Let's look at another example. Imagine you want to expose GitHub repository
+The following example shows another use case. Imagine you want to expose GitHub repository
metadata to your policies. One option is to implement a custom built-in
function to fetch the data for specific repositories on-the-fly.
diff --git a/docs/docs/external-data/index.md b/docs/docs/external-data/index.md
index 0d99e94cec..b92a8e4b76 100644
--- a/docs/docs/external-data/index.md
+++ b/docs/docs/external-data/index.md
@@ -56,7 +56,7 @@ JWTs have a limited size in practice, so if your organization has too many user
## Option 2: Overload `input`
-Often policies require external data that's not available to the authentication system, ruling out JWTs. The calling system can include external data as part of `input` (necessitating of course that the policy is written accordingly).
+Often policies require external data that's not available to the authentication system, ruling out JWTs. The calling system can include external data as part of `input` (necessitating that the policy is written accordingly).
For example, suppose your policy says that only a file's owner may delete it. The authentication system does not track resource-ownership, but the system responsible for files certainly does.
@@ -124,7 +124,7 @@ The lag between a data update and OPA having the update is the sum of the lag fo
### Size limitations
-OPA stores the entire datasource at once in memory. Obviously this can be a problem with large external data sets. Because the centralized server handles both policy and data it can prune data to just that which is needed for the policies.
+OPA stores the entire datasource at once in memory. This can be a problem with large external data sets. Because the centralized server handles both policy and data it can prune data to just that which is needed for the policies.
-In the example that follows, we show a policy that uses the
+The following example shows a policy that uses the
`regex.find_all_string_submatch_n` built-in to extract the 'plus suffix', if
present, from an email address.
diff --git a/docs/docs/policy-reference/_examples/regex/find_all_string_submatch_n/scope_parsing/intro.md b/docs/docs/policy-reference/_examples/regex/find_all_string_submatch_n/scope_parsing/intro.md
index 5293f71d26..907d857e66 100644
--- a/docs/docs/policy-reference/_examples/regex/find_all_string_submatch_n/scope_parsing/intro.md
+++ b/docs/docs/policy-reference/_examples/regex/find_all_string_submatch_n/scope_parsing/intro.md
@@ -1,6 +1,6 @@
-Here we see how `regex.find_all_string_submatch_n` can be used to create
-structured data from unstructured text. In this example, we parse a list of
-scopes from a string and use that to create an object we can use in policies to
+The following example shows how `regex.find_all_string_submatch_n` can be used to create
+structured data from unstructured text. In this example, a list of
+scopes is parsed from a string to create an object that can be used in policies to
look up permissions.
diff --git a/docs/docs/policy-reference/_examples/regex/match/case-insensitive/intro.md b/docs/docs/policy-reference/_examples/regex/match/case-insensitive/intro.md
index 4b202acd65..555845ebc8 100644
--- a/docs/docs/policy-reference/_examples/regex/match/case-insensitive/intro.md
+++ b/docs/docs/policy-reference/_examples/regex/match/case-insensitive/intro.md
@@ -3,5 +3,5 @@
Sometimes data can be supplied in a variety of cases, and matches need to be
the same regardless of case. One example of this when matching GitHub usernames.
-This is where the `(?i)` modifier comes in. In the following example we can see
+This is where the `(?i)` modifier comes in. The following example shows
how repositories with different cases are matched.
diff --git a/docs/docs/policy-reference/_examples/regex/match/email/intro.md b/docs/docs/policy-reference/_examples/regex/match/email/intro.md
index de31cd0b88..8b0f817877 100644
--- a/docs/docs/policy-reference/_examples/regex/match/email/intro.md
+++ b/docs/docs/policy-reference/_examples/regex/match/email/intro.md
@@ -5,4 +5,4 @@ is more complicated than just checking an email matches a pattern, but since a R
policy is often a first point of contact, doing a pattern based test on emails is
still a good idea as it can help surface issues to users early if they make a mistake.
-`regex.match` is the best way to validate emails in Rego.
+Use `regex.match` to validate emails in Rego.
diff --git a/docs/docs/policy-reference/_examples/regex/template_match/path_pattern/intro.md b/docs/docs/policy-reference/_examples/regex/template_match/path_pattern/intro.md
index 80befe89c0..2aea042fbb 100644
--- a/docs/docs/policy-reference/_examples/regex/template_match/path_pattern/intro.md
+++ b/docs/docs/policy-reference/_examples/regex/template_match/path_pattern/intro.md
@@ -1,6 +1,6 @@
-In the example that follows, we have a complex path which represents an AWS ARN
+The following example uses a complex path representing an AWS ARN
owned by a project with a UUID v4 identifier. The path is validated in two
parts using two separate patterns, each contained to particular segments of the
path.
diff --git a/docs/docs/policy-reference/_examples/time/clock/local_business_hours/intro.md b/docs/docs/policy-reference/_examples/time/clock/local_business_hours/intro.md
index 4901def1fc..e0fe3e2cf3 100644
--- a/docs/docs/policy-reference/_examples/time/clock/local_business_hours/intro.md
+++ b/docs/docs/policy-reference/_examples/time/clock/local_business_hours/intro.md
@@ -4,5 +4,5 @@ A common attribute-based access control (ABAC) requirement is to grant
access based on time. This is typically done by determining the user's
local time and ensuring it falls within a given period.
-In this example we show how to allow requests when made by a user
+This example shows how to allow requests when made by a user
in their local business hours.
diff --git a/docs/docs/policy-reference/_examples/time/format/local_time/intro.md b/docs/docs/policy-reference/_examples/time/format/local_time/intro.md
index 197199ec9f..1f4d46aedd 100644
--- a/docs/docs/policy-reference/_examples/time/format/local_time/intro.md
+++ b/docs/docs/policy-reference/_examples/time/format/local_time/intro.md
@@ -6,6 +6,6 @@ and local times can be useful when debugging or troubleshooting
and so in many cases returning them from policy decisions can
be helpful.
-In this example we see a user is not an admin and is denied access,
+In this example, a user is not an admin and is denied access,
the policy response is a message that includes the current time
and an error code to help them debug.
diff --git a/docs/docs/policy-reference/_examples/time/now_ns/past/intro.md b/docs/docs/policy-reference/_examples/time/now_ns/past/intro.md
index e27dd347b7..5a76f39995 100644
--- a/docs/docs/policy-reference/_examples/time/now_ns/past/intro.md
+++ b/docs/docs/policy-reference/_examples/time/now_ns/past/intro.md
@@ -1,6 +1,6 @@
-In this example, we see compare an
+This example compares an
[RFC3339](https://datatracker.ietf.org/doc/html/rfc3339) timestamp
with the current time to determine if the timestamp is in the past.
diff --git a/docs/docs/policy-reference/_examples/time/parse_ns/period/intro.md b/docs/docs/policy-reference/_examples/time/parse_ns/period/intro.md
index baaae27d25..993ecc5507 100644
--- a/docs/docs/policy-reference/_examples/time/parse_ns/period/intro.md
+++ b/docs/docs/policy-reference/_examples/time/parse_ns/period/intro.md
@@ -1,6 +1,6 @@
-In order to check if a time is in a period of time, we need to know the
-start and the end of the period first. This policy defines two dates in
+To check if a time is in a period of time, the start and end of the period
+must be known first. This policy defines two dates in
time to mark the start and the end of the period, before testing if the
supplied time is in the period.
diff --git a/docs/docs/policy-reference/_examples/time/parse_ns/time_format/intro.md b/docs/docs/policy-reference/_examples/time/parse_ns/time_format/intro.md
index 2b91a64b48..38402e1ff9 100644
--- a/docs/docs/policy-reference/_examples/time/parse_ns/time_format/intro.md
+++ b/docs/docs/policy-reference/_examples/time/parse_ns/time_format/intro.md
@@ -1,3 +1,3 @@
-In OPA, we can parse a simple YYYY-MM-DD timestamp as follows:
+In OPA, a simple YYYY-MM-DD timestamp can be parsed as follows:
diff --git a/docs/docs/policy-reference/index.md b/docs/docs/policy-reference/index.md
index cd75aa14c8..c84c08f14c 100644
--- a/docs/docs/policy-reference/index.md
+++ b/docs/docs/policy-reference/index.md
@@ -9,7 +9,7 @@ import BuiltinLegacyRedirect from "@site/src/components/BuiltinLegacyRedirect";
This page is a reference for details of the Rego language and its syntax. See
-our guided [Policy Language](./policy-language) page for a walked introduction.
+the guided [Policy Language](./policy-language) page for a walked introduction.
There are also detailed sections for
[built-in functions](./policy-reference/builtins) as well as examples for
specific keywords such as
diff --git a/docs/docs/policy-reference/keywords/_examples/contains/todo-list/intro.md b/docs/docs/policy-reference/keywords/_examples/contains/todo-list/intro.md
index c9540ae815..2135284905 100644
--- a/docs/docs/policy-reference/keywords/_examples/contains/todo-list/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/contains/todo-list/intro.md
@@ -1,9 +1,9 @@
-While this first example is trivially simple and unlikely to be useful when building real
+While this first example is simple and unlikely to be useful when building real
policies, it illustrates the fundamental reason for using the `contains` keyword: building sets.
Sets are unordered collections, and they form an important building block for many policies.
-In this example, we use a multi-value rule defined using the `contains` keyword to create a simple
+In this example, a multi-value rule defined using the `contains` keyword creates a simple
list of todos. Just remember that sets are unordered and so you should not depend on the order of
the result.
diff --git a/docs/docs/policy-reference/keywords/_examples/default/overrides/intro.md b/docs/docs/policy-reference/keywords/_examples/default/overrides/intro.md
index 3ff883e17a..e58bde8eff 100644
--- a/docs/docs/policy-reference/keywords/_examples/default/overrides/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/default/overrides/intro.md
@@ -1,8 +1,8 @@
-As we saw in the previous example, `default` is helpful for handling undefined
+As shown in the previous example, `default` is helpful for handling undefined
values. Handling undefined values is not just important for callers, but also
within policies themselves.
-Using the `default` keyword with functions, we can quickly build in
-functionality to set a base case that's overridden when conditions are met.
+The `default` keyword with functions provides a convenient way to set a base
+case that is overridden when conditions are met.
diff --git a/docs/docs/policy-reference/keywords/_examples/every/feature-flags/intro.md b/docs/docs/policy-reference/keywords/_examples/every/feature-flags/intro.md
index 379d69dea1..5382e9e37b 100644
--- a/docs/docs/policy-reference/keywords/_examples/every/feature-flags/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/every/feature-flags/intro.md
@@ -1,6 +1,6 @@
-Here we use the `every` keyword to validate that an example session has all the
+The `every` keyword is used here to validate that an example session has all the
required feature flags for a request.
`test_speedy_checkout` is false in the `input.json`, this will need to be true
diff --git a/docs/docs/policy-reference/keywords/_examples/every/internal-meetings/intro.md b/docs/docs/policy-reference/keywords/_examples/every/internal-meetings/intro.md
index 54b30f8c1e..7c74a6b97d 100644
--- a/docs/docs/policy-reference/keywords/_examples/every/internal-meetings/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/every/internal-meetings/intro.md
@@ -1,6 +1,6 @@
-Every can also be used to check an object's keys and values. Here we do just
+`every` can also be used to check an object's keys and values. The following example does just
that to validate attendees of a meeting invite.
In this example, all attendees must have the staff role and the correct email
diff --git a/docs/docs/policy-reference/keywords/_examples/if/functions/intro.md b/docs/docs/policy-reference/keywords/_examples/if/functions/intro.md
index d2bb835d9a..77ca65626c 100644
--- a/docs/docs/policy-reference/keywords/_examples/if/functions/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/if/functions/intro.md
@@ -4,7 +4,7 @@
or more heads. The head and body of a function are also separated by the `if`
keyword for consistency and readability.
-In this example, we can see that the `is_sudo` function is incrementally defined
+In this example, the `is_sudo` function is incrementally defined
where each head adds new cases to the functionality. In this case, each head
defines scenarios where the user is a 'sudoer' - both when the user is an admin
or when the user has the sudo field set.
diff --git a/docs/docs/policy-reference/keywords/_examples/if/when-not/intro.md b/docs/docs/policy-reference/keywords/_examples/if/when-not/intro.md
index 45693359c8..f243aa43c9 100644
--- a/docs/docs/policy-reference/keywords/_examples/if/when-not/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/if/when-not/intro.md
@@ -1,4 +1,4 @@
-`if` is _everywhere_ in Rego, but there are some cases where we don't use it.
+`if` is _everywhere_ in Rego, but there are some cases where it is not used.
In this example, using `if` for a rule name is a parse error.
diff --git a/docs/docs/policy-reference/keywords/_examples/some/some-in-object/intro.md b/docs/docs/policy-reference/keywords/_examples/some/some-in-object/intro.md
index e3f51a1095..532cd916e6 100644
--- a/docs/docs/policy-reference/keywords/_examples/some/some-in-object/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/some/some-in-object/intro.md
@@ -1,9 +1,9 @@
Similar to arrays, `some` can also be used on key->value pairs in
-objects. Here, we create two variables, one for the key and another
+objects. Here, two variables are created, one for the key and another
for the value. The Rego rule is then evaluated for each pair.
-We can use the key and value however we like. Here, we use the
+The key and value can be used in any way. Here, the rule uses the
name of the permission to create a list of permissions that are
toggled on in the `example_object`.
diff --git a/docs/docs/policy-reference/keywords/_examples/some/some-in/intro.md b/docs/docs/policy-reference/keywords/_examples/some/some-in/intro.md
index a09383a9cd..e14d928a0f 100644
--- a/docs/docs/policy-reference/keywords/_examples/some/some-in/intro.md
+++ b/docs/docs/policy-reference/keywords/_examples/some/some-in/intro.md
@@ -1,6 +1,6 @@
-In this example, we use `some` to select each item in an array,
+In this example, `some` is used to select each item in an array,
perform a check on it, and return matching items as a new array.
Processing lists of values like this is one of the most common use
cases for `some`.
diff --git a/docs/docs/policy-reference/keywords/every.md b/docs/docs/policy-reference/keywords/every.md
index d77b094946..7a4b24e8f5 100644
--- a/docs/docs/policy-reference/keywords/every.md
+++ b/docs/docs/policy-reference/keywords/every.md
@@ -10,7 +10,7 @@ keyword makes this
[universal quantification](/docs/policy-language#universal-quantification-for-all)
easier.
-Here we show two equivalent rules achieve universal quantification, note how
+The following two equivalent rules achieve universal quantification. Note how
much easier to read the one using `every` is.
```rego
@@ -31,7 +31,7 @@ allow2 if {
`allow2` works by generating a set of 'results' testing elements from the
array `[1,2,3]`. The resulting set is tested against `{true}` to verify all
-elements are `true`. As we can see `every` is a much better option!
+elements are `true`. `every` is a much better option!
## Examples
diff --git a/docs/docs/policy-reference/keywords/import.md b/docs/docs/policy-reference/keywords/import.md
index f8f0928528..eae986df3c 100644
--- a/docs/docs/policy-reference/keywords/import.md
+++ b/docs/docs/policy-reference/keywords/import.md
@@ -5,15 +5,14 @@ title: 'Rego Keyword Examples: import'
In Rego, the `import` keyword is used to include references in the current file
from other places, namely other Rego packages. However, the `import` keyword is
-also used to change the Rego syntax available in the current file. Let's cover
-this case first.
+also used to change the Rego syntax available in the current file. This case is covered first.
## Importing packages
Most importantly, the `import` keyword is used to make the rules defined in one
package, available in another.
-Imagine we have a package, `package1`, that defines a rule `name` like this:
+Consider a package, `package1`, that defines a rule `name` like this:
```rego
package package1
@@ -25,8 +24,7 @@ name := "World"
-Now, if we'd like to use the `name` rule in another package, `package2`, we
-could do something like this:
+To use the `name` rule in another package, `package2`, write something like this:
```rego
package package2
@@ -43,7 +41,7 @@ output := sprintf("Hello, %v", [data.package1.name])
While this will work, it's better to use an import at the top of the file to
save repetition and declare the dependency upfront for readers of the policy.
-We can achieve the same result like this:
+The same result can be achieved like this:
```rego
package package2
diff --git a/docs/docs/policy-reference/keywords/not.md b/docs/docs/policy-reference/keywords/not.md
index 1e36557232..17959f8656 100644
--- a/docs/docs/policy-reference/keywords/not.md
+++ b/docs/docs/policy-reference/keywords/not.md
@@ -89,7 +89,7 @@ admin(group) if group in ["admin", "sudo"]
:::important
-Notice how if we remove the `future.keywords.not` import in the above policy, the `restricted` rule starts failing.
+Notice that removing the `future.keywords.not` import in the above policy causes the `restricted` rule to start failing.
This is a consequence of the `lookup()` function failing with an `undefined` value.
:::
diff --git a/docs/docs/policy-testing.md b/docs/docs/policy-testing.md
index 250724a5df..9d82c3acb6 100644
--- a/docs/docs/policy-testing.md
+++ b/docs/docs/policy-testing.md
@@ -14,7 +14,7 @@ and reduce the amount of time it takes to modify rules as requirements evolve.
## Getting Started
-Let's use an example to get started. The file below implements a simple
+The following example demonstrates getting started. The file below implements a simple
policy that allows new users to be created and users to access their own
profile.
@@ -32,7 +32,7 @@ allow if {
}
```
-To test this policy, we will create a separate Rego file that contains test cases.
+To test this policy, create a separate Rego file that contains test cases.
```rego title="example_test.rego"
package authz_test
@@ -159,7 +159,7 @@ FAIL: 1/1
```
The test failed because it expected users with **write** permission to implicitly also have the **read** permission, an expectation the function under test didn't meet.
-By including the failing expression and its local variable assignments in the test report, we make troubleshooting easier for the developer, as it's immediately apparent what assertion and combination of parameters caused the test to fail.
+The test report includes the failing expression and its local variable assignments, making it immediately apparent what assertion and combination of parameters caused the failure.
## Test Format
@@ -603,7 +603,7 @@ It is also possible that [rule indexing](./policy-performance/#use-indexed-state
has determined some path unnecessary for evaluation, thereby affecting the lines
reported as covered.
-If we run the coverage report on the original **example.rego** file without
+If the coverage report is run on the original **example.rego** file without
`test_get_user_allowed` from **example_test**.rego the report will indicate
that line 8 is not covered.
diff --git a/docs/docs/privacy.md b/docs/docs/privacy.md
index 4c56f213a6..768d95e089 100644
--- a/docs/docs/privacy.md
+++ b/docs/docs/privacy.md
@@ -29,7 +29,7 @@ Host: api.github.com
User-Agent: OPA-Version-Checker
```
-No data about your OPA instance is sent in the request. OPA simply retrieves
+No data about your OPA instance is sent in the request. OPA retrieves
information about the latest release. The GitHub API responds with release
information including the tag name and release notes URL. OPA uses this
information to determine if a newer version is available and constructs a
diff --git a/docs/docs/rest-api.md b/docs/docs/rest-api.md
index fb64502ff1..87f8415155 100644
--- a/docs/docs/rest-api.md
+++ b/docs/docs/rest-api.md
@@ -1657,7 +1657,7 @@ exceptions contains "bob"
exceptions contains "alice"
```
-In this case, if we execute query on behalf of a user that does not
+In this case, if a query is executed on behalf of a user that does not
have an exception (e.g., `"eve"`), the OPA response will not contain a
`queries` field at all. This indicates there are NO conditions that
could make the query true.
@@ -1729,7 +1729,7 @@ OPA uses the `Accept` header to denote the target response format.
#### Example Request
-With OPA running with this policy, we'll compile the query `data.filters.include` into SQL filters:
+With OPA running with this policy, the following request compiles the query `data.filters.include` into SQL filters:
```rego
package filters
@@ -1797,7 +1797,7 @@ An empty string `query` indicates **unconditional include**:
#### Example: Mapping Table and Column Names
-For this example, let's assume OPA is running with this policy:
+For this example, assume OPA is running with this policy:
```rego
package filters
@@ -1812,7 +1812,7 @@ include if input.price == "free"
```
If there is no one-to-one correspondence between unknowns and table/column names, the target mapping comes into play.
-With this mapping, we would translate the policy into `WHERE fruit.display_name = E'pineapple' AND fruit.price_tag = E'free'`:
+With this mapping, the policy translates into `WHERE fruit.display_name = E'pineapple' AND fruit.price_tag = E'free'`:
```http
POST /v1/compile/filters/include
@@ -2398,7 +2398,7 @@ faster to evaluate since OPA will not have to re-parse or compile it. Hence, whe
OPA also supports query instrumentation. To enable query instrumentation,
specify the `instrument=true` query parameter when executing the API call.
Query instrumentation can help diagnose performance problems, however, it can
-add significant overhead to query evaluation. We recommend leaving query
+add significant overhead to query evaluation. It is recommended to leave query
instrumentation off unless you are debugging a performance problem.
When instrumentation is enabled there are several additional performance metrics
diff --git a/docs/docs/security.md b/docs/docs/security.md
index e20070523a..81459b74db 100644
--- a/docs/docs/security.md
+++ b/docs/docs/security.md
@@ -58,7 +58,7 @@ openssl genrsa -out private.key 2048
openssl req -new -x509 -sha256 -key private.key -out public.crt -days 1
```
-> We have generated a self-signed certificate for example purposes here. DO NOT
+> A self-signed certificate has been generated for example purposes here. DO NOT
> rely on self-signed certificates outside of development without understanding
> the risks.
@@ -83,7 +83,7 @@ curl -k https://localhost:8181/v1/data
```
:::info
-We have to use cURL's `-k/--insecure` flag because we are using a self-signed certificate.
+cURL's `-k/--insecure` flag is required because a self-signed certificate is used.
:::
## Interface Binding
@@ -411,17 +411,17 @@ identity_rights contains right if { # Right is in the identity_rights set if...
### TLS-based Authentication Example
-To set up authentication based on mutual TLS, we will need three certificates:
+To set up authentication based on mutual TLS, three certificates are needed:
1. the CA cert (self-signed),
2. the server cert (signed by the CA), and
3. the client cert (signed by the CA).
-We use `openssl` to create the example certificates and keys used in this demo. In production, creation of certificates
+`openssl` is used to create the example certificates and keys in this demo. In production, creation of certificates
and keys should be handled by an automated process out of scope for this tutorial.
-Note that we also create an extra client cert (client-2). While this certificate is signed by the same CA, it's identity
-is different. We'll use this to show our authorization policy in action.
+Note that an extra client cert (client-2) is also created. While this certificate is signed by the same CA, its identity
+is different. This cert demonstrates the authorization policy in action.
```bash
# CA
@@ -489,7 +489,7 @@ openssl req -new -key server-key.pem -out csr.pem -subj "/CN=server" -config req
openssl x509 -req -in csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 10 -extensions v3_req -extfile req.cnf -sha256
```
-We also create an example authorization policy file, called `check.rego`. This example `system.authz` policy will check
+An example authorization policy file, `check.rego`, is also created. This example `system.authz` policy will check
the certificate ID against a list of allowed paths as defined in a simple Access Control List.
:::danger
@@ -522,7 +522,7 @@ allow := {"allowed": true} if {
}
```
-Now, we're ready to starting the server with `-authentication=tls` and the
+Start the server with `-authentication=tls` and the
certificate-related parameters:
```console
@@ -537,10 +537,10 @@ $ opa run -s \
{"addrs":["https://127.0.0.1:8181"],"diagnostic-addrs":[],"level":"info","msg":"Initializing server.","time":"2023-01-04T10:31:12Z"}
```
-We can use `curl` to validate our TLS-based authentication setup:
+Use `curl` to validate the TLS-based authentication setup:
-First, we use the client certificate that was signed by the CA, and has a subject
-matching our authorization policy:
+First, use the client certificate that was signed by the CA, with a subject
+matching the authorization policy:
```console
$ curl --key client-key-1.pem \
@@ -551,13 +551,13 @@ $ curl --key client-key-1.pem \
{"result":{}}
```
-Note that we're passing the CA cert to curl -- this is done to have curl accept
-the server's certificate, which has been signed by our CA cert.
+Note that the CA cert is passed to curl -- this is done to have curl accept
+the server's certificate, which has been signed by the CA cert.
-Since we've set up an IP SAN, we may also `curl https://127.0.0.1:8181/v1/data`
-directly. (To keep our examples focused, we'll do that from here on.)
+Since an IP SAN is configured, `curl https://127.0.0.1:8181/v1/data`
+also works directly. The remaining examples use this shorter form to stay focused.
-Using a valid certificate whose subject will be declined by our authorization
+Using a valid certificate whose subject will be declined by the authorization
policy:
```console
@@ -571,7 +571,7 @@ $ curl --key client-key-2.pem \
}
```
-Finally, we'll attempt to query without a client certificate:
+Finally, query without a client certificate:
```console
$ curl --cacert ca.pem https://127.0.0.1:8181/v1/data
diff --git a/docs/docs/ssh-and-sudo-authorization.md b/docs/docs/ssh-and-sudo-authorization.md
index a0ae0416a3..eb6550f9f7 100644
--- a/docs/docs/ssh-and-sudo-authorization.md
+++ b/docs/docs/ssh-and-sudo-authorization.md
@@ -3,8 +3,8 @@ title: SSH and sudo
---
Host-level access controls are an important part of every organization's
-security strategy. Using [Linux-PAM](https://tldp.org/HOWTO/User-Authentication-HOWTO/x115.html) and OPA
-we can extend policy-based access control to SSH and sudo.
+security strategy. With [Linux-PAM](https://tldp.org/HOWTO/User-Authentication-HOWTO/x115.html) and OPA,
+policy-based access control can be extended to SSH and sudo.
## Goals
@@ -12,16 +12,16 @@ This tutorial shows how you can use OPA and Linux-PAM to enforce fine-grained,
host-level access controls over SSH and sudo.
Linux-PAM can be configured to delegate authorization decisions to plugins
-(shared libraries). In this case, we have created an OPA-based plugin that can
+(shared libraries). An OPA-based plugin has been created that can
be configured to authorize SSH and sudo access. The OPA-based Linux-PAM plugin
used in this tutorial can be found at [open-policy-agent/contrib](https://github.com/open-policy-agent/contrib/tree/main/pam_opa).
-For this tutorial, our desired policy is:
+For this tutorial, the desired policy is:
- Admins can SSH into any host and run sudo commands.
- Normal users can SSH into hosts that they have _contributed_ to and run sudo commands.
-Furthermore, we'll assume we have the following set of users and hosts:
+The following set of users and hosts is assumed:
- `frontend-dev` is a developer who contributes to the app running on the `frontend` host.
- `backend-dev` is a developer who contributes to the app running on the `backend` host.
@@ -32,8 +32,6 @@ responsibility so this tutorial relies on identities being statically
defined. In real-world scenarios authentication can be delegated to SSH itself
(`authorized_keys`) or other identity management systems.
-Let's get started.
-
## Prerequisites
This tutorial requires [Docker Compose](https://docs.docker.com/compose/install/) to run dummy SSH hosts along
@@ -44,7 +42,7 @@ with OPA. The dummy SSH hosts are just containers running sshd inside.
### 1. Bootstrap the tutorial environment using Docker Compose
First, create a `tutorial-docker-compose.yaml` file that runs OPA and the containers that
-represent our backend and frontend hosts.
+represent the backend and frontend hosts.
```yaml title="tutorial-docker-compose.yaml"
@@ -92,7 +90,7 @@ services:
The `tutorial-docker-compose.yaml` file requires two other local files:
`frontend_host_id.json` and `backend_host_id.json`. These files are mounted
-into the containers representing our hosts. The content of the file provides
+into the containers representing the hosts. The content of the file provides
_context_ that the PAM module provides as input when executing queries
against OPA.
@@ -103,7 +101,7 @@ echo '{"host_id": "frontend"}' > frontend_host_id.json
echo '{"host_id": "backend"}' > backend_host_id.json
```
-> In real-world scenarios, these files could contain arbitrary information that we want to expose to the policy.
+> In real-world scenarios, these files could contain arbitrary information to expose to the policy.
Finally, run `docker-compose` to pull and run the containers.
@@ -112,7 +110,7 @@ docker-compose -f tutorial-docker-compose.yaml up
```
This tutorial uses a special Docker image named `openpolicyagent/demo-pam` to simulate an SSH server.
-This image contains pre-created Linux accounts for our users, and the required PAM module is
+This image contains pre-created Linux accounts for the users, and the required PAM module is
pre-configured inside the `sudo` and `sshd` files in `/etc/pam.d/`.
### 2. Create a Bundle for the policies and data
@@ -147,8 +145,7 @@ include some default values, such as the username making the request. See
[this documentation](https://github.com/open-policy-agent/contrib/tree/main/pam_opa/pam#authz)
to get a better understanding of what the `input` to the authorization policy will look like.
-Unlike the _pull_ policy, we'll create separate _authz_ policies
-for SSH and `sudo` for more fine-grained control.
+Unlike the _pull_ policy, the _authz_ policies for SSH and `sudo` are kept separate for more fine-grained control.
In production, it makes more sense to have this separation for _display_ and _pull_ as well.
Create the SSH authorization policy. It should allow admins to SSH into all hosts,
@@ -211,7 +208,7 @@ errors contains "Request denied by administrative policy" if {
}
```
-Now we need to create the data that represents our roles, hots, and contributors into OPA.
+Create the data that represents the roles, hosts, and contributors in OPA.
Create a folder called roles, and the following data file.
@@ -270,7 +267,7 @@ Now you should have the following file structure setup.
### 3. SSH and sudo as a user with the `admin` role
-First, let's try to access the hosts as the `ops` user. Recall, the `ops` user
+First, try to access the hosts as the `ops` user. Recall, the `ops` user
has been granted the `admin` role (via the `PUT /data/roles` request above) and
users with the `admin` role can login to any host and perform sudo commands.
@@ -292,7 +289,7 @@ configuration. For more details see
### 4. SSH as a user without the `admin` role
-Let's try a user without the admin role. Recall, that a non-admin user can SSH
+Try a user without the admin role. Recall, that a non-admin user can SSH
into any host that they have _contributed to_.
The `frontend-dev` user contributed code to the `frontend` host so they should be
@@ -320,7 +317,7 @@ Suppose you have a ticketing system for elevation, where you generate tickets fo
that need elevated rights, send the ticket to the user, and expire those tickets when
their rights should be removed.
-Let's mock the current state of this simple ticketing system's API with some data.
+Mock the current state of this simple ticketing system's API with some data.
```shell
mkdir elevate
@@ -336,9 +333,9 @@ EOF
This means that for now, if the `frontend-dev` user can provide ticket number `1234`,
they should be able to SSH into all servers.
-Let's write policy to ensure that this happens.
+Write policy to ensure that this happens.
-First, we need to make the PAM module take input from the user.
+First, make the PAM module take input from the user.
**display.rego**:
@@ -355,7 +352,7 @@ display_spec := [
]
```
-Then we need to make sure that the authorization takes this input into account.
+Then make sure that the authorization takes this input into account.
**sudo_authz_elevated.rego**:
@@ -374,7 +371,7 @@ allow if {
}
```
-Now we need to build a new bundle for OPA to use.
+Now build a new bundle for OPA to use.
```shell
opa build -b .
@@ -389,12 +386,12 @@ ssh -p 2222 frontend-dev@localhost \
sudo ls /
```
-You should be prompted with the message that we defined in our _display_ policy
+You should be prompted with the message defined in the _display_ policy
for both the SSH and `sudo` authorization cycles.
This happens because the _display_ policy is shared by the PAM configurations of SSH and `sudo`.
In production, it is more practical to use separate policy packages for each PAM configuration.
-We have not defined the SSH _authz_ policy to work with elevation, so you can enter any value
+The SSH _authz_ policy has not been defined to work with elevation, so you can enter any value
into the prompt that comes up for SSH.
For `sudo`, enter the ticket number `1234` to get access.
@@ -418,13 +415,11 @@ opa build -b .
You will find that running `sudo ls /` as the `frontend-dev` user is disallowed again.
It is possible to configure the _display_ policy to only make the PAM module prompt for the
-elevation ticket when our mock API has a non-empty `tickets` object. So when there are no
+elevation ticket when the mock API has a non-empty `tickets` object. So when there are no
elevated users, there will be no prompt for a ticket. This can be done using the Rego
[`count` aggregate](./policy-reference/builtins/aggregates).
-## Wrap Up
-
-Congratulations for finishing the tutorial!
+## Summary
You learned a number of things about SSH with OPA:
diff --git a/docs/docs/style-guide.md b/docs/docs/style-guide.md
index 5e44d562df..eb93220531 100644
--- a/docs/docs/style-guide.md
+++ b/docs/docs/style-guide.md
@@ -10,10 +10,10 @@ The purpose of this style guide is to provide a collection of recommendations an
[Rego](https://www.openpolicyagent.org/docs/policy-language).
From the maintainers of [Open Policy Agent](https://www.openpolicyagent.org) (OPA),
and some of the most experienced members of the community,
-we hope to share lessons learnt from authoring and reviewing hundreds of thousands of lines of Rego over the years.
+this guide shares lessons learnt from authoring and reviewing hundreds of thousands of lines of Rego over the years.
-With new features, language constructs, and other improvements continuously finding their way into OPA, we aim to keep
-this style guide a reflection of what we consider current best practices. Make sure to check back every once in a while,
+With new features, language constructs, and other improvements continuously finding their way into OPA, the goal is to keep
+this style guide a reflection of current best practices. Make sure to check back every once in a while,
and see the changelog for updates since your last visit.
## Regal
@@ -186,7 +186,7 @@ Regal rule. Get started with [Regal, the Rego linter](/projects/regal).
### Optionally, use leading underscore for rules intended for internal use
-While OPA doesn't have "private" rules or functions, a pretty common convention that we've seen in the community is to
+While OPA doesn't have "private" rules or functions, a pretty common convention in the community is to
use a leading underscore for rules and functions that are intended to be internal to the package that they are in:
```rego
@@ -304,14 +304,14 @@ deny contains "User is anonymous" if input.user_id == "anonymous"
At first glance, it might seem obvious that evaluating the rule should add a violation to the set of messages if the
`user_id` provided in `input` is equal to "anonymous". But what happens if there is no `user_id` provided _at all_?
Evaluation will stop when encountering undefined, and the comparison will never be invoked, leading to **nothing**
-being added to the `deny` set β the rule allows someone without a `user_id`. We could of course add another
+being added to the `deny` set β the rule allows someone without a `user_id`. One option is to add another
rule, checking only for its presence:
```rego
deny contains "User ID missing from input" if not input.user_id
```
-This is nice in that we'll get an even more granular message returned to the caller, but quickly becomes tedious when
+This provides an even more granular message returned to the caller, but quickly becomes tedious when
working with a large set of input data. To deal with this, a helper rule using _negation_ may be used.
**Prefer**
@@ -324,8 +324,8 @@ authenticated_user if input.user_id != "anonymous"
```
In the above case, the `authenticated_user` rule will fail **both** in the the undefined case, and if defined
-but equal to "anonymous". Since we negate the result of the helper rule in the `deny` rule, we'll have both
-cases covered.
+but equal to "anonymous". Since the result of the helper rule is negated in the `deny` rule, both
+cases are covered.
#### Related Resources
@@ -502,8 +502,7 @@ my_rule if {
}
```
-While this could be alleviated by declaring `some user` before the iteration, we can't take that consideration for
-granted when reading code from someone else.
+While this could be alleviated by declaring `some user` before the iteration, that assumption cannot be taken for granted when reading code from someone else.
**Avoid**
```rego
@@ -1074,7 +1073,7 @@ Regal rule. Get started with [Regal, the Rego linter](/projects/regal).
## Contributing
This document is meant to reflect the style preferences and best practices as compiled by the OPA community. As such,
-we welcome contributions from any of its members. Since most of the topics in a guide like this are likely subject to
+contributions from community members are welcome. Since most of the topics in a guide like this are likely subject to
discussion, please open an issue, and allow some time for people to comment, before opening a PR.
If you'd like to add or remove items for your own company, team or project, forking this repo is highly encouraged!
diff --git a/docs/docs/terraform.md b/docs/docs/terraform.md
index 15371ce242..28503ec66d 100644
--- a/docs/docs/terraform.md
+++ b/docs/docs/terraform.md
@@ -446,7 +446,7 @@ Here is the expected contents of `tfplan.json`.
}
```
-The JSON plan output produced by terraform contains a lot of information. For this tutorial, we will be interested by:
+The JSON plan output produced by terraform contains a lot of information. For this tutorial, the relevant fields are:
- `.resource_changes`: array containing all the actions that terraform will apply on the infrastructure.
- `.resource_changes[].type`: the type of resource (e.g. `aws_instance` , `aws_iam` ...)
@@ -595,7 +595,7 @@ opa exec --decision terraform/analysis/authz --bundle policy/ tfplan.json
```
If you're curious, you can ask for the score that the policy used to make the authorization decision.
-In our example, it is 11 (10 for the creation of the auto-scaling group and 1 for the creation of the server).
+In this example, it is 11 (10 for the creation of the auto-scaling group and 1 for the creation of the server).
```shell
opa exec --decision terraform/analysis/score --bundle policy/ tfplan.json
@@ -696,7 +696,7 @@ In addition to loading policies from the local filesystem, `opa exec` can fetch
opa build policy/
```
-Next, serve the bundle via NGINX:
+Next, serve the bundle via Nginx:
```bash
docker run --rm --name bundle_server -d -p 8888:80 -v ${PWD}:/usr/share/nginx/html:ro nginx:latest
@@ -711,9 +711,7 @@ opa exec --decision terraform/analysis/authz \
tfplan_large.json
```
-## Wrap Up
-
-Congratulations for finishing the tutorial!
+## Summary
You learned a number of things about Terraform Testing with OPA:
@@ -805,7 +803,7 @@ terraform show -json tfplan.binary > tfplan2.json
The policy evaluates if a security group is valid based on the contents of it's description:
- Resources can be specified under the root module or in child modules
-- We want to evaluate against the combined group of these resources
+- The policy evaluates against the combined group of these resources
- This example is scoped to the planned changes section of the JSON representation
The policy uses the walk keyword to explore the json structure, and uses conditions to filter for the specific paths where resources would be found.
@@ -904,9 +902,7 @@ This should return one of the two resources. The security group created by the m
}
```
-## Module Wrap Up
-
-Congratulations on finishing the tutorial!
+## Summary
You learned OPA can be used to determine if a proposed configuration is authorized.
diff --git a/docs/docs/v0-compatibility.md b/docs/docs/v0-compatibility.md
index b074a8d05d..58a5ba7482 100644
--- a/docs/docs/v0-compatibility.md
+++ b/docs/docs/v0-compatibility.md
@@ -19,7 +19,7 @@ feature set. Examples of when this applies:
- You run a service for customers who supply their own Rego.
- You use OPA as part of a managed platform and need to run a mix of v0.x and
- v1.0 OPAs based on customer demands.
+ v1.0 OPA instances based on customer demands.
Users with control over their Rego and OPA deployments are instead encouraged
to migrate their Rego to be compatible with OPA v1.0 using the below tooling options:
diff --git a/docs/docs/v0-upgrade/index.md b/docs/docs/v0-upgrade/index.md
index b43ff79854..3027f62fc6 100644
--- a/docs/docs/v0-upgrade/index.md
+++ b/docs/docs/v0-upgrade/index.md
@@ -55,7 +55,7 @@ working with in different parts of their systems. Select the scenario that best
matches your setup to find the recommended upgrade path.
If you are in doubt, [Scenario 1](#scenario-1-v0x-producer-v0x-consumer) is the most common starting
-point and we recommended you start there.
+point and is the recommended place to start.
| | v0.x Consumer | Mix Consumer | v1.0 Consumer |
| ----------------- | -------------------------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------- |
@@ -174,7 +174,7 @@ bundles. This upgrade path cannot continue until this is possible.
### Next
Upgrade producers to v1.0 and continue the upgrade from that point. Generally, it's recommended to
-upgrade producers first, however depending on your existing OPAs v1.0 consumers deployments, you may prefer to
+upgrade producers first, however depending on your existing v1.0 OPA consumer deployments, you may prefer to
upgrade all your producers to v1.0 rather than to downgrade consumers.
### Scenario 5: Mix Producer, Mix Consumer
@@ -201,7 +201,7 @@ Please gradually upgrade producers to v1.0 until all producers are v1.0 ([Scenar
### Scenario 6: v1.0 Producer, Mix Consumer
All consumers can be run without flags, as the bundle will contain
-attributes to inform v1.0 OPAs to accept v0.x modules.
+attributes to inform v1.0 OPA instances to accept v0.x modules.
#### How to Run
@@ -222,7 +222,7 @@ the next and final step.
### Scenario 7: v0.x Producer, v1.0 Consumer
All consumers are v1.0, but producers are v0.x. This scenario might occur when
-OPAs used for evaluation are upgraded before the policy bundling system.
+OPA instances used for evaluation are upgraded before the policy bundling system.
#### Pre-requisites
@@ -268,10 +268,10 @@ Upgrade producers to v1.0 ([Scenario 9](#scenario-9-v10-producer-v10-consumer)),
Once you have all consumers and producers running at v1.0 then you have
completed the upgrade to OPA v1.0. If you are using `--v0-compatible`
-functionality, the next task is to upgrade the Rego loaded into OPAs to Rego v1.
+functionality, the next task is to upgrade the Rego loaded into OPA instances to Rego v1.
-Regardless of whether you are now upgrading your Rego, we encourage users to
-use `opa check`, `opa check --strict` and to lint their Rego projects if you
+Regardless of whether you are now upgrading your Rego, run `opa check`,
+`opa check --strict` and lint your Rego projects if you
have not already done so to identify issues.
## Changes to Rego in OPA v1.0
diff --git a/docs/docs/wasm.md b/docs/docs/wasm.md
index 02f3c9b941..959463edd7 100644
--- a/docs/docs/wasm.md
+++ b/docs/docs/wasm.md
@@ -16,7 +16,7 @@ As described on [https://webassembly.org/](https://webassembly.org/)
OPA is able to compile Rego policies into executable Wasm modules that can be
evaluated with different inputs and external data. This is _not_ running the OPA
-server in Wasm, nor is this just cross-compiled Golang code. The compiled Wasm
+server in Wasm, nor is this just cross-compiled Go code. The compiled Wasm
module is a planned evaluation path for the source policy and query.
## Current Status
@@ -79,7 +79,7 @@ API that produces OPA bundle files. The compile API is recommended.
There is a JavaScript SDK available that simplifies the process of loading and
evaluating compiled policies. If you want to evaluate Rego policies inside
-JavaScript we recommend you use the
+JavaScript, it is recommended to use the
[Javascript SDK](https://github.com/open-policy-agent/npm-opa-wasm).
There is also an
[example NodeJS application](https://github.com/open-policy-agent/npm-opa-wasm/tree/main/examples/nodejs-app)
@@ -312,7 +312,7 @@ heap pointer. The calling convention is as follows:
and clear any memory left from `eval` or `opa_eval` calls.
2. Call `opa_heap_blocks_restore` to reinstate the heap stashed heap memory.
3. Call `opa_malloc`/`opa_json_parse`/`opa_free` to create the "path" and
- "value" arguments (in WASM value form) as usual.
+ "value" arguments (in Wasm value form) as usual.
4. Call `opa_value_add_path` or `opa_value_remove_path` as usual.
5. Call `opa_value_free` on the "path" argument to release it as usual.
6. Call `opa_heap_blocks_stash` to stash any free heap blocks to
@@ -334,9 +334,9 @@ to `eval` or `opa_eval`. But that memory was never truly available for
queries in the first place. The very first call to `opa_heap_ptr_set`
(either before `eval` or which `opa_eval` calls internally) resets the heap
and leaks any free blocks on the heap. In versions of the ABI prior to
-1.3 this memory was simply lost. Note, however, that multiple queries
+1.3 this memory was lost. Note, however, that multiple queries
would not continue to leak memory since they would always reset the heap
-pointer to the same value. The WASM engine would only leak further
+pointer to the same value. The Wasm engine would only leak further
memory if there were subsequent calls to `opa_value_add_path` or
`opa_value_remove_path` followed by more queries. ABI 1.3 introduced the
calling convention using `opa_heap_blocks_stash` and
@@ -378,5 +378,5 @@ Sets are represented as JSON arrays.
## Ecosystem Projects
-Wasm is a great way to integrate OPA into applications where the Go SDK is unavailable.
+Wasm can be used to integrate OPA into applications where the Go SDK is unavailable.
diff --git a/docs/projects/regal/index.md b/docs/projects/regal/index.md
index 85afc50c29..e264f55777 100644
--- a/docs/projects/regal/index.md
+++ b/docs/projects/regal/index.md
@@ -286,10 +286,11 @@ Documentation: https://www.openpolicyagent.org/projects/regal/rules/style/prefer
-> **Note**
-> If you're running Regal on an existing policy library, you may want to disable the `style` category initially, as it
-> will likely generate a lot of violations. You can do this by passing the `--disable-category style` flag to
-> `regal lint`.
+:::note
+If you're running Regal on an existing policy library, you may want to disable the `style` category initially, as it
+will likely generate a lot of violations. You can do this by passing the `--disable-category style` flag to
+`regal lint`.
+:::
### Using Regal in Your Editor
diff --git a/docs/projects/regal/pre-commit-hooks.md b/docs/projects/regal/pre-commit-hooks.md
index d80022dfc1..ee7e4e31a8 100644
--- a/docs/projects/regal/pre-commit-hooks.md
+++ b/docs/projects/regal/pre-commit-hooks.md
@@ -48,7 +48,7 @@ Runs Regal against all staged `.rego` files, aborting the commit if any fail.
Runs Regal against all staged `.rego` files, aborting the commit if any fail.
-- Downloads the latest `regal` binary from Github.
+- Downloads the latest `regal` binary from GitHub.
### `regal-fix`
@@ -77,4 +77,4 @@ Same as `regal-fix`, but uses the `regal` binary already on `$PATH`.
Same as `regal-fix`, but downloads the latest `regal` binary from GitHub instead of building or relying on `$PATH`.
-- Downloads the latest `regal` binary from Github.
+- Downloads the latest `regal` binary from GitHub.
diff --git a/docs/src/data/ecosystem/entries/opa-wasm-rust.md b/docs/src/data/ecosystem/entries/opa-wasm-rust.md
index 38fbfbd924..5b5d456913 100644
--- a/docs/src/data/ecosystem/entries/opa-wasm-rust.md
+++ b/docs/src/data/ecosystem/entries/opa-wasm-rust.md
@@ -20,4 +20,4 @@ docs_features:
'
---
-A crate to use OPA policies compiled to WASM.
+A crate to use OPA policies compiled to Wasm.
diff --git a/docs/src/data/ecosystem/entries/opa-wasm-zig.md b/docs/src/data/ecosystem/entries/opa-wasm-zig.md
index 10c36eeab6..427f8d5244 100644
--- a/docs/src/data/ecosystem/entries/opa-wasm-zig.md
+++ b/docs/src/data/ecosystem/entries/opa-wasm-zig.md
@@ -19,4 +19,4 @@ docs_features:
'
---
-A Zig library to use OPA policies compiled to WASM.
+A Zig library to use OPA policies compiled to Wasm.
diff --git a/docs/src/data/ecosystem/features/opa-bundles-discovery.md b/docs/src/data/ecosystem/features/opa-bundles-discovery.md
index c632c8f7bc..4afadd7cef 100644
--- a/docs/src/data/ecosystem/features/opa-bundles-discovery.md
+++ b/docs/src/data/ecosystem/features/opa-bundles-discovery.md
@@ -1,6 +1,6 @@
---
title: Discovery Bundles
-description: Distribute flexible configuration to OPAs
+description: Distribute flexible configuration to OPA instances
category: production
---
diff --git a/docs/src/pages/_examples/app/intro.md b/docs/src/pages/_examples/app/intro.md
index c3d3eeb086..29f82b7c06 100644
--- a/docs/src/pages/_examples/app/intro.md
+++ b/docs/src/pages/_examples/app/intro.md
@@ -1,5 +1,5 @@
-Applications can directly integrate with OPA using our
+Applications can directly integrate with OPA using the
[SDKs](./ecosystem) or [REST API](./docs/rest-api). This is great when your
application needs to make domain specific runtime decisions.