@securecode/sdk
v0.10.1
Published
SecureCodeHQ SDK - Access your secrets programmatically
Maintainers
Readme
@securecode/sdk
The official Node.js SDK for SecureCodeHQ — the secrets vault for developers who build with Claude Code.
Install
npm install @securecode/sdkQuick Start
The fastest way to get started is through the MCP onboarding — just tell Claude Code:
You: "Set up SecureCode for this project"This creates your account, imports your .env files, and configures everything automatically. After onboarding, a .securecoderc file is created in your project root — the SDK reads it automatically.
Manual setup
Set your API key and start using secrets:
export SECURECODE_API_KEY=sc_your_key_hereimport { getSecret } from '@securecode/sdk';
const stripeKey = await getSecret('STRIPE_SECRET_KEY');
const dbUrl = await getSecret('DATABASE_URL');Load All Secrets at Once
Inject all your secrets into process.env with a single API call:
import { loadEnv } from '@securecode/sdk';
await loadEnv();
// Now use process.env.STRIPE_SECRET_KEY, process.env.DATABASE_URL, etc.Options:
await loadEnv({
tags: { env: 'production', project: 'acme' }, // filter by tags
override: false, // don't overwrite existing env vars
});Note:
overridedefaults totrue— secrets from the vault overwrite existingprocess.envvalues. Setoverride: falseto preserve local values.
Framework Integration
Next.js (App Router)
Use instrumentation.ts to load secrets at startup. Important: Next.js compiles this file for both Node.js and Edge runtimes. Use the NEXT_RUNTIME guard to avoid Edge bundling issues:
// src/instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
const { loadEnv } = await import("@securecode/sdk");
await loadEnv();
}
}For Next.js 14, add
experimental: { instrumentationHook: true }tonext.config.mjs.
Express / Plain Node.js
Call loadEnv() before your app starts:
import { loadEnv } from '@securecode/sdk';
await loadEnv();
// Now start your server — all secrets are in process.envGranular Access (getSecret)
For fine-grained audit trails, use getSecret() instead of loadEnv():
import { getSecret } from '@securecode/sdk';
// Each call = 1 HTTP request + 1 audit log entry
const stripe = await getSecret('STRIPE_KEY');
const db = await getSecret('DATABASE_URL');When to use which:
loadEnv()— 1 API call, all secrets inprocess.env, ideal for app startupgetSecret()— 1 call per secret, individual audit trail per secret, ideal for on-demand access
CLI Tools
Migrate from .env files
Scan and import your .env files into SecureCodeHQ:
npx securecode migrate # scan all .env* files
npx securecode migrate .env.production # import specific file
npx securecode migrate --tags "project:acme" # apply tags
npx securecode migrate --ttl 720 -y # 30-day TTL, skip confirmRun with secrets injected
Load secrets into process.env and run your command:
npx securecode-run node server.js
npx securecode-run -- npm start
npx securecode-run --tags "env:production" node app.jsConfiguration
The SDK resolves the API key from these sources (in order):
SECURECODE_API_KEYenvironment variable.securecodercfile in the project root (created during onboarding).mcp.jsonfile (MCP server configuration)
The .securecoderc file can also set project and environment filters:
SECURECODE_API_KEY=sc_your_key_here
SECURECODE_PROJECT=acme
SECURECODE_ENV=stagingWhen SECURECODE_PROJECT and/or SECURECODE_ENV are set, loadEnv() and listSecrets() automatically filter by those tags.
Full Client
For more control, create a client instance:
import { SecureCodeClient } from '@securecode/sdk';
const client = new SecureCodeClient({
apiKey: 'sc_your_key_here',
});
// Get a secret value
const value = await client.getSecret('OPENAI_API_KEY');
// Get a secret with tags to disambiguate
const prodKey = await client.getSecret('DB_URL', { env: 'production' });
// Reveal mode — value returned to caller (audited as conscious action)
const revealed = await client.getSecret('DB_URL', undefined, undefined, { reveal: true });
// List all secrets (metadata only, no values)
const secrets = await client.listSecrets();
// Filter by tags
const prodSecrets = await client.listSecrets({
tags: { env: 'production', project: 'acme' },
});
// Create a secret with tags and TTL
await client.createSecret({
name: 'NEW_API_KEY',
value: 'sk-...',
description: 'OpenAI production key',
tags: { env: 'production', project: 'acme' },
ttlHours: 720, // expires in 30 days
});
// Update a secret
await client.updateSecret('NEW_API_KEY', {
value: 'sk-new-value...',
tags: { env: 'production', rotated: 'true' },
});
// Renew an expired secret
await client.renewSecret('EXPIRED_KEY', 48); // 48 hours
// Delete a secret
await client.deleteSecret('OLD_KEY');
// Export all secrets as .env format
const envContent = await client.exportEnv({ format: 'env' });MCP Access Rules
When an MCP rule blocks access, the SDK throws McpRuleBlockedError:
import { SecureCodeClient, McpRuleBlockedError } from '@securecode/sdk';
const client = new SecureCodeClient({ apiKey: 'sc_...' });
try {
const value = await client.getSecret('STRIPE_LIVE_KEY');
} catch (err) {
if (err instanceof McpRuleBlockedError) {
console.log(err.ruleAction); // 'block_always' | 'require_confirmation' | ...
console.log(err.ruleName); // 'Block production secrets'
// For require_confirmation rules, acknowledge and retry:
if (err.ruleAction === 'require_confirmation') {
const value = await client.getSecret('STRIPE_LIVE_KEY', undefined, err.ruleId);
}
}
}
// List active rules (read-only)
const rules = await client.getActiveRules();Session Lock
Control when Claude Code can access your secrets:
// Wake session with scoped access
await client.wakeSession({
scope: [{ project: 'acme', env: 'staging' }],
autoSleepMinutes: 60,
});
// Check session status
const status = await client.getSessionStatus();
console.log(status.status); // 'active' | 'sleeping'
// Lock session when done
await client.sleepSession();API Key Retry on Rotation
The SDK automatically handles API key rotation. If a request returns 401, the SDK re-reads the API key from its source (env var, .securecoderc, or .mcp.json) and retries once. This means you can rotate keys without restarting your application.
Requirements
- Node.js >= 18
License
MIT
