# How Gogcli Implements Command Allowlisting for Sandboxed Agent Runs

> Learn how Gogcli implements command allowlisting for sandboxed agent runs. Secure your agent by controlling executable commands with flags or environment variables.

- Repository: [Peter Steinberger/gogcli](https://github.com/steipete/gogcli)
- Tags: internals
- Published: 2026-02-16

---

**Gogcli restricts which top-level commands can execute by validating a comma-separated allowlist from the `--enable-commands` flag or `GOG_ENABLE_COMMANDS` environment variable against the invoked command before any subcommand logic runs.**

Gogcli (steipete/gogcli) is a command-line interface for Google services that includes a robust sandboxing mechanism to limit agent capabilities. The **command allowlisting for sandboxing agent runs** feature ensures that automated processes, particularly those driven by LLM agents, can only invoke explicitly permitted top-level commands, preventing unauthorized access to sensitive functionality.

## The Allowlist Architecture

The allowlist system operates as a gatekeeper immediately after command-line parsing completes. It intercepts execution before any business logic runs, ensuring that disallowed commands fail fast with a clear error message.

The mechanism centers on three components:

- **Flag definition** in [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go) that captures user input
- **Parsing logic** in [`internal/cmd/enabled_commands.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/enabled_commands.go) that normalizes the allowlist
- **Enforcement function** that validates the active command against the parsed set

## How the Allowlist Works

### Flag Definition in the Root Command

The root CLI struct defines the `--enable-commands` flag with a default value pulled from the environment. In [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go), the field appears as:

```go
type CLI struct {
    EnableCommands string `help:"Comma-separated list of enabled top‑level commands (restricts CLI)" default:"${enabled_commands}"`
    // ... other fields
}

```

The default value `${enabled_commands}` resolves to the `GOG_ENABLE_COMMANDS` environment variable, allowing system administrators to set restrictions at the process level without modifying invocation scripts.

### Enforcement Point After Parsing

After Kong constructs the command context, `main` immediately invokes the enforcement check. The code in [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go) executes:

```go
if err = enforceEnabledCommands(kctx, cli.EnableCommands); err != nil {
    // Abort with usage error
    return err
}

```

This validation runs for **every** invocation, including those triggered by the agent helper commands, ensuring consistent sandboxing regardless of entry point.

### Parsing the Allowlist String

The `enforceEnabledCommands` helper delegates normalization to `parseEnabledCommands` in [`internal/cmd/enabled_commands.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/enabled_commands.go). This function:

1. Splits the input on commas
2. Trims whitespace and converts to lowercase
3. Stores valid entries in a `map[string]bool` for O(1) lookup

```go
func parseEnabledCommands(value string) map[string]bool {
    out := map[string]bool{}
    for _, part := range strings.Split(value, ",") {
        part = strings.TrimSpace(strings.ToLower(part))
        if part == "" {
            continue
        }
        out[part] = true
    }
    return out
}

```

### Decision Logic and Validation

The `enforceEnabledCommands` function implements the final authorization check:

```go
func enforceEnabledCommands(kctx *kong.Context, enabled string) error {
    if enabled == "" {
        return nil // No restriction
    }
    
    allowed := parseEnabledCommands(enabled)
    
    // Check for wildcard disable
    if allowed["*"] || allowed["all"] {
        return nil
    }
    
    // Extract top-level command
    top := strings.ToLower(strings.Fields(kctx.Command())[0])
    
    if !allowed[top] {
        return usagef("command %q is not enabled (set --enable-commands to allow it)", top)
    }
    
    return nil
}

```

This logic guarantees that **only the first word of the command line** is subject to validation, which is sufficient for sandboxing agent runs that typically invoke single top-level commands like `calendar`, `tasks`, or `gmail`.

### Integration with Agent Commands

The Agent subcommand defined in [`internal/cmd/agent.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/agent.go) inherits this protection automatically:

```go
type AgentCmd struct {
    ExitCodes AgentExitCodesCmd `cmd:"" name:"exit-codes" aliases:"exitcodes,exit-code" help:"Print stable exit codes for automation"`
}

```

Because agent commands flow through the same root parsing pipeline, they are subject to identical allowlist enforcement. An LLM-driven automation can be safely sandboxed by launching the CLI with a restrictive `--enable-commands` list that excludes potentially dangerous operations.

## Practical Configuration Examples

Restrict execution to calendar and tasks functionality only:

```bash
gog --enable-commands "calendar,tasks" calendar list

# ✅ succeeds

gog --enable-commands "calendar,tasks" gmail list

# ❌ error: command "gmail" is not enabled (set --enable-commands to allow it)

```

Configure via environment variable for persistent sandboxing:

```bash
export GOG_ENABLE_COMMANDS="calendar,tasks"
gog calendar list          # ✅ allowed

gog gmail list             # ❌ blocked

```

Allow agent execution while blocking other commands:

```bash
gog --enable-commands "agent" agent exit-codes

# ✅ succeeds, but other top-level commands are blocked

```

## Key Source Files

| File | Purpose |
|------|---------|
| [`internal/cmd/enabled_commands.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/enabled_commands.go) | Contains `parseEnabledCommands` and `enforceEnabledCommands` functions that implement the allowlist logic and validation |
| [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go) | Defines the `--enable-commands` flag, reads the `GOG_ENABLE_COMMANDS` environment variable, and invokes enforcement after Kong parsing |
| [`internal/cmd/agent.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/agent.go) | Defines the Agent command structure that inherits the same sandboxing protections |

## Summary

- Gogcli implements **command allowlisting** through the `--enable-commands` flag and `GOG_ENABLE_COMMANDS` environment variable
- The `enforceEnabledCommands` function in [`internal/cmd/enabled_commands.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/enabled_commands.go) validates commands immediately after Kong parsing completes
- Only **top-level commands** are validated against the allowlist, making it ideal for sandboxing agent runs
- Special values `"*"` and `"all"` disable restrictions entirely
- Agent commands automatically inherit these protections because they flow through the same root command pipeline

## Frequently Asked Questions

### What is command allowlisting in gogcli?

Command allowlisting in gogcli is a security mechanism that restricts which top-level commands can execute by validating the invoked command against a predefined set of permitted commands. This feature is implemented in [`internal/cmd/enabled_commands.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/enabled_commands.go) and enforced immediately after command-line parsing to prevent unauthorized access to CLI functionality, particularly useful when running automated agents.

### How do I configure the allowlist via environment variables?

Set the `GOG_ENABLE_COMMANDS` environment variable to a comma-separated list of allowed top-level commands before invoking gogcli. For example, `export GOG_ENABLE_COMMANDS="calendar,tasks"` restricts execution to only the calendar and tasks commands, while the `--enable-commands` flag can override this value for specific invocations.

### Can I disable the allowlist restriction entirely?

Yes, you can disable restrictions by including the special values `"*"` or `"all"` in your allowlist. When `enforceEnabledCommands` detects either of these values in the parsed allowlist map, it returns early without validation, effectively allowing all commands to execute regardless of the restriction settings.

### Does the allowlist affect agent subcommands?

Yes, agent subcommands inherit the same allowlist enforcement because they flow through the root command parsing pipeline defined in [`internal/cmd/root.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go). When sandboxing an agent run, you can restrict execution to only the `agent` top-level command, which prevents the agent from invoking other potentially dangerous operations like `gmail` or `calendar` modifications while still allowing agent-specific helpers like `agent exit-codes`.