Two lines of code. Every secret your app needs.
The SDK should feel effortless — not like another dependency to learn. Import it, call FyVault.auto(), and get back to the code that actually matters.
Sound familiar?
You have wrapped secret managers in custom abstractions before. Retry logic because the vault returned a 503. Caching because every cold start was 400ms slower. Error handling because the SDK threw generic exceptions with no status codes. Environment switching because staging and production used different auth flows.
All of it was boilerplate you wrote because the SDK was too low-level. It gave you an HTTP client and wished you luck. You ended up maintaining two systems: your application and the wrapper code that made secret management bearable.
FyVault's SDK is different. It is opinionated so you do not have to be.
$ npm install @fyvault/sdk
import { FyVault } from "@fyvault/sdk";
// Auto-detects env vars, config files, and runtime.
// No manual token wiring. No org ID lookup.
const fv = FyVault.auto();
// Fetch a secret by name — cached, typed, audit-logged
const dbUrl = await fv.secrets.get("DATABASE_URL");
// List every secret your org owns
const all = await fv.secrets.list();
// Need a different environment? One argument.
const staging = FyVault.auto({ env: "staging" });FyVault.auto() checks FYVAULT_TOKEN, then .fyvault/config.json, then the local agent socket — in that order. First one wins. Zero config in every environment.
Other SDKs return raw secrets.
FyVault returns handles that expire.
Think about what happens when a secret value ends up in a log line, a crash dump, or an error tracker. With every other SDK, that leaked value is your production API key — and it works forever until you rotate it manually.
FyVault never hands your application the raw credential. Instead, you get a rotating handle — a short string prefixed with fvh_that maps to the real secret inside FyVault's local proxy. Even if someone scrapes your logs, the handle they find expired minutes ago. It resolves to nothing.
- Default TTL is 5 minutes — configurable down to 60 seconds
- SHA-256 hashed at rest. FyVault never stores plaintext handles
- Local proxy resolves fvh_ to real credentials at the network layer
- Captured handles are dead strings after expiry — no rotation panic
- Every resolution is audit-logged with caller identity and timestamp
import { FyVault, SecretProxy } from "@fyvault/sdk";
const fv = FyVault.auto();
// What you get back is a handle, not the real key
const handle = await fv.secrets.getHandle("stripe-key");
// handle.value = "fvh_a8f3c9..." (expires in 5 min)
// handle.expiresAt = "2025-01-15T12:05:00Z"
// The local proxy swaps handles for real creds at network level
const proxy = new SecretProxy(fv);
const { port, stop } = await proxy.start();
// Your HTTP client routes through localhost:{port}
// It sees fvh_a8f3c9 in the header, swaps it for sk_live_...
// Need to resolve manually? One call.
const real = await fv.secrets.resolveHandle(handle.value);
// handle expires → resolveHandle returns null
// No panic. No manual rotation. It just works.One SDK. Eleven resource managers.
Most secret SDKs give you .get() and .list() and call it a day. FyVault ships typed managers for secrets, environments, agent credentials, sharing, compliance, sandboxes, hooks, dependencies, access tokens, organizations, and break-glass sessions. Every workflow lives on a single import.
const fv = FyVault.auto();
// Secrets
const key = await fv.secrets.get("STRIPE_KEY");
// Environments
const envs = await fv.environments.list();
// Agent credentials — scoped, time-limited
const cred = await fv.agents.issueCredential({
agentId: "agent_deploy_bot",
scopes: ["secrets:read"],
ttl: 300,
});
// Secret sharing — one-time links
const link = await fv.sharing.create({
secretId: key.id,
maxViews: 1,
ttlHours: 24,
});
// Compliance — who accessed what, when
const report = await fv.compliance.accessLog({
since: "7d",
secretId: key.id,
});
// Break-glass — emergency access with audit trail
const emergency = await fv.breakGlass.request({
reason: "Production DB unreachable",
secretId: "db-root-password",
});Session tokens that self-destruct
Mint, scope, expire, forget
Long-lived API keys are a liability. Every CI runner, every serverless function, every background job that holds a permanent token is a breach waiting to happen. FyVault session tokens flip the model: mint a short-lived credential scoped to exactly the permissions the job needs, and let it evaporate when the job ends.
No revocation scripts. No key rotation runbooks. The token simply stops working after its TTL expires. If someone intercepts it, they have minutes — not months.
- TTL from 60 seconds to 24 hours — you choose the blast radius
- Scoped to specific permissions — secrets:read, agents:write, anything
- SHA-256 hashed at rest. We never store the plaintext token
- Revocable instantly if you need to kill it before TTL
- Every use is audit-logged with caller context and IP
// Mint a session token from your root API key
const session = await fv.accessTokens.create({
ttlSeconds: 900, // 15 minutes
scopes: ["secrets:read"], // least privilege
label: "deploy-bot-run-42",
});
// Hand the token to a CI runner or serverless function
const runner = new FyVault({
accessToken: session.token, // fvsess_...
orgId: "org_acme",
});
// The runner can only read secrets. Nothing else.
const secret = await runner.secrets.get("DEPLOY_KEY");
// Job done. Revoke early or let it expire.
await fv.accessTokens.revoke(session.id);
// Token is now a dead string. Even if logs captured it.Same API surface. Same method names.
Your backend is Node.js. Your ML pipeline is Python. Your deploy scripts are a mix of both. With FyVault, you do not learn two SDKs. You learn one API and pick your language. Method names, parameter shapes, error codes — identical across both.
import { FyVault } from "@fyvault/sdk";
const fv = FyVault.auto();
const secret = await fv.secrets.get("API_KEY");
const handle = await fv.secrets.getHandle("API_KEY");
const envs = await fv.environments.list();
const cred = await fv.agents.issueCredential({
agentId: "bot_1",
scopes: ["secrets:read"],
ttl: 300,
});from fyvault import FyVault
fv = FyVault.auto()
secret = await fv.secrets.get("API_KEY")
handle = await fv.secrets.get_handle("API_KEY")
envs = await fv.environments.list()
cred = await fv.agents.issue_credential(
agent_id="bot_1",
scopes=["secrets:read"],
ttl=300,
)camelCase in TypeScript, snake_case in Python. Everything else is the same. Switch languages mid-project without re-reading documentation.
Errors that tell you what went wrong
No more guessing why a secret fetch failed. Every error carries a typed status code, a machine-readable error code, and a human-readable message. Catch them, branch on them, or let them propagate — they always make sense in your stack trace.
import { FyVault, FyVaultError } from "@fyvault/sdk";
try {
const secret = await fv.secrets.get("missing-key");
} catch (err) {
if (err instanceof FyVaultError) {
console.error(err.status); // 404
console.error(err.code); // "SECRET_NOT_FOUND"
console.error(err.message); // "Secret 'missing-key' not found in org_acme"
console.error(err.requestId); // "req_8f3a..." for support tickets
}
}
// Or use the built-in fallback pattern
const dbUrl = await fv.secrets.get("DATABASE_URL", {
fallback: "postgres://localhost:5432/dev",
});
// Returns fallback in development, throws in productionSDK or Agent? Pick the right tool for the job.
The SDK is code-first — import it, call methods, get secrets. The Agent is infrastructure-first — install it on the host, and your app reads secrets from .env placeholders without code changes. Same secrets, different delivery.
Reach for the SDK when
- Serverless functions where you can't install a daemon
- CI/CD pipelines that spin up and tear down in seconds
- Edge runtimes — Cloudflare Workers, Vercel Edge, Deno Deploy
- You want programmatic control over secret lifecycle
- Your team already manages dependencies via package.json or requirements.txt
Reach for the Agent when
- Dedicated servers or VMs where a daemon can run continuously
- Zero code changes — your app reads .env, the Agent fills the values
- Maximum isolation — secrets never enter application memory
- Offline operation after initial boot is a requirement
- You need kernel-level memory protection for the highest security posture
Finally, an SDK that doesn't make you write wrapper code
Every feature below ships in the box. No plugins. No community extensions. No "check out this third-party integration." Just import and use.
Zero-Config Auth
FyVault.auto() reads your environment, finds your credentials, and connects. No manual wiring.
Rotating Handles
Every secret access returns an fvh_ handle that expires in minutes. Leaked logs become dead strings.
Built-In Caching
Hot secrets stay in memory. Cold secrets fetch once. You never think about TTLs or invalidation.
Typed Everything
Full TypeScript types for secrets, environments, agents, sessions. Autocomplete that actually works.
Any Runtime, Same API
Node.js, Deno, Bun, Lambda, Cloudflare Workers, GitHub Actions. One import, everywhere.
Audit Trail Included
Every .get(), .list(), .resolve() call is logged with caller identity, IP, and timestamp. No extra code.
11 Resource Managers
Secrets, environments, agents, sharing, compliance, sandboxes, hooks, dependencies, tokens, orgs, break-glass.
Agent Credentials
Give AI agents scoped, time-limited access to secrets. Revoke instantly when the job ends.
Secret Sharing
Generate one-time links with TTL and view limits. Share credentials without Slack messages or sticky notes.
Compliance Queries
Ask which secrets are expiring, who accessed what, which agents hold active credentials. One method call.
Ephemeral Sandboxes
Spin up isolated secret environments for testing. Tear them down when CI finishes. No cleanup scripts.
Break-Glass Built In
Emergency access with full audit trail and automatic alerts. No custom escalation code needed.