hushsecrets your AI agent can use but never readGitHub

What a value should look like

The most common failure is not a leak, it is a wrong value: the test key in the production set, a truncated paste, a key whose prefix the SDK checks before it will talk to the API. A .env.schema declares the shape, in the same @env-spec syntax Varlock reads, so a schema you already have works here unchanged:

# @required @type=url
API_URL=

# @type=string(startsWith=sk-) @required
STRIPE_SECRET_KEY=

# @type=enum(development, preview, production) @sensitive=false
APP_ENV=development

# @type=port
PORT=3000

@sensitive=false is a request, not a permission. It asks for a key to be printed unmasked (useful for NODE_ENV or a PORT, which otherwise show as [redacted:…] on every line). Because the schema is a file in the repo, hush honours it only for keys you have listed in your own floor's unmaskKeys; every other request is ignored and named in a warning on the run. Without that, a repository could turn output masking off for a credential it can never read.

Supported: @required, @type= string/number/boolean/url/port/ email/enum(...), @type=string(startsWith=…, minLength=…, maxLength=…), @pattern=, and @sensitive=false. The placeholder after = is ignored: hush reads this file for rules, and the vault is the only source of values. @default is deliberately not implemented, because an injected default would make "the vault is the source of truth" quietly false.

hush run and hush request check the keys they are about to use and refuse before anything is spawned or sent (--no-validate overrides; an agent cannot). Only the keys in play are checked, so a production rule cannot block a dev command that never touches it. hush doctor reports everything. A failure names the key, the rule, and the length — never the value.

@sensitive=false means "do not mask this in output", which is what the mask is for: NODE_ENV=production arriving as [redacted:NODE_ENV] on every line is how people learn to ignore it. The value is still encrypted at rest.