How to Create Custom YAML Security Packs in dcg: A Complete Guide
Custom YAML security packs in dcg let you define command whitelists and blacklists using simple YAML files that the Destructive Command Guard loads at runtime to extend its protective rules.
The Dicklesworthstone/destructive_command_guard repository implements a flexible, file-driven rule system that allows you to version-control security policies and share them across teams. By authoring custom packs, you can tailor the guardrails to your specific toolchain—whether that means permitting benign Git operations or blocking catastrophic recursive deletions.
Understanding the Pack Schema
Before writing rules, review the formal specification in docs/pack.schema.yaml. This schema defines the mandatory structure that dcg validates during load time. A valid pack must declare metadata fields and two distinct pattern arrays that drive the evaluation pipeline.
Structuring Your Custom Pack
Create a new file ending in .yaml and populate it with the required top-level fields: id, name, description, and enabled. Beneath these, define safe_patterns (whitelist) and destructive_patterns (blacklist).
Pack Metadata
The metadata block identifies your collection and controls its activation:
id: A unique, dot-separated identifier (e.g.,custom.example).name: Human-readable title shown in CLI listings.description: Brief explanation of the pack’s purpose.enabled: Boolean toggle; set totrueto load by default.
Safe Patterns
Safe patterns act as a whitelist. If a command matches any entry here, dcg permits it immediately without further checks. Each entry requires:
rule_id: Stable unique identifier for the rule.regex: Fancy-Regex pattern to match against the normalized command string.description(optional): Context for why the command is considered safe.
Destructive Patterns
Destructive patterns form the blacklist. Matching commands trigger a denial response containing remediation guidance. Each entry requires:
rule_id: Unique identifier for tracking and auditing.regex: Fancy-Regex pattern to detect dangerous commands.reason: Human-readable explanation returned in the denial JSON.
Here is a complete example based on examples/packs/example.yaml:
id: custom.example
name: Example Pack
description: Demonstrates a user-defined pack.
enabled: true
safe_patterns:
- rule_id: custom.example:git-branch-create
regex: ^git\s+checkout\s+-b\s+\S+$
description: Allows creating a new Git branch.
destructive_patterns:
- rule_id: custom.example:git-reset-hard
regex: ^git\s+reset\s+--hard\b
reason: "git reset --hard discards uncommitted changes and rewrites history."
- rule_id: custom.example:rm-rf-home
regex: ^rm\s+-rf\s+~/?$
reason: "Recursive removal of the home directory is catastrophic."
Installation and Configuration
Once your YAML file is written, dcg must be told where to find it. The loader logic in src/config.rs resolves paths and registers packs with the evaluator.
Locating the Packs Directory
You have two registration options:
- Automatic discovery: Place your file in
~/.config/dcg/packs/. The engine loads every*.yamlfile in this directory automatically. - Explicit listing: Add the relative path to the
packs.enabledarray in~/.config/dcg/config.toml.
Registering in config.toml
Open your configuration file and append the pack filename:
[packs]
enabled = [
"custom.example.yaml",
# existing built-in packs …
]
After saving, verify registration by running dcg packs --verbose (command implemented in src/cli.rs). The output should list custom.example among active packs.
The Evaluation Pipeline
When dcg processes a command, patterns from your custom pack enter the evaluation pipeline defined in src/evaluator.rs:
- Quick-reject filter (
memchr) discards obvious non-matches to improve performance. - Normalization strips paths and expands aliases, standardizing the input string.
- Safe-pattern whitelist checks against your
safe_patterns. If matched, the command bypasses all further checks. - Destructive-pattern blacklist checks against your
destructive_patterns. If matched, dcg emits a JSON denial containing theruleId,reason, and remediation suggestions. - Default-allow permits any command that survives the above stages.
This ordering ensures that explicit allowances override blanket prohibitions, giving you fine-grained control.
Validation and Testing
Before deploying to production, validate your YAML against the official schema. While dcg performs runtime validation via Pack::from_yaml() (as seen in the loading sequence), catching syntax errors early prevents service interruptions.
Test your regex patterns against sample commands using the Fancy-Regex syntax. Remember that patterns are anchored implicitly against the normalized command string, so account for whitespace and argument ordering.
Summary
- Custom YAML security packs extend dcg’s protection by defining project-specific whitelists and blacklists.
- Schema compliance is enforced via
docs/pack.schema.yaml; every pack needs metadata plussafe_patternsanddestructive_patternsarrays. - Installation requires either dropping the file into
~/.config/dcg/packs/or listing it inconfig.toml, then verifying withdcg packs --verbose. - Evaluation order prioritizes safe patterns over destructive ones, with automatic fall-through for unmatched commands.
Frequently Asked Questions
What regex engine does dcg use for pattern matching?
dcg uses the Fancy-Regex engine, which supports Perl-compatible regular expressions with advanced features like look-aheads. Patterns are defined in the regex field of each rule entry and are evaluated against normalized command strings after path stripping and alias expansion.
Can I disable a built-in pack while keeping my custom pack active?
Yes. Edit ~/.config/dcg/config.toml and remove the built-in pack filename from the packs.enabled array, or set enabled: false inside the YAML file’s metadata block. The configuration loader in src/config.rs only registers packs explicitly marked as enabled.
How does dcg handle rule ID collisions?
Each ruleId must be unique across all loaded packs. If two packs define the same rule_id, the evaluator in src/evaluator.rs will encounter a collision during registration. Use dot-prefixed namespaces (e.g., company.team.rule-name) in your custom packs to avoid conflicts with built-in identifiers.
Where should I place pack files for team-wide distribution?
While ~/.config/dcg/packs/ is the default user directory, you can reference absolute paths in config.toml to load packs from shared network mounts or version-controlled repositories. This allows teams to maintain a centralized rule set that updates independently of the dcg binary.
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 →