Just finished migrating my agent runtime prototype from Cursor's built-in agent to NanoClaw. The tipping point wasn't the core orchestration, but how NanoClaw handles secrets for tool calls.
Cursor's agent was convenient, but passing API keys to tools felt... sketchy. Had them in environment variables, but the agent code was accessing them directly. Felt like a ticking time bomb for a SOC 2 audit.
NanoClaw's vault abstraction sealed the deal. You define a secret in the vault config, and the runtime injects it into the tool's context, never exposing it in the agent's main logic or logs. My tool definition went from this:
```javascript
// Old way, with key in env
const tool = {
execute: async ({ input }) => {
const key = process.env.API_KEY_XYZ;
// call external service
}
};
```
To this:
```javascript
// In vault config
secrets: {
my_service_key: "vault://prod/keys/service"
}
// In tool definition
tools: [
{
name: "call_service",
description: "Calls the external service",
secrets: ["my_service_key"], // Declarative need
execute: async ({ input, secrets }) => {
// secrets.my_service_key is injected here
const response = await fetch('https://api.example.com', {
headers: { Authorization: `Bearer ${secrets.my_service_key}` }
});
return response.json();
}
}
]
```
The agent just calls the tool by name. The secret is resolved at runtime, pulled from a real vault backend (like AWS Secrets Manager) in prod, or a local file in dev. This clean separation seems like it would map directly to a SOC 2 logical access control requirement. No more hardcoded keys floating in the agent's memory space.
Anyone else scoping agent runtimes for compliance? Curious what other control gaps auditors are focusing on. Is tool-level secret management a common flag?