v2.62.0

Access Guard

Mark the paths an AI agent must never read, or never write β€” and have every C3 surface enforce it. Two glob lists in your project (or global) config, one evaluator, refusals that tell the agent exactly why and what to do instead.

deny β€” no read, no write read_only β€” no write tighten-only v2.62.0+

What this is β€” and is not. Access Guard protects a cooperative agent against mistakes and prompt-injection: an agent that names a protected path gets a firm, reasoned refusal at every C3 surface. It is not a sandbox β€” it governs file actions invoked through C3's tools and hooks, but does not isolate raw OS processes or external editors. See Coverage for exactly where each layer holds.

Quick start

1

Add a rule

UI β†’ project β†’ Access Guard tab β†’ Add rule, or:

c3 access add "secrets/**" --kind deny
2

Test a path

Use the tab's Test path probe, or:

c3 access check secrets/key.txt
3

Let it work

Agent attempts on protected paths return [c3-access:denied] refusals that name the rule and tell the agent not to retry.

Rules & semantics

Rules live in the access section of .c3/config.json (project scope) and ~/.c3/config.json (global scope):

{
  "access": {
    "deny":      ["secrets/**", "*.pem"],
    "read_only": ["docs/legal/**", "migrations/**"]
  }
}
Rule kindReadWrite / create / deleteAppears in search?
denyβœ—βœ—βœ— (never listed or hinted)
read_onlyβœ“ (unless another rule denies)βœ—βœ“

Built-in protections (always on)

These apply in every C3 project, with no configuration, and cannot be overridden. If the access config is corrupt or unparseable, that scope fails closed β€” everything in it is denied until fixed.

PathsProtectionWhy
**/.env*denySecrets never enter agent context
.c3/secrets.enc Β· .c3/cred_state.jsondenyCredential vault sidecars
.c3/** Β· ~/.c3/**write-denyConfig self-tampering (incl. access rules + credential registry)
.claude/settings*.jsonwrite-denyHook/permission self-modification
.git/**write-denygit hooks are a code-execution vector (reads stay open)
C3 install directorywrite-denyAgent self-modification (installed layouts only)
*.pem Β· id_rsa* Β· *.keydefault ruleSeeded in global scope β€” visible and removable, unlike builtins

Refusal messages

Every denial carries a stable machine tag, the matched rule and scope, and explicit no-retry guidance β€” so the agent pivots instead of retry-looping or silently recreating "missing" files.

TagMeaning
[c3-access:denied]Operation refused by a deny rule (or a write refused where read_only applies via hooks). Policy, not an error β€” the agent is told not to retry or route around it.
[c3-access:read_only]Write refused; reads remain separately evaluated.
[c3-access:limited]Search/listing footer: results may omit protected paths β€” a file that doesn't appear may still exist.
[c3-access:error]The enforcement hook itself failed β€” native write tools are denied until it loads (fail-closed). See Troubleshooting.

Coverage β€” honest limits

Enforced: C3 MCP tools (any agent that uses C3 β€” Claude Code, Codex, Gemini, Oracle-connected models) Β· Claude Code native tools (PreToolUse hooks, fail-closed) Β· c3_shell (best-effort command scan, advisory).

Not enforced: a non-Claude agent's raw shell or direct file APIs β€” including native file tools in non-Claude CLI environments unless they route through C3 tools β€” external editors, and OS-level access. Renames/moves via shell commands are a known v1 gap. Access Guard is a guardrail for cooperative agents β€” pair it with OS permissions when you need a real boundary.

CLI commands

c3 access list                        # rules by scope, builtins included
c3 access add "secrets/**" --kind deny            # project scope
c3 access add "*.pem" --kind deny --global        # global scope
c3 access remove "secrets/**" --kind deny
c3 access check secrets/key.txt                   # probe: verdict + matched rule
c3 access check docs/x.md --op write

UI tab & probe

Each project's UI gains an Access Guard tab: rules grouped by scope (builtins shown locked), an add-rule form, delete with typed confirmation for deny rules, and a Test path probe that shows the verdict, matched rule, and the exact refusal the agent would see. The coverage matrix above is pinned at the bottom of the tab.

Troubleshooting

[c3-access:error] on every write The access hook failed to load β€” this is fail-closed by design. Check .c3/hook_errors.log, rerun c3 install-mcp. C3 MCP tools keep working meanwhile.
Everything in a scope denied That scope's access section is corrupt or has an unknown key. Fix the JSON; c3 access list names the scope.
Expected file "missing" in search Check c3 access check <path> β€” deny rules remove files from search entirely (deny-enumerate).
Rule not matching Globs are POSIX-style: use forward slashes; remember * does not cross directories β€” use **. Probe with c3 access check.

Relationship to the Credential Vault. Credentials protect values (never in agent context, injected at the subprocess boundary); Access Guard protects files and folders. The vault's registry and sidecars are covered by Access Guard builtins, and both systems log every mutation to the same edit ledger.