How to Configure Project-Specific Pack Configurations in dcg
Create a .dcg.toml file in your repository root with a [packs] table containing enabled, disabled, and custom_paths arrays to define which destructive command guards are active for that specific project.
The dcg (Destructive Command Guard) tool uses a layered configuration system that allows repositories to define project-specific pack configurations. By placing a .dcg.toml file at your project root, you can override user and system defaults, enable specific protection packs like database.postgresql or kubernetes, and even load custom YAML rule files local to the repository. This approach ensures that dangerous command patterns are tailored to your project's specific technology stack and deployment workflows.
Understanding the Configuration Hierarchy
dcg merges configuration from multiple sources, with later sources overriding earlier ones. According to src/config.rs (lines 6-14), the priority from highest to lowest is:
- CLI flags (e.g.,
dcg --packs …) - Environment variables (
DCG_PACKS,DCG_DISABLE) - Explicit file path (
DCG_CONFIG=/path/to/config.toml) - Project config (
.dcg.tomlin the repository root) - User config (
~/.config/dcg/config.toml) - System config (
/etc/dcg/config.toml) - Compiled defaults (built-in hardcoded values)
This hierarchy means that a .dcg.toml file in your project root will override the user and system configuration files, but can itself be overridden by environment variables or command-line flags.
Creating a Project-Level Configuration File
To configure project-specific pack configurations, create a file named .dcg.toml at the root of your repository. The [packs] table in this file controls which protection packs are active.
The PacksConfig struct defined in src/config.rs (lines 1343-1365) supports three fields:
pub struct PacksConfig {
pub enabled: Vec<String>,
pub disabled: Vec<String>,
#[serde(default)]
pub custom_paths: Vec<String>,
}
A minimal project configuration looks like this:
[packs]
enabled = ["core", "database.postgresql", "kubernetes"]
disabled = ["kubernetes.helm"]
Enabling and Disabling Packs for Your Project
The enabled array accepts pack IDs or category prefixes. When you enable a category like kubernetes, all sub-packs (e.g., kubernetes.kubectl, kubernetes.helm) are included. The disabled array removes specific packs even if their parent category is enabled.
Example configuration:
[packs]
enabled = [
"database.postgresql",
"kubernetes",
"windows.filesystem",
]
disabled = [
"kubernetes.helm",
]
This enables all PostgreSQL database guards and Kubernetes protections, but explicitly disables Helm commands while keeping other Kubernetes checks active.
Loading External Project-Local Packs
For rules specific to your project that aren't covered by built-in packs, use the custom_paths field to load external YAML pack files. According to src/packs/external.rs, these paths support glob patterns and the ${repo_root} variable, which resolves to the nearest directory containing a .git folder.
Configuration example:
[packs]
enabled = ["mycompany.custom"]
custom_paths = ["${repo_root}/.dcg/packs/*.yaml"]
Place your custom pack definition at .dcg/packs/mycompany.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 loader is fail-open: malformed YAML files are logged but do not abort the entire configuration.
How Pack Resolution Works
When dcg determines which packs to activate, it calls enabled_pack_ids() in src/config.rs (lines 65-89). This method:
- Starts with the IDs listed in
enabled - Removes any IDs listed in
disabledand any sub-packs whose prefix matches a disabled category - Automatically inserts the
corepack - Adds the
system.diskpack unless explicitly disabled - On Windows, adds
windows.filesystemandwindows.systemunless disabled
You can verify the final active packs by running:
dcg packs enabled
Validating Custom Packs
Before distributing a custom pack to your team, validate it using the built-in validator:
dcg pack validate path/to/mycompany.yaml
This command checks YAML syntax, required fields (id, schema_version, destructive_patterns or safe_patterns), regex compilation, and duplicate pattern names. Errors abort loading, while warnings are printed but allow the pack to load.
Summary
- Project-specific pack configurations in
dcgare defined in a.dcg.tomlfile at your repository root - The configuration hierarchy prioritizes CLI flags and environment variables over project, user, and system configs
- Use the
[packs]table withenabledanddisabledarrays to control which protection categories are active - Load custom YAML rule files via
custom_pathsusing glob patterns and the${repo_root}variable - The
enabled_pack_ids()function insrc/config.rsresolves the final set of active packs by merging defaults, explicit enables, and disabled entries - External packs are loaded fail-open: malformed files are logged but don't crash the application
Frequently Asked Questions
Can I disable the core pack in my project configuration?
Yes, though not recommended. You can add "core" to the disabled array in your .dcg.toml, but the enabled_pack_ids() method in src/config.rs automatically re-inserts it unless explicitly removed via the disabled list. Note that disabling core removes fundamental protections against common destructive patterns like rm -rf /.
What happens if my custom YAML pack file has syntax errors?
dcg uses a fail-open approach implemented in src/packs/external.rs. Malformed YAML files are logged as warnings but do not abort the entire configuration loading process. Other valid packs will still load and protect against destructive commands.
How do environment variables interact with project-specific configurations?
Environment variables override project configuration. According to the hierarchy in src/config.rs, DCG_PACKS and DCG_DISABLE take precedence over .dcg.toml settings. This is useful for CI pipelines where you might need to temporarily adjust pack behavior without modifying committed files.
Can I use relative paths without the ${repo_root} variable in custom_paths?
While you can specify relative paths, using ${repo_root} ensures the configuration works correctly regardless of the directory from which dcg is invoked. The variable resolves to the nearest parent directory containing a .git folder, making it the safest choice for project-specific pack configurations that need to reference files within the repository.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →