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

# Declarative Resource Management

> Manage compliance resources as code using YAML definitions and the Chainloop CLI.

<Note>
  This feature is only available on Chainloop's platform [paid plans](https://chainloop.dev/pricing).
</Note>

## Overview

Chainloop lets you manage compliance resources declaratively by defining them as YAML files and applying them via the CLI. This GitOps-friendly approach means you can:

* **Version-control** resource definitions alongside your code
* **Review changes** through pull requests before they take effect
* **Automate** resource management in CI/CD pipelines
* **Reproduce** configurations across environments

All resources follow a Kubernetes-style schema with `apiVersion`, `kind`, `metadata`, and `spec` fields. Apply operations are idempotent—if a resource with the same name already exists, it is updated; otherwise, a new one is created.

## Supported Resources

| Kind          | Description                                         |
| ------------- | --------------------------------------------------- |
| `Framework`   | Groups requirements into compliance frameworks      |
| `Requirement` | Defines policies and manual proofs for compliance   |
| `Policy`      | Custom policy with Rego rules                       |
| `PolicyGroup` | Reusable group of related policies                  |
| `Contract`    | Workflow contract defining attestation expectations |

For full details on each resource type, see [Compliance Frameworks](/concepts/compliance-frameworks), [Policies](/concepts/policies), [Policy Groups](/concepts/policy-groups), and [Contracts](/concepts/contracts).

## Getting Started

Before you begin, make sure you have:

* **Chainloop CLI Enterprise Edition** installed - see the [CLI installation guide](/command-line-reference/cli-installation)
* **Authenticated** to your organization - run `chainloop auth login`

This walkthrough builds a complete compliance-as-code setup from scratch around an SBOM license-compliance use case. Each step builds on the previous one - by the end you'll have a policy, a policy group, a requirement, a framework, and a contract that all work together.

The steps below apply each resource individually so you can verify as you go. In practice, you can place all your YAML files in a single directory and apply them at once with `chainloop apply -f ./compliance/` - Chainloop resolves dependencies automatically. See [Applying Resources at Scale](#applying-resources-at-scale).

## Step 1 - Write a Policy

A **policy** contains the Rego rules that Chainloop evaluates against your attestation materials. Start by defining one that checks CycloneDX SBOMs for components missing license information.

Create `cyclonedx-licenses.yaml`:

```yaml theme={"dark"}
apiVersion: workflowcontract.chainloop.dev/v1
kind: Policy
metadata:
  name: cyclonedx-licenses
  description: Checks for components without licenses
  annotations:
    category: sbom
spec:
  policies:
    # kind determines which material type this policy evaluates
    - kind: SBOM_CYCLONEDX_JSON
      # Rego code inline - you can also use `ref` to point to an external .rego file
      embedded: |
        package main

        import rego.v1

        valid_input if {
          count(input.components) > 0
        }

        violations contains msg if {
          some comp in input.components
          not comp.licenses
          msg := sprintf("Missing license for %s", [comp.purl])
        }
```

Apply and verify:

```bash theme={"dark"}
chainloop policy apply --file cyclonedx-licenses.yaml
chainloop policy describe --name cyclonedx-licenses
```

<Tip>
  For the full Rego development workflow - scaffolding, linting, testing, and iterating on policies - see [How to write custom policies](/guides/custom-policies).
</Tip>

## Step 2 - Group Policies Together

A **policy group** bundles related policies into a reusable unit. Let's create one that groups the `cyclonedx-licenses` policy from Step 1 with another SBOM policy to form a complete SBOM quality check.

Create `sbom-quality-group.yaml`:

```yaml theme={"dark"}
apiVersion: workflowcontract.chainloop.dev/v1
kind: PolicyGroup
metadata:
  name: sbom-quality
  description: >-
    SBOM quality policies - checks that SBOMs contain
    license and dependency information.
  annotations:
    category: sbom
spec:
  inputs:
    - name: bannedLicenses
      description: Comma-separated list of licenses to ban (e.g., AGPL-1.0-only)
      # default provides a fallback when the caller doesn't supply a value
      default: ""
  policies:
    # attestation policies run against the envelope itself
    attestation:
      - ref: sbom-present
    # materials policies run against individual attached artifacts
    materials:
      - policies:
          # The custom policy from Step 1
          - ref: cyclonedx-licenses
          # A built-in policy that ships with Chainloop
          - ref: sbom-banned-licenses
            with:
              licenses: "{{ inputs.bannedLicenses }}"
```

The group includes the `cyclonedx-licenses` policy you just created alongside `sbom-banned-licenses`, a built-in policy that ships with Chainloop. The `attestation` section checks that an SBOM was included in the attestation; the `materials` section runs quality checks against the SBOM itself.

Apply and verify:

```bash theme={"dark"}
chainloop policy-group apply --file sbom-quality-group.yaml
chainloop policy-group describe --name sbom-quality
```

<Tip>
  For full details on policy group structure and capabilities, see [Policy Groups](/concepts/policy-groups).
</Tip>

## Step 3 - Define a Requirement

A **requirement** specifies what must be satisfied for compliance - which policies to evaluate, how often, and what manual evidence is needed. Let's create one that enforces license compliance by referencing the policy from Step 1.

Create `license-compliance.yaml`:

```yaml theme={"dark"}
apiVersion: chainloop.dev/v1
kind: Requirement
metadata:
  name: license-compliance
  displayName: License Compliance
  description: |
    All software artifacts must include license information
    and must not use banned licenses.
  annotations:
    categories: security, licensing
spec:
  policies:
    # The custom policy from Step 1
    - ref: cyclonedx-licenses
    # A built-in policy that ships with Chainloop
    - ref: sbom-banned-licenses
      # with passes parameters to the policy
      with:
        licenses: "AGPL-1.0-only,AGPL-3.0-only"
```

Requirements can also include `periodicity` (how often a policy is re-evaluated, e.g. `daily`, `weekly`), `sla` (grace period in hours before failures affect the compliance score), `group` (to organize policies into groups where any member passing satisfies the group), and `manual_proofs` for evidence that can't be automated (e.g., license review sign-offs). For the full schema, see [Compliance Frameworks](/concepts/compliance-frameworks).

Apply and verify:

```bash theme={"dark"}
chainloop requirement apply --file license-compliance.yaml
chainloop requirement describe --name license-compliance
```

## Step 4 - Build a Framework

A **framework** organizes requirements into a structured compliance program. You can group requirements into sections (and nested sub-sections) to model standards like CRA, SLSA, or your own internal policies. Let's build one that includes the requirement from Step 3.

Create `best-practices.yaml`:

```yaml theme={"dark"}
apiVersion: chainloop.dev/v1
kind: Framework
metadata:
  name: my-best-practices
  displayName: Best Practices
  description: Internal security and compliance best practices
spec:
  sections:
    - name: Source Code
      description: Source code integrity and secure development practices.
      requirements:
        # Built-in requirements that ship with Chainloop
        - ref: branch-protection
        - ref: code-review
    - name: Supply Chain
      description: Ensure software dependencies are properly licensed.
      requirements:
        # The custom requirement from Step 3
        - ref: license-compliance
```

This framework mixes built-in requirements (`branch-protection`, `code-review`) with the custom `license-compliance` requirement you created in Step 3. Chainloop ships with a library of built-in requirements and policies - your custom resources extend them.

Apply and verify:

```bash theme={"dark"}
chainloop framework apply --file best-practices.yaml
chainloop framework describe --name my-best-practices
```

<Note>
  Each requirement can only appear once in a framework - either at the root level or within a section, not both.
</Note>

## Step 5 - Tie It Together in a Contract

A **contract** defines the attestation expectations for a workflow - what materials to collect and which policies and policy groups to evaluate. This is where everything comes together: the contract references the policy group from Step 2, which in turn includes the policy from Step 1.

Create `example-contract.yaml`:

```yaml theme={"dark"}
apiVersion: chainloop.dev/v1
kind: Contract
metadata:
  name: example-contract
spec:
  policyGroups:
    # The policy group from Step 2 (which includes the policy from Step 1)
    - ref: sbom-quality
      with:
        bannedLicenses: AGPL-1.0-only,AGPL-3.0-only
```

When a workflow attests against this contract, Chainloop will check that an SBOM is present, verify every component has a license, and flag any banned licenses - all driven by the resources you built in the previous steps.

Apply and verify:

```bash theme={"dark"}
chainloop apply -f example-contract.yaml
chainloop contract describe --name example-contract
```

<Tip>
  For the full contract schema including material types and runner context, see [Contracts](/concepts/contracts).
</Tip>

## Applying Resources at Scale

The steps above apply resources one at a time. The `chainloop apply` command can handle any resource type, including multi-document YAML files and entire directories:

```bash theme={"dark"}
# Apply a single file (can contain multiple resources separated by ---)
chainloop apply -f compliance-resources.yaml

# Apply all YAML files in a directory
chainloop apply -f ./compliance/
```

<Note>
  When applying multiple resources, Chainloop processes them in dependency order: Policies, then Policy Groups, then Requirements, then Frameworks, then Contracts. Multi-document YAML files use `---` as the separator between resources.
</Note>

## Inspecting and Exporting Resources

After applying resources, you can verify them, explore what's deployed, and export definitions for backup or migration.

**Export** a resource as reusable YAML with the `--output schema` flag - useful for bootstrapping new configurations, backing up resources, or migrating between organizations:

```bash theme={"dark"}
chainloop policy describe --name cyclonedx-licenses --output schema
chainloop requirement describe --name license-compliance --output schema
chainloop framework describe --name my-best-practices --output schema
```

<Tip>
  Add `--output json` to any describe or list command for JSON output.
</Tip>

## Automating with CI/CD

Store your YAML resource definitions in a git repository and apply them automatically whenever changes are merged. This ensures compliance configurations are always up to date and auditable. You'll need an [API token](/reference/api-tokens) stored as a CI secret.

<Tabs>
  <Tab title="GitHub Actions">
    ```yaml theme={"dark"}
    name: Apply Compliance Resources
    on:
      push:
        branches: [main]
        paths: ['compliance/**']
    jobs:
      apply:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: Install Chainloop CLI
            run: curl -sfL https://dl.chainloop.dev/cli/install.sh | bash -s
          - name: Apply resources
            run: chainloop apply -f ./compliance/
            env:
              CHAINLOOP_TOKEN: ${{ secrets.CHAINLOOP_TOKEN }}
    ```
  </Tab>

  <Tab title="GitLab CI">
    ```yaml theme={"dark"}
    apply-compliance:
      stage: deploy
      script:
        - curl -sfL https://dl.chainloop.dev/cli/install.sh | bash -s
        - chainloop apply -f ./compliance/
      rules:
        - changes: [compliance/**]
      variables:
        CHAINLOOP_TOKEN: $CHAINLOOP_TOKEN
    ```
  </Tab>
</Tabs>
