Allow-Once Short Code Bypass vs Permanent Allowlist Entries in DCG: A Technical Comparison

The allow-once short code bypass provides a temporary 24-hour exemption for a single blocked command using a 6-digit numeric code, while permanent allowlist entries create durable, rule-based exemptions stored in TOML configuration files that persist indefinitely across sessions.

The dcg (Destructive Command Guard) open-source project by Dicklesworthstone implements a two-tiered authorization system for managing destructive shell commands. Understanding the distinction between these allow-once short code bypasses and permanent allowlist entries is essential for administrators balancing security with operational flexibility.

How Allow-Once Short Code Bypasses Work

The allow-once mechanism creates temporary exemptions without modifying configuration files. When dcg blocks a command, it generates a 6-digit short code derived from a SHA-256/HMAC hash of the blocked command record.

In src/pending_exceptions.rs, the short_code_from_hash function generates this code from the pending exception data. The system writes a pending-exception record to pending_exceptions.jsonl, displaying the code to the user. Running dcg allow-once <code> converts this into an active entry stored in allow_once.jsonl.


# Command is blocked and generates a short code

$ echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard HEAD"}}' | dcg
{
  "hookSpecificOutput": {
    "permissionDecision":"deny",
    "allowOnceCode":"834921"
  }
}

# Grant exemption for 24 hours

$ dcg allow-once 834921
✅ Allow-once entry created – expires in 24 h

The AllowOnceEntry struct in src/pending_exceptions.rs tracks three critical properties:

  • scope_kind: Defines whether the exemption applies to the current working directory (Cwd) or the entire project (Project)
  • single_use: When set to true, the entry is consumed and removed immediately after the first matching command execution
  • force_allow_config: Allows the bypass to override configuration-based blocklists when set via the --force CLI flag

By default, entries expire after EXPIRY_HOURS = 24 as defined in src/pending_exceptions.rs. The system logs each lifecycle event—issuance, resolution, consumption, and expiration—via structured AllowOnceLogEntry records handled by the log_allow_once_event function.

How Permanent Allowlist Entries Work

Permanent allowlist entries provide durable authorization through TOML configuration files. Unlike the transient allow-once system, these entries are stored in .dcg/allowlist.toml (project-level), ~/.config/dcg/allowlist.toml (user-level), or /etc/dcg/allowlist.toml (system-level).

The allowlist module in src/allowlist.rs parses these files, which contain rule-IDs (e.g., core.git:reset-hard) identifying specific command patterns. Each entry includes an optional reason and expiration date parsed via allowlist::parse_duration.


# Add a permanent rule to the project allowlist

$ dcg allowlist add core.git:reset-hard --project
✅ Rule core.git:reset-hard added to .dcg/allowlist.toml

# Verify the configuration

$ cat .dcg/allowlist.toml
[[allow]]
rule = "core.git:reset-hard"
reason = "Admins approve resetting history"

During execution, the evaluator consults the allowlist after the safe-pattern whitelist but before the destructive-pattern blacklist. This evaluation order allows allowlist entries to short-circuit deny decisions globally, regardless of the current working directory.

Key Differences in Scope and Persistence

Temporary vs Indefinite Lifetime

Allow-once entries operate on a 24-hour expiration window by default, or until consumed if marked as single_use. Permanent allowlist entries persist indefinitely until manually removed or until an explicit expiration timestamp is reached.

Scoped vs Global Application

The allow-once system respects scope boundaries through AllowOnceScopeKind::Cwd or AllowOnceScopeKind::Project as stored in the scope_path field. Permanent entries apply globally across all directories once loaded from the TOML configuration.

Audit Trail Variations

Allow-once events generate detailed structured logs through src/pending_exceptions.rs, tracking the full lifecycle of each short code. Permanent allowlist matches appear in the JSON hook output under the "allowlist" field within TraceDetails handling in src/trace.rs, but do not generate per-use audit logs unless specifically configured.

When to Use Each Mechanism

Use the allow-once short code bypass for emergency situations requiring immediate execution of a blocked command without modifying project configuration. This is ideal for one-time operations like git reset --hard HEAD~5 that you do not want to permanently whitelist.

Use permanent allowlist entries for command patterns that have been security-vetted and require regular execution. For example, if git clean -n commands are deemed safe for your workflow, adding core.git:clean-n to the allowlist prevents repeated interruption without manual code entry.

Summary

  • Allow-once short codes provide temporary 24-hour exemptions generated via short_code_from_hash in src/pending_exceptions.rs, stored in allow_once.jsonl, and scoped to specific directories or projects.
  • Permanent allowlist entries are rule-based configurations stored in TOML files parsed by src/allowlist.rs, applying globally and persisting indefinitely until manually removed.
  • Allow-once entries support single-use consumption and forced override of config blocks; permanent entries are always reusable and evaluated after safe-patterns but before destructive-patterns.
  • Use short codes for occasional emergency bypasses; use permanent allowlists for repetitive, pre-approved command patterns.

Frequently Asked Questions

How long does an allow-once short code remain valid?

Allow-once short codes remain valid for 24 hours by default, as defined by the EXPIRY_HOURS = 24 constant in src/pending_exceptions.rs. If the entry was created with the single_use flag set to true, it expires immediately after the first matching command execution, regardless of the time elapsed.

Can I convert an allow-once exemption into a permanent allowlist entry?

No direct conversion mechanism exists within the CLI. To make a temporary exemption permanent, you must manually add the corresponding rule-ID to your TOML allowlist using dcg allowlist add <rule-id>. The rule-ID corresponds to the pattern identifier used by the matching engine (e.g., core.git:reset-hard), which you can identify from the blocked command output or logs.

What happens if both an allowlist entry and a blocklist rule exist for the same command?

According to the evaluation logic in dcg, the allowlist is consulted after the safe-pattern whitelist but before the destructive-pattern blacklist. This means a permanent allowlist entry will override a blocklist rule, allowing the command to execute. However, an allow-once entry will not override a config-based blocklist unless the force_allow_config flag is explicitly set to true via the --force CLI option.

Where are the allow-once entries stored compared to permanent allowlist rules?

Allow-once entries are stored in allow_once.jsonl and pending_exceptions.jsonl within the dcg data directory, managed by PendingExceptionStore in src/pending_exceptions.rs. Permanent allowlist rules reside in TOML configuration files (.dcg/allowlist.toml, ~/.config/dcg/allowlist.toml, or /etc/dcg/allowlist.toml) and are parsed by the allowlist module in src/allowlist.rs.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →