Your agent has the keys. Who decides what it does with them?

Vulnify is now open to the public, with a free plan and no credit card.
I'm Giovanni Zadinello. I started Vulnify because of one question I kept running into while watching teams connect AI agents to real systems: once the agent has a credential, who decides what it does with it?
The gap
An agent gets access once. An API key, a service account, an OAuth scope. From then on it acts on its own. It reads records, writes to systems, sends email, exports data, calls other APIs.
The credential tells you who is acting. It does not tell you whether this specific action should run, right now, against this resource, with this many records, to this destination.
An example. Reading one customer record and exporting 12,000 of them to an outside email address can use the same credential. Scanners look at code and prompts before deployment. Logs tell you what happened afterwards. Neither is in the path at the moment the agent acts.
That moment is where I think a decision belongs.
One decision before the action
Vulnify is a runtime authorization layer for AI agents. Before a sensitive tool call runs, your code describes the action: the agent, the action, the resource, the destination, and how many records are affected. Vulnify answers with one of three decisions.
- ALLOW: the action runs.
- REVIEW: the action does not run yet. A person has to approve it.
- BLOCK: the action does not run.
Each decision carries a score from 0 to 100 and the reasons behind it. The point is not that the score is always right. The point is that a person can read why, and disagree. Policies sit on top. They can match on the action, the resource and whether it holds sensitive data, the destination, the record count, the score, specific agents, and whether it is outside business hours. A policy can explicitly allow, or tighten the outcome to REVIEW or BLOCK.
Every decision, including human reviews, is appended to an audit log that is hash-chained per organization. You can verify the chain in the app. Owners and admins can download the compliance evidence as a JSON or CSV file that comes with a SHA-256 checksum.
What Vulnify sees, and what it doesn't
A check sends metadata about the action, not the data. Vulnify is designed to store the agent, the action, the resource, the destination and the record count. It does not store the contents of your records.
If you want, you can also send content to be scanned for sensitive data, including Brazilian identifiers such as CPF and PIX keys, with an LGPD category for each finding. That content is scanned and not stored.
What it looks like in code
There are two ways to ask.
The first is check, then act. You call the API or an SDK, and run the tool only after ALLOW. With the Python SDK:
import os
from vulnify import Vulnify
vulnify = Vulnify(api_key=os.environ["VULNIFY_API_KEY"])
vulnify.guard(
lambda: export_customer_records(),
agent="SalesBot",
action="EXPORT_DATA",
resource="Customer Database",
destination="EXTERNAL_EMAIL",
records_affected=12000,
)
guard() runs the function only on ALLOW. On REVIEW or BLOCK it raises, and the export never starts. The Node.js SDK has the same shape. Both packages include adapters that wrap tools for common agent frameworks: the OpenAI Agents SDK, the Vercel AI SDK, LangChain tools and MCP handlers in Node.js, and CrewAI and LangGraph in Python.
The second way is the gateway. You register an HTTP API as a route in the app. The call goes to Vulnify, which decides and forwards it upstream only when the decision allows it. The credential for that upstream stays in an encrypted vault and is injected only after ALLOW. The agent never sees it.
Policies can live in git. The SDK packages include a CLI. vulnify policies validate checks the YAML offline. vulnify policies apply --dry-run shows the change plan before anything is written. vulnify test --local runs test cases against the policy files in your branch and exits non-zero when a case fails, so it fits in CI.
Design choices you can argue with
Fail closed by default. If Vulnify cannot be reached, the SDKs return BLOCK and the action does not run. Fail open is an explicit setting, and the SDK marks that result as degraded so you know it happened. I think anything in the critical path of a risky action should fail safe. You may disagree, and the setting is yours.
Monitor mode first. Turning on a new control in front of agents that already work is risky. In monitor mode, Vulnify scores every action and records what it would have blocked or sent to review, and nothing is stopped. You enforce when the results look right.
Reviews happen outside the agent. A REVIEW is approved on the Vulnify side, in Vulnify or in Slack, by someone allowed to approve. Approving a high or critical review asks for a fresh authenticator code when the approver has MFA turned on. The process that asked never approves itself.
Test keys run in a sandbox. You can try decisions without touching production usage.
What is not there yet
It is early, and I would rather say this up front.
- MFA can be turned on per account. It cannot be enforced for a whole organization yet.
- No dedicated environment or VPC deployment. The service runs in the United States.
- No certification of any kind. The app maps evidence to LGPD, ISO/IEC 42001, NIST AI RMF and the EU AI Act. That is a mapping, not a certificate.
On the basics: passwords are hashed, and sign-up rejects common or known passwords. The SDKs and the CLI are free to use. The decision service is hosted.
If you are already shipping agents, there is a design partner program: three months free in exchange for weekly feedback.
Try it, and tell me where it breaks
I want to hear what you would need before putting something like this in your agent's critical path, and where the decision model is wrong.
Giovanni
Vulnify decides every sensitive agent action before it runs: ALLOW, REVIEW or BLOCK, with the reasons.
Try it free