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

# Policy as Code Overview

> Version-control and automate Charley policy deployment via CLI and Python SDK

## What is Policy as Code?

Policy as Code (PaC) lets you define Charley security policies in YAML files, store them in Git, and deploy them automatically through CI/CD — the same way teams manage infrastructure as code.

Instead of clicking through the dashboard, you declare policies in files, preview diffs before applying, and have a full audit trail in git history.

```
charley/
├── groups.yaml
└── policies/
    ├── global.yaml      # org-wide baseline
    ├── finance.yaml     # finance group overrides
    └── engineering.yaml # engineering group overrides
```

## Why Use It?

| Dashboard                  | Policy as Code                              |
| -------------------------- | ------------------------------------------- |
| Point-and-click, immediate | Declared in code, reviewed in PRs           |
| No audit trail beyond logs | Every change is a git commit                |
| Per-session changes        | Idempotent apply — same input = same result |
| Manual rollback            | `git revert` to any prior state             |
| Good for one-offs          | Scales to hundreds of groups and devices    |

## How It Works

The `agent-charley-cli` CLI (and Python SDK) communicate with the Charley API using an **API key** — separate from your dashboard login. On each run:

1. **Plan** — fetch current server state, diff against local files, print what would change
2. **Apply** — apply the diff, skipping unchanged policies

Policies are idempotent: running `apply` twice produces the same result as running it once.

## Scope Hierarchy

Policies merge from broadest to most specific:

```
global (org-wide)  →  group  →  device
```

Only the fields you explicitly set in a narrower scope override the broader scope. Unset fields fall through.

## Getting Started

<CardGroup cols={2}>
  <Card title="Install & First Policy" icon="terminal" href="/policy-as-code/getting-started">
    Install the CLI and deploy your first policy in 5 minutes
  </Card>

  <Card title="API Keys" icon="key" href="/policy-as-code/authentication">
    Create and manage API keys for the CLI and SDK
  </Card>

  <Card title="Policy Reference" icon="book" href="/policy-as-code/policy-reference">
    Full reference for all policy types and fields
  </Card>

  <Card title="Examples" icon="copy" href="/policy-as-code/examples">
    Ready-to-use templates for common setups
  </Card>
</CardGroup>

## CI/CD Integration

The most common setup runs `plan` on pull requests and `apply` on merge to main:

```yaml theme={null}
# .github/workflows/charley.yml
on:
  pull_request:
    paths: ['charley/**']
  push:
    branches: [main]
    paths: ['charley/**']

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install charley_policy-0.1.0-py3-none-any.whl
      - run: agent-charley-cli plan --file charley/policies/ --groups charley/groups.yaml
        env:
          CHARLEY_API_KEY: ${{ secrets.CHARLEY_API_KEY_RO }}

  apply:
    if: github.ref == 'refs/heads/main'
    needs: plan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install charley_policy-0.1.0-py3-none-any.whl
      - run: agent-charley-cli apply --file charley/policies/ --groups charley/groups.yaml --prune -y
        env:
          CHARLEY_API_KEY: ${{ secrets.CHARLEY_API_KEY }}
```

Use a `read_only` key (`ck_ro_...`) for the plan step and a `read_write` key (`ck_live_...`) for the apply step.
