Administer
Release policies
On this page
What a policy does
Governance skills guide coding agents while they build. Release policies enforce checks before a release goes live. Valet evaluates every new release of an artifact, app or agent against your organization's policies, regardless of who published it or how.
A policy is a checker configured for your organization. Each policy has an enforcement:
- Monitor reports findings and never stops a release. New policies start in Monitor.
- Block at a severity refuses a release that has a finding at or above that severity: info, low, medium, high or critical. It also refuses a release the checker couldn't evaluate.
A refused release never goes live, and the current release stays live.
Each release gets a release evaluation, made of one policy evaluation per policy. Each policy evaluation reports findings with a severity, a rule, a file and line or package, and instructions for fixing the problem.
When every policy is Monitor, the release goes live immediately while its policies finish evaluating it.
The checkers
Valet ships two checkers. Your organization can add its own: see Custom checkers.
catalog:osv
- Name
- Dependencies (OSV)
- Finds
- Packages with known vulnerabilities
catalog:secrets
- Name
- Secrets (gitleaks)
- Finds
- Credentials committed to the source
list_policies and valet policies checkers list both, with their
settings, and any custom checker your organization added.
Dependencies (OSV)
catalog:osv reads the packages a release pins and looks each one up
in OSV.dev, a public vulnerability database run by
Google. It reads:
- npm:
package-lock.json. - Python: the metadata of installed packages, and
name==versionlines inrequirements.txt. - Go: the modules compiled into a Go program, or
go.sum. With neither, the modulesgo.modrequires, at their minimum versions.
An app's build holds the exact versions it installed, so the checker reads the build as well as the source. It doesn't check operating-system packages, packages in the runtime image, or whether the vulnerable code is ever called.
The checker sends each package's ecosystem, name and version to
api.osv.dev, and nothing else from the release. If your organization
can't share its package list that way, don't add this policy.
Each finding uses the advisory's severity, names the lowest version that fixes the vulnerability, and links to the advisory on OSV.dev. The checker never passes a release it couldn't read in full. It errors when it can't reach OSV.dev, when a dependency file doesn't parse, or when the release has more than 20,000 packages.
The setting ignore takes comma-separated advisory IDs to skip. An ID
matches the advisory's own ID or any of its aliases, such as a CVE- or
GHSA- ID.
Secrets (gitleaks)
catalog:secrets scans a release's source with the default rules of
gitleaks, about 220 rules that
each match one vendor's credential format. The scan runs inside Valet
and sends nothing out.
- Every finding is high, except a generic API key, which the rule guesses from a name and randomness. That finding is medium.
- A finding names the file and line, never the value it matched.
- The scan skips lockfiles,
node_modules/andvendor/, images, fonts, binaries, files over 1 MiB, and lines that carry agitleaks:allowcomment. It does scan.envfiles. - It reads the source only, not the build.
The setting exclude takes comma-separated path globs of source files
to skip, such as testdata/*,*.pem. A glob with no / also matches a
file's name in any folder, so *.pem skips keys/dev.pem.
Add a policy
Start in Monitor to see what a policy finds before it blocks anything. A policy's name uses lowercase letters, digits and hyphens. Ask your agent:
Add a Valet release policy called dependencies that checks our packages with OSV. Start it in Monitor.set_policy
{ "policy": "dependencies", "checker": "catalog:osv", "enforcement": "monitor" }list_policies and valet policies show each policy's evaluation
results over the last 30 days: how many passed, blocked or errored.
valet policies also counts, for a Monitor policy, the releases it
would have blocked at critical, high and medium. list_policies returns
the count at each severity in recent.at_or_above.
Once the findings look right, make the policy block. Ask your agent:
Make the dependencies policy block releases at high.set_policy
{ "policy": "dependencies", "checker": "catalog:osv", "enforcement": "block", "block_at": "high" }Adding a policy with a name that exists replaces it, settings included, so pass every setting again. To pass one:
set_policy
{
"policy": "secrets",
"checker": "catalog:secrets",
"settings": { "exclude": "testdata/*,*.pem" },
"enforcement": "block",
"block_at": "high"
}What a change does
Completed evaluations never change. A running policy evaluation keeps its original checker and enforcement. It uses the current settings if the checker hasn't started yet.
Removing a policy or changing its checker cancels its running evaluations. Releases waiting only on that policy can then go live.
Switching a policy from Block to Monitor doesn't release a deploy already held by it. Publish again to evaluate the new release under Monitor.
Publish with policies
After the release is built, Valet holds it while blocking policies
evaluate it. The current release stays live. valet deploy prints
Waiting for policies, with the policy names, then each policy's status
as it changes. A blocked deploy ends like this:
Waiting for policies (dependencies, secrets)…
dependencies pending (block at high)
secrets pending (block at high)
secrets passed (block at high)
dependencies blocked (block at high)
high build/workspace/package-lock.json Command Injection in lodash (lodash@4.17.15) (osv/GHSA-35jh-r3h4-6jhm) [blocks]
Fix: Upgrade lodash to 4.17.21
More: https://osv.dev/vulnerability/GHSA-35jh-r3h4-6jhm
Error: deploy.policy_blocked: acme's policies blocked shop's changes: dependencies found 1 finding at high or above. Nothing was deployed; the current release is still live. Fix it and deploy again.Over MCP, publish_site and publish_agent answer that the release
waits for its policies, with the release evaluation's ID.
publish_app answers before the build finishes, so the agent follows
the build with get_build. Its deploy_state reads checking while
policies hold the release and refused once they refuse it.
When every blocking policy passes, the release goes live. When one doesn't, the publish ends with one of two errors:
deploy.policy_blocked: a finding is at or above the policy's severity. The message names the policy and counts its findings.deploy.policy_errored: the checker couldn't evaluate the release. The message names the policy and quotes the checker's error, such ascould not reach OSV.dev.
Either way, nothing was deployed, and the current release is still live. See Error codes.
Fix it and publish again
For a blocked release, fix what the findings name, then publish again. Ask your agent:
Policies blocked the last release of shop. Read the findings, fix them, and publish again.For an errored policy, publish again. A brief failure, such as OSV.dev not answering, clears on its own. If the policy keeps erroring, a member can change or remove it.
A new publish replaces a release that is still waiting. The replaced release never goes live, and Valet stops its evaluation.
While an agent's release waits, Valet refuses changes that would
redeploy the agent, such as attaching a skill, with deploy.checking.
Wait for the policies, or publish again.
Follow an evaluation
valet deploy waits up to 15 minutes for policies, longer than a
failed checker's retries take. --wait-timeout changes the wait, and
--no-wait skips it. The evaluation continues if the command stops
waiting. Ask your agent:
Check whether shop's release passed its policies.get_evaluation
{ "name": "shop", "wait_seconds": 20 }Both read the service's latest release evaluation: each policy's
status, every finding with its file or package and its fix, and what
Valet did with the release. wait_seconds waits up to 20 seconds for
the evaluation or the deploy to change. To read an older evaluation,
pass its ID, as evaluation_id or as the argument to
valet policies show.
Remove a policy
Ask your agent:
Remove the dependencies release policy.destroy_policy
{ "policy": "dependencies" }New releases no longer evaluate the policy. Its running policy evaluations are canceled, so releases that waited only on it go ahead. See What a change does. Past evaluations stay on the releases they evaluated.
In the dashboard
- Governance › Policies. Governance has two tabs: Standards, the skills, and Policies. Policies lists each policy with its checker, its enforcement, and whether it errored recently. Below the list, Blocked in the last 30 days shows each refused release with its service, commit, policy and first finding. Add policy picks a checker, then asks for a name, an enforcement and the checker's settings. Select a policy to change or remove it.
- Releases. Every artifact, app, agent and organization skill has a Releases tab. It lists each release, including those that never went live, with its author, when it was published, and its state: live, previous, checking, blocked, errored, superseded or building. Open a release to see each policy's findings: blocking policies first, then Monitor policies, marked Never blocks.
- Attention. When an artifact, app or agent has a refused release newer than any release that went live or passed, the sidebar badge for its kind counts it. Its listing names the problem, with a Review release link to the release. A banner on its page lists the blocking findings and how to clear them. All three clear when a newer release goes live or passes. They also clear when you publish source that matches the live release exactly, such as by undoing the change the policy refused. That publish makes no new release, and the refused release still shows as blocked or errored.
Limits
- Policies evaluate every release in the organization. A policy can't be limited to some services, and no service can be exempted.
- An organization skill's releases are evaluated too. Its page has a
Releases tab, but the sidebar badge and the banner don't cover
skills. Follow a skill's evaluation there or with
valet policies show. - A policy runs one of Valet's two checkers or a custom checker your organization adds. It can change only the settings its checker offers.
Next steps
- Custom checkers: enforce rules with your own endpoint.
- Governance: guide coding agents before they publish.