# Custom Pack Authoring Guide This guide covers creating external YAML packs for dcg. Custom packs let you define organization-specific security policies without modifying the dcg binary. ## Quick Start 1. Create a pack file at `~/.config/dcg/packs/mycompany.yaml` 2. Define at least one pattern (safe or destructive) 3. Validate with `dcg pack validate ~/.config/dcg/packs/mycompany.yaml` 4. Restart dcg or reload config See `examples/packs/example.yaml` for a complete working example. ## Pack File Structure ```yaml # Required fields schema_version: 1 # Always use 1 (current version) id: mycompany.policies # namespace.name format name: MyCompany Security Policies # Human-readable name version: 1.0.0 # Your pack's semantic version # Optional fields description: | What this pack protects against. keywords: # Trigger evaluation (recommended) - mycommand - mytool destructive_patterns: # Patterns that block/warn - name: pattern-id pattern: regex-pattern severity: critical # critical/high/medium/low description: Short denial reason explanation: | # Optional detailed explanation Longer help text with alternatives. safe_patterns: # Patterns that explicitly allow - name: safe-pattern-id pattern: safe-regex-pattern description: Why this is allowed ``` ## Field Reference ### Required Pack Fields | Field | Type | Description | |-------|------|-------------| | `id` | string | Unique identifier in `namespace.name` format. Must match `^[a-z][a-z0-9_]*\.[a-z][a-z0-9_]*$` | | `name` | string | Human-readable pack name shown in messages | | `version` | string | Semantic version (`X.Y.Z`) for your own tracking | ### Optional Pack Fields | Field | Type | Default | Description | |-------|------|---------|-------------| | `schema_version` | integer | 1 | Schema version for forward compatibility | | `description` | string | none | What this pack protects against | | `keywords` | array | `[]` | Keywords that trigger pattern matching | | `destructive_patterns` | array | `[]` | Patterns that block or warn | | `safe_patterns` | array | `[]` | Patterns that explicitly allow | ### Destructive Pattern Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | yes | Stable identifier within the pack | | `pattern` | string | yes | fancy-regex pattern to match | | `severity` | string | no | `critical`, `high` (default), `medium`, `low` | | `description` | string | no | Short reason shown on denial | | `explanation` | string | no | Detailed explanation for verbose output | ### Safe Pattern Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | yes | Stable identifier within the pack | | `pattern` | string | yes | fancy-regex pattern to match | | `description` | string | no | Why this command is allowed | ## Severity Levels Severity determines the default action when a command matches: | Severity | Default Action | Use Case | |----------|---------------|----------| | `critical` | Always deny | Irreversible operations (rm -rf /, DROP DATABASE) | | `high` | Deny (allowlistable) | Dangerous but sometimes needed (force push, truncate) | | `medium` | Warn but allow | Worth noting but not blocking (large deletes) | | `low` | Log only | Learning/audit purposes | ## Keywords Best Practices Keywords gate pattern evaluation. Commands without any keywords skip the pack entirely, improving performance. **Do:** - Use specific, unambiguous keywords: `kubectl`, `terraform`, `mycompany-deploy` - Include common aliases if applicable: `k` for kubectl - Keep the list short (< 10 keywords) **Don't:** - Use single letters or common words: `a`, `run`, `do` - Include partial matches: `rm` instead of `rm -rf` - Omit keywords (forces evaluation on every command) ## Regex Pattern Guidelines Patterns use [fancy-regex](https://docs.rs/fancy-regex) syntax, which supports: - Standard regex: `\s`, `\w`, `.*`, `[a-z]+` - Lookahead: `(?=...)`, `(?!...)` - Lookbehind: `(?<=...)`, `(?