# How to Create a Custom YAML Pack for dcg with Organization-Specific Security Rules

> Learn to create a custom YAML pack for dcg with organization-specific security rules. Define regex patterns, validate your pack, and integrate policies without modifying the binary.

- Repository: [Jeff Emanuel/destructive_command_guard](https://github.com/Dicklesworthstone/destructive_command_guard)
- Tags: how-to-guide
- Published: 2026-07-13

---

**You can create a custom YAML pack for dcg by defining destructive and safe regex patterns in a YAML file that conforms to the [`docs/pack.schema.yaml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/pack.schema.yaml) schema, validating it with `dcg pack validate`, and registering it in your `~/.config/dcg/config.toml` to integrate organization-specific security policies without modifying the binary.**

dcg (Destructive Command Guard) discovers security policies through *packs*—collections of regex patterns stored in YAML files. Creating a custom YAML pack for dcg allows you to embed organization-specific rules that protect deployment pipelines and cloud resources without touching the binary. When added to your configuration, dcg reads these packs at startup, validates them against the official schema in [`docs/pack.schema.yaml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/pack.schema.yaml), and integrates them into the evaluation pipeline while preserving the security guarantees of built-in packs.

## Understanding the Pack Structure and Schema

A valid pack file requires specific metadata fields and pattern definitions. According to the schema defined in [`docs/pack.schema.yaml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/pack.schema.yaml), every pack must declare `schema_version`, `id`, `name`, and `version` at minimum.

### Required and Optional Fields

The following fields define your pack's identity and behavior:

- **schema_version**: Must be `1` for the current specification
- **id**: Unique identifier using reverse-domain notation (e.g., `mycompany.security`)
- **name**: Human-readable description of the pack
- **version**: Semantic versioning string (e.g., `1.0.0`)
- **keywords**: List of strings triggering the quick-reject optimization
- **destructive_patterns**: Array of regex patterns that block commands
- **safe_patterns**: Array of regex patterns that explicitly allow commands

### Pattern Syntax and Severity

Each pattern in `destructive_patterns` or `safe_patterns` uses **fancy-regex** syntax, supporting look-ahead, look-behind, and back-references. Destructive patterns require a `severity` field (critical, high, medium, low) and should include an `explanation` field to guide users toward safer alternatives.

```yaml
destructive_patterns:
  - name: force-push-git
    pattern: \bgit\s+push\s+--force\b
    severity: critical
    description: Force-push can overwrite shared history
    explanation: Use `git push --force-with-lease` instead

```

## Validating and Loading Custom Packs

Before dcg integrates your pack into the evaluation pipeline, it validates the file structure and regex syntax to prevent runtime errors.

### The Validation Command

Run `dcg pack validate <path>` to verify your pack against the schema. This command parses the YAML, checks for ID collisions with built-in packs (such as `core.*` or `database.*`), and compiles each regex once to catch syntax errors early. The validator reports which regex engine (linear or backtracking) each pattern will use.

```bash
dcg pack validate ~/.config/dcg/packs/mycompany.yaml

```

Expected output includes the pack ID, pattern count, engine assignments, and a final validity confirmation.

### Configuration Integration

Valid packs load according to the order defined in your user configuration. Edit `~/.config/dcg/config.toml` or project-specific [`.dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg.toml) to include custom pack paths:

```toml
[packs]
custom_paths = [
  "~/.config/dcg/packs/*.yaml",
  ".dcg/packs/*.yaml",
  "/etc/dcg/packs/*.yaml"
]

```

As implemented in [`src/config.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/config.rs), external packs cannot override built-in packs, ensuring core security guarantees remain intact. The registry construction logic in [`src/packs/mod.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/mod.rs) enforces these collision rules during startup.

## Runtime Evaluation Logic

Understanding how dcg evaluates commands against your custom pack helps you optimize pattern design and keyword selection.

### Two-Pass Evaluation Strategy

When a command arrives, [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs) implements a two-pass evaluation system. First, dcg performs a **keyword quick-reject**—if the command contains no keywords from your pack, the entire pack is skipped. If keywords match, safe patterns are tried first; the first matching safe pattern **allows** the command immediately. If no safe patterns match, destructive patterns evaluate in order, and the first match **denies** the command with a JSON response containing the explanation text.

### Lazy Compilation for Performance

Following the architecture described in [`design-lazy-pack-registry.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/design-lazy-pack-registry.md), dcg employs lazy regex compilation. Only patterns actually needed for a specific command incur the cost of compilation. This design ensures that adding large organization-specific packs does not degrade startup performance or memory usage until those specific patterns are triggered.

## Step-by-Step: Building Your Organization Pack

Follow this workflow to deploy organization-specific security rules.

1. **Create the YAML file** at `~/.config/dcg/packs/mycompany.yaml` or your preferred location.

2. **Define metadata and patterns** using the structure from [`docs/custom-packs.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/custom-packs.md):

```yaml
schema_version: 1
id: mycompany.security
name: MyCompany Security Policies
version: 1.0.0
description: Organization-wide rules protecting deployment pipelines

keywords:
  - deploy
  - terraform
  - kubectl

destructive_patterns:
  - name: delete-s3-bucket
    pattern: \baws\s+s3\s+rm\s+--recursive\s+--force\b
    severity: high
    description: Irreversible deletion of S3 data
    explanation: Require approval workflow or use versioned buckets

safe_patterns:
  - name: tf-plan-ok
    pattern: \bterraform\s+plan\s+-out=.*\.tfplan\b
    description: Allows Terraform plan generation

```

3. **Validate the pack** using the CLI to catch schema violations:

```bash
dcg pack validate ~/.config/dcg/packs/mycompany.yaml

```

4. **Add to configuration** by updating `~/.config/dcg/config.toml` with the pack directory path.

5. **Test specific commands** before full deployment:

```bash
dcg test --pack-path ~/.config/dcg/packs/mycompany.yaml "git push --force origin master"

```

6. **Reload dcg** by restarting the daemon or rerunning the CLI to load the new pack into the evaluation flow.

## Summary

- **Custom YAML packs for dcg** let you define organization-specific security rules without modifying the binary.
- Packs must conform to the schema in [`docs/pack.schema.yaml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/pack.schema.yaml) with required fields `schema_version`, `id`, `name`, and `version`.
- Use `dcg pack validate` to check schema compliance and regex syntax before deployment.
- Configure pack paths in `~/.config/dcg/config.toml`; external packs load after built-in packs and cannot override them.
- Runtime evaluation uses keyword quick-reject and two-pass matching (safe patterns first, then destructive) as implemented in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs).
- Lazy compilation ensures only triggered patterns impact performance, following the design in [`design-lazy-pack-registry.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/design-lazy-pack-registry.md).

## Frequently Asked Questions

### What schema version does dcg require for custom packs?

dcg currently requires `schema_version: 1` as defined in [`docs/pack.schema.yaml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/pack.schema.yaml). This version supports the metadata fields, keyword lists, and pattern structures described in the official documentation. Future versions may extend the schema while maintaining backward compatibility for version 1 packs.

### Can custom packs override built-in packs like core or database packs?

No. As enforced in [`src/packs/mod.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/mod.rs), external packs cannot override built-in packs with IDs such as `core.*` or `database.*`. This restriction preserves the security guarantees of the core distribution while allowing your organization-specific rules to supplement the existing policy set.

### How does the keyword quick-reject optimization work?

The keyword quick-reject optimization filters commands before expensive regex evaluation. When processing a command, dcg checks if any keywords from your pack appear in the command string. If no keywords match, the entire pack is skipped. This optimization, detailed in [`src/evaluator.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/evaluator.rs), ensures that organization-specific packs for rare operations (like Terraform or kubectl) do not impact the performance of everyday shell commands.

### Which regex syntax does dcg support in pattern definitions?

dcg uses the **fancy-regex** crate, which supports Perl-compatible regular expressions plus advanced features like look-ahead, look-behind, and back-references. During validation, `dcg pack validate` reports whether each pattern uses the linear engine (fast, guaranteed linear time) or the backtracking engine (more expressive but potentially slower), helping you optimize performance-critical patterns.