diff --git a/config/navigation.json b/config/navigation.json
index 6706c65..7a2fc64 100644
--- a/config/navigation.json
+++ b/config/navigation.json
@@ -26,6 +26,7 @@
"getting_started/attestations",
"getting_started/environments",
"getting_started/policies",
+ "getting_started/enforce_policies",
"getting_started/approvals"
]
},
diff --git a/getting_started/enforce_policies.md b/getting_started/enforce_policies.md
new file mode 100644
index 0000000..8b9f704
--- /dev/null
+++ b/getting_started/enforce_policies.md
@@ -0,0 +1,155 @@
+---
+title: "Enforce policies"
+description: "Block non-compliant artifacts from deploying by enforcing policies in CI/CD pipelines, via the API, or with Kubernetes admission controllers."
+icon: "shield-check"
+---
+
+Environment policies define what an artifact needs to be compliant. Policy enforcement gates check artifacts against those requirements and block deployments when they fall short.
+
+You can enforce policies:
+- As a **CI/CD pipeline step** that fails the build on non-compliance
+- Through the **Kosli API** for custom tooling
+- Via a **Kubernetes admission controller** that rejects non-compliant pods
+
+All methods use the same assertion: checking an artifact's fingerprint against an environment, specific policies, or a flow template.
+
+## Assertion scopes
+
+`kosli assert artifact` (and its API equivalent) supports four mutually exclusive scopes:
+
+| Scope | CLI flag | When to use |
+|-------|----------|-------------|
+| Environment | `--environment` | Check all policies attached to the target environment. The most common choice for deployment gates. |
+| Specific policies | `--policy` | Check one or more named policies, regardless of environment attachment. Useful for promotion gates between stages. |
+| Flow template | `--flow` | Check the artifact against a flow's template requirements. |
+| All flows | _(no scope flag)_ | Check against the templates of every flow the artifact appears in. |
+
+See [`kosli assert artifact`](/client_reference/kosli_assert_artifact) for the full flag reference.
+
+## Enforce in CI/CD pipelines
+
+Add `kosli assert artifact` as a step before your deployment step. If the artifact is non-compliant, the command exits with a non-zero status and the pipeline fails.
+
+### Assert against an environment
+
+Check all policies attached to the target environment:
+
+
+
+ ```yaml
+ - name: Assert artifact compliance
+ env:
+ KOSLI_API_TOKEN: ${{ secrets.KOSLI_API_TOKEN }}
+ KOSLI_ORG: my-org
+ run: |
+ kosli assert artifact ${{ env.IMAGE }} \
+ --artifact-type oci \
+ --environment production
+ ```
+
+
+ ```yaml
+ assert-compliance:
+ stage: deploy
+ script:
+ - kosli assert artifact $IMAGE \
+ --artifact-type oci \
+ --environment production
+ variables:
+ KOSLI_API_TOKEN: $KOSLI_API_TOKEN
+ KOSLI_ORG: my-org
+ ```
+
+
+
+### Assert against specific policies
+
+Check one or more named policies directly. This is useful when gating a promotion between stages or checking policies that are not attached to an environment:
+
+```shell
+kosli assert artifact $IMAGE \
+ --artifact-type oci \
+ --policy has-tests,has-review
+```
+
+
+Use `--dry-run` to test assertions without sending data to Kosli. The CLI prints the compliance result but always exits with code 0.
+
+
+## Enforce via the API
+
+For custom deployment tooling or non-CI contexts, call the assert endpoint directly:
+
+
+
+ ```shell
+ curl -s \
+ -H "Authorization: Bearer $KOSLI_API_TOKEN" \
+ "https://app.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?environment_name=production"
+ ```
+
+
+ ```shell
+ curl -s \
+ -H "Authorization: Bearer $KOSLI_API_TOKEN" \
+ "https://app.us.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?environment_name=production"
+ ```
+
+
+
+The response includes:
+- `compliant` — `true` or `false`
+- `policy_evaluations` — detailed results per policy (when asserting against an environment)
+- `compliance_status` — per-attestation compliance breakdown
+
+To assert against specific policies instead of an environment:
+
+
+
+ ```shell
+ curl -s \
+ -H "Authorization: Bearer $KOSLI_API_TOKEN" \
+ "https://app.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?policy_name=has-tests&policy_name=has-review"
+ ```
+
+
+ ```shell
+ curl -s \
+ -H "Authorization: Bearer $KOSLI_API_TOKEN" \
+ "https://app.us.kosli.com/api/v2/asserts/my-org/fingerprint/$SHA256?policy_name=has-tests&policy_name=has-review"
+ ```
+
+
+
+See the [Assert artifact API reference](/api-reference/asserts/assert-artifact) for the full response schema. You can also try it out directly in the API playground on that page.
+
+## Enforce with a Kubernetes admission controller
+
+A Kubernetes [validating admission webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) can call the Kosli assert API when a pod is created and reject pods whose images are non-compliant.
+
+The flow is:
+
+
+
+ Kubernetes calls your admission webhook before scheduling the pod.
+
+
+ The webhook reads the container image reference from the pod spec and resolves its SHA256 digest.
+
+
+ The webhook sends a request to the [assert endpoint](/api-reference/asserts/assert-artifact) with the fingerprint and the target environment name.
+
+
+ If `compliant` is `true`, the pod is admitted. If `false`, the webhook rejects the pod with a message explaining which policy requirements were not met.
+
+
+
+
+The [Kosli K8S Reporter](/helm/k8s_reporter) reports what is running in your Kubernetes environments to Kosli. Pair it with an admission controller to both enforce and monitor compliance.
+
+
+## What happens on failure
+
+**CLI:** A non-compliant artifact causes `kosli assert artifact` to exit with a non-zero code. CI/CD pipelines treat this as a failed step and stop the deployment. Use `--output json` to get machine-readable compliance details.
+
+**API:** The response body returns `compliant: false` with a `compliance_status` object describing which attestations are missing or non-compliant, and `policy_evaluations` listing per-policy results.
diff --git a/getting_started/policies.md b/getting_started/policies.md
index a8a96fb..766fde0 100644
--- a/getting_started/policies.md
+++ b/getting_started/policies.md
@@ -137,19 +137,6 @@ track snapshots, but its compliance cannot be evaluated without policies.
-## Policy Enforcement Gates
+## Enforcing policies
-Environment policies enable you to proactively block deploying a non-compliant artifact into an environment. This
-can be done as a deployment gate in your delivery pipeline or as an admission controller in your environment.
-
-Regardless of where you place your policy enforcement gate, it will be using the `assert artifact` Kosli CLI command
-or its equivalent API call.
-
-```shell
-kosli assert artifact --fingerprint=$SHA256 --environment=aws-production
-```
-
-An artifact can also be asserted directly against one or more policies.
-```shell
-kosli assert artifact --fingerprint=$SHA256 --policy=has-approval,has-been-integration-tested
-```
+Once policies are attached to environments, you can enforce them as deployment gates in your CI/CD pipeline, via the API, or with a Kubernetes admission controller. See [Enforce policies](/getting_started/enforce_policies) for setup instructions.