> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kosli.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.kosli.com/feedback

```json
{
  "path": "/labs/lab-05-runtime-controls",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Lab 5: Runtime Controls

> Create environments, snapshot what's running in production, and enforce compliance policies.

<Info>
  **Prerequisites**: Complete [Lab 4: Release Controls](/labs/lab-04-release-controls) before starting this lab.
</Info>

## Learning goals

* Understand Kosli Environments and how they track runtime state
* Create a Kosli Environment representing your deployment target
* Snapshot a Docker environment to report what's running
* Create and configure compliance Policies
* Attach Policies to Environments for enforcement
* Integrate environment snapshotting into your CI/CD pipeline

## Introduction

**Kosli Environments** allow you to track what's actually running in your runtime environments (dev, staging, production). By taking regular **snapshots**, Kosli creates an immutable record of:

* What artifacts are running, identified by their SHA256 digest
* When they started and stopped
* Whether they comply with your policies
* The complete change history over time

**Policies** define compliance requirements for environments — rules like "all artifacts must have provenance", "all artifacts must have passed unit tests", or "all artifacts must have an SBOM".

Together, Environments and Policies give you runtime visibility and enforcement for your software supply chain.

### Environment types

Kosli supports several environment types:

| Type     | Tracks                        |
| -------- | ----------------------------- |
| `docker` | Docker containers on a host   |
| `k8s`    | Kubernetes pods in namespaces |
| `ecs`    | AWS ECS tasks                 |
| `lambda` | AWS Lambda functions          |
| `s3`     | Files in S3 buckets           |
| `server` | Files on a server filesystem  |

See [Environments](/getting_started/environments) for more.

## Exercise

<Steps>
  <Step title="Create an environment">
    Your application deploys as a Docker container, so create a `docker` type environment:

    ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
    kosli create environment labs-prod \
      --type docker \
      --description "Production environment for labs application"

    # Verify it was created
    kosli get environment labs-prod
    ```

    Visit [app.kosli.com](https://app.kosli.com) → **Environments** and you should see `labs-prod` listed (with no snapshots yet).

    See [`kosli create environment`](/client_reference/kosli_create_environment) for full flag reference.
  </Step>

  <Step title="Explore an existing environment">
    To see a real-world example, navigate to the [Cyber-Dojo AWS Beta environment](https://app.kosli.com/cyber-dojo/environments/aws-beta/snapshots/).

    Here you can see a history of snapshots taken from a production AWS environment. Each snapshot shows:

    * **Running artifacts**: Container images currently running
    * **Compliance status**: Whether they meet policy requirements
    * **Events**: What started or stopped since the last snapshot
    * **Duration**: How long the application has been running

    <Tip>
      Each snapshot is immutable. If nothing changed since the last snapshot, Kosli won't create a new one — only real changes produce new snapshots.
    </Tip>
  </Step>

  <Step title="Integrate snapshotting into CI">
    In `.github/workflows/full-pipeline.yaml`, add this step to the `Deploy` job **after** the "Deploy to production" step:

    ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
        - name: Snapshot environment
          run: kosli snapshot docker labs-prod
    ```

    This captures what's running immediately after deployment.
  </Step>

  <Step title="Create a compliance policy">
    Create `.kosli-policy.yml` in the root of your repository:

    ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
    _schema: https://docs.kosli.com/schemas/policy/v1

    artifacts:
      provenance:
        required: true  # All artifacts must be part of a Flow

      attestations:
        - name: unit-tests
          type: junit
        - name: sbom
          type: "*"  # Any attestation type
    ```

    This policy requires:

    1. All running artifacts must have been attested to Kosli (provenance)
    2. All artifacts must have JUnit test results
    3. All artifacts must have an SBOM

    Then create the policy in Kosli:

    ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
    kosli create policy labs-prod-requirements .kosli-policy.yml

    # View it
    kosli get policy labs-prod-requirements
    ```

    See [`kosli create policy`](/client_reference/kosli_create_policy) and [Policies](/getting_started/policies) for more details.
  </Step>

  <Step title="Attach the policy to your environment">
    ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
    kosli attach-policy labs-prod-requirements --environment labs-prod

    # Verify attachment
    kosli get environment labs-prod
    ```

    <Tip>
      Attaching a policy automatically triggers a new snapshot evaluation. Kosli immediately checks if currently running artifacts meet the requirements.
    </Tip>

    See [`kosli attach-policy`](/client_reference/kosli_attach-policy) for full flag reference.
  </Step>

  <Step title="Add policy management to CI">
    In the `Deploy` job, add these steps **before** the "Assert compliance" step:

    ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
        - name: Update policy
          run: kosli create policy labs-prod-requirements .kosli-policy.yml
        - name: Attach policy to environment
          run: kosli attach-policy labs-prod-requirements --environment labs-prod
    ```
  </Step>

  <Step title="Push and verify">
    ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
    git add .kosli-policy.yml .github/workflows/full-pipeline.yaml
    git commit -m "Add Kosli environment and policy management"
    git push origin main
    ```

    Watch the workflow execute. After it completes, in [app.kosli.com](https://app.kosli.com):

    * Navigate to **Environments → labs-prod** → latest snapshot
    * Check the compliance status — it should be <Badge color="green">Compliant</Badge>, since you've been attesting unit tests and SBOM since Lab 3
    * Click on the running artifact to see which attestations are present

    <Accordion title="If your artifact is non-compliant">
      - Verify the attestation names in your workflow match the names in `.kosli-policy.yml` exactly
      - Check that all attestation steps completed successfully in the previous workflow run
      - Confirm the artifact fingerprint matches what was attested
    </Accordion>
  </Step>
</Steps>

<Accordion title="Optional: policy enforcement gate">
  You can also use policies as deployment gates, preventing non-compliant artifacts from deploying:

  ```bash theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
  # Assert against specific policies before deployment
  kosli assert artifact ghcr.io/${IMAGE}:latest \
    --policy labs-prod-requirements
  ```

  If the artifact is non-compliant, this command exits with a non-zero status, failing the deployment step.

  See [`kosli assert artifact`](/client_reference/kosli_assert_artifact) for more details.
</Accordion>

<Accordion title="Optional: policy expressions">
  Policies support conditional logic for sophisticated compliance rules:

  ```yaml theme={"theme":"dracula","languages":{"custom":["/languages/rego.json"]}}
  artifacts:
    attestations:
      # Only require security scans for production flow
      - if: ${{ flow.name == "production" }}
        name: security-scan
        type: snyk

      # Exceptions for specific artifacts
      - name: unit-tests
        type: junit
        exceptions:
          - if: ${{ artifact.name == "legacy-component" }}
  ```

  See [Policy expressions](/policy-reference/environment_policy#policy-expressions) for more.
</Accordion>

## Verification checklist

* [ ] `labs-prod` environment of type `docker` created
* [ ] Explored the Cyber-Dojo environment in Kosli
* [ ] `.kosli-policy.yml` created with compliance requirements
* [ ] Policy created in Kosli and attached to the environment
* [ ] Workflow updated with policy update and snapshot steps
* [ ] Workflow runs successfully
* [ ] Environment snapshots visible in Kosli
* [ ] Running artifact shows as <Badge color="green">Compliant</Badge>

## Congratulations!

You've completed all five Kosli Learning Labs. You now know how to:

1. Set up Kosli and integrate it with a CI/CD pipeline
2. Create Flows and Trails to track your software delivery process
3. Attest artifacts and attach evidence (tests, SBOMs, scans)
4. Define compliance requirements and gate releases
5. Create environments, track what's running, and enforce policies

You have full visibility and control over your software supply chain, from build to deployment.

## Explore further

* [Custom attestation types](/getting_started/attestations) for your specific tools
* [Kubernetes environment reporting](/tutorials/report_k8s_envs) if you use K8s
* [Approvals](/getting_started/approvals) for production deployment workflows

**Further reading:**

* [Environments](/getting_started/environments)
* [Policies](/getting_started/policies)
