Skip to content

bug(guardrails): .env.example reads blocked despite opencode.json explicitly allowing them #142

@terisuke

Description

@terisuke

Bug Report

Summary

guardrail.ts プラグインが .env.example ファイルの読み取りをブロックします。opencode.json では "*.env.example": "allow" と明示的に許可しているにもかかわらず。

Root Cause

Two locations in packages/guardrails/profile/plugins/guardrail.ts are affected:

1. sec regex (L5):

const sec = [
  /(^|\/)\.env($|\.)/i,  // matches .env.example because .env. satisfies \.env\.
]

2. bash command check (L642):

if (has(file, sec) || file.includes(".opencode/guardrails/")) {
  throw new Error(text("shell access to protected files"))
}

file here is the full command string, so cat backend/.env.example is matched by the sec pattern.

This produces two distinct error messages:

  • Read tool: Guardrail policy blocked this action: secret material is outside the allowed read surface
  • Bash tool: Guardrail policy blocked this action: shell access to protected files

Conflict with opencode.json

packages/guardrails/profile/opencode.json already expresses the correct intent:

"read": {
  "*.env": "deny",
  "*.env.*": "deny",
  "*.env.example": "allow"
}

The plugin fires in tool.execute.before before permission evaluation, so the config allowlist is never reached.

Impact

Agents investigating Docker/service configurations cannot read .env.example template files. This slows down legitimate debugging workflows unnecessarily.

Proposed Fix

Option A — Narrow the sec regex with a negative lookahead:

/(^|\/)\.env($|\.)(?!example)/i

Option B — Add an early return in deny() and the bash check:

function deny(file: string, kind: "read" | "edit") {
  const item = rel(input.worktree, file)
  if (item.endsWith(".env.example")) return  // template files are safe
  if (kind === "read" && has(item, sec)) return "secret material is outside the allowed read surface"
  ...
}

The same exception must be applied to the bash command check at L642.

Steps to Reproduce

  1. Enable the guardrails profile in opencode
  2. Ask an agent to read backend/.env.example or run cat backend/.env.example
  3. Observe: Guardrail policy blocked this action

Environment

  • File: packages/guardrails/profile/plugins/guardrail.ts
  • Config: packages/guardrails/profile/opencode.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions