<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>SecretSpec | Blog</title><description/><link>https://secretspec.dev/</link><language>en</language><item><title>SecretSpec 0.12: audit logs and coding agents</title><link>https://secretspec.dev/blog/secretspec-0-12-audit-logs-and-coding-agents/</link><guid isPermaLink="true">https://secretspec.dev/blog/secretspec-0-12-audit-logs-and-coding-agents/</guid><pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A coding agent reaches for the same secrets you do, but on its own initiative and
many times a session: a read looks identical whether it came from you running a
deploy or an agent exploring the codebase.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/cachix/secretspec/releases/tag/v0.12.0&quot; title=&quot;SecretSpec 0.12 release&quot;&gt;SecretSpec 0.12&lt;/a&gt;
makes that access accountable. It ships three things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Audit log&lt;/strong&gt; — every secret read and write is appended to a local,
per-user JSONL log. On by default. Values are never recorded.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reason-on-access&lt;/strong&gt; — secret access can require a human-readable reason,
enforced for coding agents by default.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;secretspec audit&lt;/code&gt; command&lt;/strong&gt; — filter and summarize the log, or pipe raw
JSON Lines to &lt;code dir=&quot;auto&quot;&gt;jq&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;aside aria-label=&quot;Behavior change in 0.12&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Behavior change in 0.12&lt;/p&gt;&lt;div&gt;&lt;p&gt;If you run SecretSpec inside a coding agent, secret access now &lt;strong&gt;fails&lt;/strong&gt; until a
reason is supplied. This is the new default (&lt;code dir=&quot;auto&quot;&gt;require_reason = &quot;agents&quot;&lt;/code&gt;). Opt
out with &lt;code dir=&quot;auto&quot;&gt;require_reason = false&lt;/code&gt; in the &lt;code dir=&quot;auto&quot;&gt;[project]&lt;/code&gt; table. Existing providers
and library callers keep working unchanged. See &lt;a href=&quot;#upgrading&quot;&gt;Upgrading&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;div&gt;&lt;h2 id=&quot;the-audit-log&quot;&gt;The audit log&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Every secret read and write, from the CLI and the Rust SDK, is appended to a
local log as &lt;a href=&quot;https://jsonlines.org/&quot;&gt;JSON Lines&lt;/a&gt;, one event per line. Secret
&lt;strong&gt;values are never written&lt;/strong&gt;, only metadata: the secret name, the profile, the
provider that served it (with any embedded credentials redacted), the outcome,
the reason, and who was asking, including the detected coding agent.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;v&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;ts&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;2026-06-04T17:04:00.893Z&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;action&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;project&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;my-app&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;profile&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;production&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;key&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;DATABASE_URL&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;provider&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;keyring://&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;outcome&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;found&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;reason&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;deploy web frontend&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;actor&quot;&lt;/span&gt;&lt;span&gt;: { &lt;/span&gt;&lt;span&gt;&quot;user&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;alice&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;agent&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;claude-code&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&quot;is_agent&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;version&quot;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;0.12.0&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The log lives in your per-user state directory
(&lt;code dir=&quot;auto&quot;&gt;~/.local/state/secretspec/audit.log&lt;/code&gt;) and is created readable only by you. Read
it with any tool, or use the new &lt;code dir=&quot;auto&quot;&gt;secretspec audit&lt;/code&gt; command for filtering and a
readable summary:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Last 20 entries, formatted&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;secretspec&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;audit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Only `run` events for one project&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;secretspec&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;audit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--project&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-app&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--action&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Raw JSON Lines, piped to jq&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;secretspec&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;audit&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;jq&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;select(.outcome == &quot;missing&quot;)&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;It is configured in your &lt;strong&gt;user-global config&lt;/strong&gt;
(&lt;code dir=&quot;auto&quot;&gt;~/.config/secretspec/config.toml&lt;/code&gt;), not the project’s &lt;code dir=&quot;auto&quot;&gt;secretspec.toml&lt;/code&gt;, so a
repository you clone can’t quietly turn off or redirect your audit log. The log is
a single file capped at 1 MiB, a size-bounded recent record rather than permanent
compliance history; forward it to a central system if you need that. To turn it
off entirely:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;~/.config/secretspec/config.toml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;[audit]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;enabled&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;See &lt;a href=&quot;https://secretspec.dev/concepts/audit/&quot;&gt;Audit Logging&lt;/a&gt; for the full record schema and options.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;supplying-a-reason&quot;&gt;Supplying a reason&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;When a coding agent like Claude Code reaches for a secret without a reason, the
access is refused and the agent is told exactly what to do next:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;$ secretspec run -- npm test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Error: Accessing secrets requires a reason. Provide one with --reason&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&quot;&amp;#x3C;why you are accessing these secrets&gt;&quot;, the SECRETSPEC_REASON environment&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;variable, or Secrets::with_reason() in the SDK. (Policy: require_reason in&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;[project] of secretspec.toml — defaults to &quot;agents&quot;; set it to false to&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;disable.)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Claude Code reads that message, states why it needs the secret, and retries:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;secretspec&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--reason&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;run the test suite before opening a PR&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Both the refusal and the successful retry land in the audit log, so the reason
is tied to the access. There are three ways to supply a reason:&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Source&lt;/th&gt;&lt;th&gt;Scope&lt;/th&gt;&lt;th&gt;Precedence&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;--reason&lt;/code&gt; flag&lt;/td&gt;&lt;td&gt;CLI&lt;/td&gt;&lt;td&gt;highest&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;Secrets::with_reason()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;SDK&lt;/td&gt;&lt;td&gt;overrides env&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code dir=&quot;auto&quot;&gt;SECRETSPEC_REASON&lt;/code&gt;&lt;/td&gt;&lt;td&gt;CLI + SDK + derive&lt;/td&gt;&lt;td&gt;lowest&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# CLI: the most explicit option, overrides the others&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;secretspec&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--reason&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;deploying release 0.12&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;./deploy.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// SDK: the programmatic equivalent of --reason&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secrets&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; Secrets&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;load&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;?.&lt;/span&gt;&lt;span&gt;with_reason&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;nightly backup job&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# Env: lowest precedence, but honored everywhere&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;SECRETSPEC_REASON&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;nightly backup job&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;SECRETSPEC_REASON&lt;/code&gt; is resolved by &lt;code dir=&quot;auto&quot;&gt;Secrets::load&lt;/code&gt; / &lt;code dir=&quot;auto&quot;&gt;load_from&lt;/code&gt;, which means
&lt;code dir=&quot;auto&quot;&gt;secretspec-derive&lt;/code&gt;-generated code and other library callers satisfy the policy
and supply an audit reason &lt;strong&gt;without any code changes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Whichever path you use, blank or whitespace-only reasons are ignored, so they
can’t quietly satisfy the policy. Under the hood this is backed by a new
&lt;code dir=&quot;auto&quot;&gt;Provider::set_reason&lt;/code&gt; trait method (a no-op by default), so existing providers
keep working unchanged.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;configuring-when-a-reason-is-required&quot;&gt;Configuring when a reason is required&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;The new &lt;code dir=&quot;auto&quot;&gt;require_reason&lt;/code&gt; policy in the &lt;code dir=&quot;auto&quot;&gt;[project]&lt;/code&gt; table controls when a reason
is mandatory:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;[project]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;my-app&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;require_reason&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;agents&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# require it from agents (default), or true / false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;&quot;agents&quot;&lt;/code&gt; (the default): require a reason only when a coding agent is detected.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;true&lt;/code&gt;: require it from every caller.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;false&lt;/code&gt;: never require it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because the policy lives in &lt;code dir=&quot;auto&quot;&gt;secretspec.toml&lt;/code&gt; and is enforced by SecretSpec, it
applies to everyone and every CI runner, and is inherited through &lt;code dir=&quot;auto&quot;&gt;extends&lt;/code&gt;.
Coding agents are spotted by the
&lt;a href=&quot;https://crates.io/crates/detect-coding-agent&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;detect-coding-agent&lt;/code&gt;&lt;/a&gt; crate
(Claude Code, Cursor, Codex, Gemini CLI, Copilot, and more); set
&lt;code dir=&quot;auto&quot;&gt;SECRETSPEC_AGENT&lt;/code&gt; for a harness it doesn’t recognize.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;upgrading&quot;&gt;Upgrading&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;cargo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secretspec&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Remember the new default: agents must pass a reason: set &lt;code dir=&quot;auto&quot;&gt;require_reason = false&lt;/code&gt;
to opt out.&lt;/p&gt;
&lt;p&gt;Questions or feedback? Join us on &lt;a href=&quot;https://discord.gg/naMgvexb6q&quot;&gt;Discord&lt;/a&gt;.&lt;/p&gt;</content:encoded></item></channel></rss>