# How to Set Up Project-Specific Pack Configurations in dcg

> Learn to set up project specific pack configurations in dcg by creating a .dcg.toml file. Enable disable custom paths for destructive command guards in your repository.

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

---

**Create a [`.dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg.toml) file in your repository root with a `[packs]` table containing `enabled`, `disabled`, and optional `custom_paths` arrays to control which destructive command guards are active for that specific project.**

The `dcg` (Destructive Command Guard) tool from the Dicklesworthstone/destructive_command_guard repository uses a layered configuration system to determine which safety packs are active. Setting up project-specific pack configurations in dcg allows teams to customize protection levels per repository, enabling database guards for backend projects while disabling irrelevant filesystem warnings for documentation sites.

## Understanding the Pack Configuration Structure

At the heart of the system lies the **`PacksConfig`** struct defined in [`src/config.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/config.rs). This structure manages how the tool discovers and filters command guards through three primary fields:

- **`enabled`** – A vector of pack IDs or category prefixes to activate.
- **`disabled`** – A vector of pack IDs or categories to explicitly deactivate, overriding any `enabled` entries.
- **`custom_paths`** – Glob patterns pointing to external YAML pack files specific to your project, user, or system.

```rust
pub struct PacksConfig {
    pub enabled: Vec<String>,
    pub disabled: Vec<String>,
    #[serde(default)]
    pub custom_paths: Vec<String>,
}

```

According to the source code in [`src/config.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/config.rs) (lines 1343-1365), dcg merges built-in packs with external packs discovered via `custom_paths`. The loader implements a **fail-open** policy: malformed YAML files are logged but do not abort the entire configuration, ensuring that a syntax error in one custom pack does not break your entire safety net.

## Configuration Hierarchy and Precedence

When dcg initializes, it resolves the final pack list by merging multiple sources in strict priority order, as implemented in [`src/config.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/config.rs) (lines 6-14). Higher priority sources override lower ones:

- **CLI flags** – `dcg --packs …` takes highest precedence.
- **Environment variables** – `DCG_PACKS` and `DCG_DISABLE`.
- **Explicit file path** – `DCG_CONFIG=/path/to/config.toml`.
- **Project config** – [`.dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg.toml) in the repository root.
- **User config** – `~/.config/dcg/config.toml`.
- **System config** – [`/etc/dcg/config.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main//etc/dcg/config.toml).
- **Compiled defaults** – Built-in fallback settings.

The **[`.dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg.toml)** file in your project root is the primary mechanism for project-specific pack configurations in dcg, sitting between user preferences and command-line overrides.

## Creating the Project Configuration File

To enable or disable packs for a single repository, create a [`.dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg.toml) file at the root and add a `[packs]` table. This approach keeps security policies version-controlled alongside your codebase.

```toml
[packs]

# Enable whole categories or individual sub-packs

enabled = [
    "database.postgresql",   # all PostgreSQL database commands

    "kubernetes",           # every kubernetes.* sub-pack

    "windows.filesystem",   # Windows-specific filesystem guard

]

# Turn off a sub-pack while keeping its category enabled

disabled = [
    "kubernetes.helm",      # we allow Helm by accident, disable it here

]

```

As documented in [`docs/configuration.md`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/configuration.md), the `enabled` field accepts category prefixes (enabling all sub-packs) or specific pack IDs, while `disabled` acts as a denylist that removes packs even if their parent category is enabled.

## Loading External Project-Specific Packs

For bespoke rules not covered by built-in packs, use the **`custom_paths`** field to reference project-local YAML files. The path may contain `${repo_root}`, which resolves to the nearest directory containing a `.git` folder, ensuring portability across different checkouts.

```toml
[packs]
enabled = ["mycompany.custom"]          # the pack ID defined inside the YAML

custom_paths = ["${repo_root}/.dcg/packs/*.yaml"]

```

Place your custom pack definition at [`.dcg/packs/mycompany.yaml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg/packs/mycompany.yaml) using the schema defined in [`docs/pack.schema.yaml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/docs/pack.schema.yaml):

```yaml
schema_version: 1
id: mycompany.custom
name: MyCompany Custom Pack
version: 1.0.0
description: Project-specific dangerous commands
destructive_patterns:
  - name: prod-deploy
    pattern: deploy\s+--env\s*=?\s*prod
    severity: critical
    description: Direct production deployment
    explanation: |
      Production deployments must go through CI/CD. Use the pipeline instead.
safe_patterns:
  - name: staging-deploy
    pattern: deploy\s+--env\s*=?\s*(staging|dev)
    description: Non-production deployments are allowed

```

The external loader in [`src/packs/external.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/external.rs) processes these files during startup, expanding globs and validating syntax before merging the patterns into the active guard set.

## Overriding Packs via Environment Variables

For CI pipelines or temporary testing, you can toggle packs without modifying the TOML file. The **`DCG_PACKS`** variable adds to the enabled list, while **`DCG_DISABLE`** removes packs regardless of other settings.

```bash

# Enable a pack, disable another

DCG_PACKS="database.postgresql,windows.filesystem" DCG_DISABLE="windows.filesystem" dcg scan .

```

This is particularly useful in continuous integration environments where you might enable the `cloud.aws` pack for infrastructure jobs while keeping it disabled for application code repositories.

## Validating Custom Pack Configurations

Before committing new rules, validate your external YAML files using the built-in validator. This command checks syntax, required fields (`id`, `schema_version`, `destructive_patterns` or `safe_patterns`), regex compilation, and duplicate pattern names.

```bash
dcg pack validate path/to/mycompany.yaml

```

As implemented in [`src/packs/external.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/external.rs) and exposed via [`src/cli.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/cli.rs), validation errors abort loading for that specific file, while warnings are printed but allow the pack to load. This fail-open behavior ensures that one invalid custom pack does not prevent the tool from guarding against other destructive commands.

## Summary

- **Project-specific configurations** reside in [`.dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg.toml) at the repository root, overriding user and system settings but yielding to CLI flags and environment variables.
- The **`PacksConfig`** struct in [`src/config.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/config.rs) defines three key fields: `enabled`, `disabled`, and `custom_paths` for controlling pack activation.
- Use **`custom_paths`** with `${repo_root}` placeholders to load project-local YAML packs containing custom destructive and safe patterns.
- **Environment variables** `DCG_PACKS` and `DCG_DISABLE` provide temporary overrides ideal for CI/CD pipelines.
- Run **`dcg pack validate`** against external YAML files to catch syntax errors and invalid regex patterns before deployment.

## Frequently Asked Questions

### What is the difference between enabled and disabled in dcg pack configuration?

The **`enabled`** field specifies which packs or categories to activate, while **`disabled`** explicitly removes packs from the final set even if they appear in `enabled` or are active by default. According to the `enabled_pack_ids()` method in [`src/config.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/config.rs) (lines 65-89), the resolution logic starts with the enabled list, subtracts any disabled IDs or categories, then injects core packs like `core` and `system.disk` unless explicitly disabled.

### Can I use wildcards when specifying pack IDs?

You can use **category prefixes** as wildcards. For example, enabling `"kubernetes"` automatically includes all sub-packs like `kubernetes.helm` and `kubernetes.kubectl`. However, you cannot use glob characters like `*` within the `enabled` or `disabled` arrays themselves; use the `custom_paths` field with glob patterns to load external YAML files instead.

### Where should I place custom YAML pack files in my project?

Store custom packs anywhere within your repository and reference them via **`custom_paths`** in [`.dcg.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg.toml). A common convention is to place them in `.dcg/packs/*.yaml` and use the `${repo_root}` placeholder in your configuration to ensure the paths resolve correctly regardless of where the repository is cloned.

### How does dcg handle invalid external pack files?

The loader in [`src/packs/external.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/packs/external.rs) implements a **fail-open** strategy. If a YAML file contains syntax errors or fails validation, dcg logs the error but continues loading other packs and the built-in defaults. This prevents a malformed project-specific pack configuration from accidentally disabling all command guards.