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

> Compare DCG's allow-once short code bypass and permanent allowlist entries. Understand temporary vs. durable exemptions for your destructive command guard.

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

---

**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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`.

```bash

# 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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg/allowlist.toml) (project-level), `~/.config/dcg/allowlist.toml` (user-level), or [`/etc/dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main//etc/dcg/allowlist.toml) (system-level).

The **allowlist** module in [`src/allowlist.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`.

```bash

# 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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/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`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/pending_exceptions.rs). Permanent allowlist rules reside in **TOML configuration files** ([`.dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/.dcg/allowlist.toml), `~/.config/dcg/allowlist.toml`, or [`/etc/dcg/allowlist.toml`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main//etc/dcg/allowlist.toml)) and are parsed by the allowlist module in [`src/allowlist.rs`](https://github.com/Dicklesworthstone/destructive_command_guard/blob/main/src/allowlist.rs).