@agentroot/sdk
v0.1.9
Published
The AgentRoot SDK for machine-bound proxy access
Readme
The AgentRoot SDK
npm version Node.js License: MIT
Machine-bound proxy access for autonomous agents.
@agentroot/sdk is the official Node.js SDK for The AgentRoot, the access layer that lets an agent call upstream APIs without ever holding the upstream API key itself.
You bind an agent to a machine once, store a local encrypted client_secret, and then send signed requests through The AgentRoot proxy with automatic token rotation and renew-on-401 behavior built in.
Why This Exists
The AgentRoot's raw proxy flow is intentionally simple: an agent can work with just an ID, a token, and a proxy URL.
This SDK is for the higher-assurance path:
- bind an agent to one machine with a one-time
init - store the returned
client_secretlocally in encrypted form - generate per-request HMAC proofs automatically
- rotate session tokens from response headers
- retry once on
401, with optional renewal againstsecure.agentroot.app
If you want the thinnest possible HTTP integration, use the raw proxy directly. If you want machine binding and signed proof generation, use this package.
What You Get
- Machine-bound local credential storage under
~/.agentroot/{agent_id}.enc - AES-256-GCM encryption for the stored
client_secret - Per-request proof headers:
X-AgentRoot-Proof,X-AgentRoot-Ts,X-AgentRoot-Nonce - Automatic session token rotation from
X-AgentRoot-New-Token - Optional session renewal via
POST /agents/{id}/renew - No runtime dependencies beyond Node.js
Get Started in 60 Seconds (Raw Proxy)
Use the raw proxy path with standard HTTP. No SDK install, no init, no local binding step.
Set 3 required environment variables:
export AGENTROOT_AGENT_ID="your-agent-id"
export AGENTROOT_TOKEN="your-session-token"
export AGENTROOT_PROXY="https://proxy.agentroot.app"Then call the proxy directly:
const response = await fetch(
`${process.env.AGENTROOT_PROXY}/openai/v1/models`,
{
headers: {
Authorization: `Bearer ${process.env.AGENTROOT_TOKEN}`,
"X-AgentRoot-Id": process.env.AGENTROOT_AGENT_ID!,
},
}
);
if (!response.ok) {
throw new Error(`Proxy request failed: ${response.status} ${await response.text()}`);
}
const data = await response.json();
console.log(data);This works with fetch, axios, curl, Python, or any language/runtime with HTTP support.
Upgrade: Install the SDK for Machine Binding (Optional)
Use the SDK when you want stronger stolen-credential protection and less auth plumbing.
What you get:
- one-time machine binding via
init - encrypted local
client_secretstorage - per-request HMAC proof generation
- automatic token rotation from proxy response headers
- optional renew-on-
401viasecure.agentroot.app
Install:
npm install @agentroot/sdkRequirements:
- Node.js
>= 18.17.0 - A valid AgentRoot agent ID
- A valid AgentRoot session token
- A proxy URL such as
https://proxy.agentroot.app
1. Bind This Machine Once
Set 3 required environment variables (+1 optional for secure renewal):
export AGENTROOT_AGENT_ID="your-agent-id"
export AGENTROOT_TOKEN="your-session-token"
export AGENTROOT_PROXY="https://proxy.agentroot.app"
# Optional (defaults to https://secure.agentroot.app)
export AGENTROOT_SECURE_URL="https://secure.agentroot.app"Run the one-time init:
npx @agentroot/sdk initThat exchanges your session token for a client_secret and stores it at:
~/.agentroot/{agent_id}.enc2. Make Requests Through The Proxy
import { AgentRootClient } from "@agentroot/sdk";
const client = new AgentRootClient({
agentId: process.env.AGENTROOT_AGENT_ID!,
token: process.env.AGENTROOT_TOKEN!,
proxyUrl: process.env.AGENTROOT_PROXY!,
secureUrl: process.env.AGENTROOT_SECURE_URL,
});
const response = await client.fetch("/openai/v1/models");
if (!response.ok) {
throw new Error(`Proxy request failed: ${response.status} ${await response.text()}`);
}
const data = await response.json();
console.log(data);Runtime Examples
POST JSON To An Upstream API
import { AgentRootClient } from "@agentroot/sdk";
const client = new AgentRootClient({
agentId: process.env.AGENTROOT_AGENT_ID!,
token: process.env.AGENTROOT_TOKEN!,
proxyUrl: process.env.AGENTROOT_PROXY!,
secureUrl: process.env.AGENTROOT_SECURE_URL,
});
const response = await client.fetch("/openai/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "<your-model>",
messages: [
{ role: "system", content: "Be concise." },
{ role: "user", content: "Explain what AgentRoot does." },
],
}),
});
if (!response.ok) {
throw new Error(await response.text());
}
const data = await response.json();
console.log(data);Persist The Latest Rotated Token
The SDK updates its in-memory token automatically when the proxy returns X-AgentRoot-New-Token.
If your process persists credentials between runs, persist the latest token yourself:
await client.fetch("/openai/v1/models");
const latestToken = client.getToken();
console.log("Store this token for the next process start:", latestToken);Add Your Own Request Headers
const response = await client.fetch("/openai/v1/models", {
headers: {
"X-Trace-Id": "agent-123",
},
});The SDK preserves your headers and adds the required AgentRoot auth headers on top.
API
new AgentRootClient(options)
type AgentRootClientOptions = {
agentId: string;
token: string;
proxyUrl: string;
secureUrl?: string;
};Constructor options:
| Option | Required | Description |
| ----------- | -------- | ------------------------------------------------------------------------------ |
| agentId | Yes | Your AgentRoot agent identifier |
| token | Yes | Your current short-lived session token |
| proxyUrl | Yes | Base URL for the AgentRoot proxy |
| secureUrl | No | Base URL for secure renewal, defaults in CLI to https://secure.agentroot.app |
Methods:
| Method | Description |
| -------------------- | ---------------------------------------------------------------------------------- |
| fetch(path, init?) | Sends a signed request through the proxy and returns a standard Response |
| getToken() | Returns the latest in-memory session token after any header rotation or renew flow |
Environment Variables
| Variable | Required | Used By | Notes |
| ---------------------- | -------- | --------------- | ------------------------------------------------------------------------------ |
| AGENTROOT_AGENT_ID | Yes | CLI and runtime | Agent identifier |
| AGENTROOT_TOKEN | Yes | CLI and runtime | Short-lived session token |
| AGENTROOT_PROXY | Yes | Runtime | Proxy base URL |
| AGENTROOT_SECURE_URL | No | CLI and runtime | Secure service base URL, defaults to https://secure.agentroot.app in the CLI |
The CLI also reads a local .env file from the current working directory if present.
In total: 3 required vars + 1 optional var (AGENTROOT_SECURE_URL).
Security Notes
This SDK improves the default proxy flow, but the guarantees are specific and worth being explicit about.
What It Protects
- Your agent process never receives the upstream provider API key directly
- The local
client_secretis encrypted on disk before storage - Every request carries a fresh timestamp and nonce in the proof payload
- Cloned request headers are not sufficient without the local bound secret
How Local Binding Works
The SDK derives the local encryption key from:
agentId- hostname
- platform
- CPU architecture
- OS release
- current username
That means the stored secret is tied to the machine identity as seen by Node.js at runtime.
What It Does Not Claim
- This is not TPM-backed or Secure Enclave-backed attestation
- This is not a browser SDK
- This is not protection against a fully compromised host
- This does not replace full-disk encryption, least-privilege OS config, or proper secret hygiene for your session token
In other words: this package raises the cost of secret reuse and makes off-machine replay harder, but it is still software-based machine binding.
Operational Implications
- If you move the workload to a new machine, run
initagain - If your container hostname or user changes frequently, the local encrypted file may become undecryptable across restarts
- Do not commit
~/.agentroot/*.encto source control - Do not log or hardcode
AGENTROOT_TOKEN
Failure Modes And Troubleshooting
| Symptom | Likely Cause | What To Do |
| ---------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------- |
| Missing required env var | CLI/runtime configuration incomplete | Set the missing environment variable or add it to .env |
| Agent already bound | The agent is already attached to another machine | Use Re-bind in the AgentRoot dashboard, then run init again |
| ENOENT reading ~/.agentroot/{agent_id}.enc | init was never run on this machine | Run npx @agentroot/sdk init first |
| Repeated 401 responses | Token expired and renew is unavailable or failed | Provide secureUrl, refresh the token, or re-run the auth flow |
| Decryption fails after host migration | Machine fingerprint changed | Re-run init on the target host |
About The AgentRoot
Mint agents. Root control.
One registration. Every API. Full control. Instant kill.
The AgentRoot is built around a simple security model:
- proxied upstream credentials
- verifiable agent identity
- revocation outside the agent runtime
- a kill switch the agent cannot unilaterally override
More context:
License
MIT
