Getting started
Install the SDK and run your first security check.
Prerequisites
- Security Layer CLI installed and initialized (
sl init) - Node.js 18+ or Bun 1.0+
Installation
npm install @securitylayerai/sdkyarn add @securitylayerai/sdkpnpm add @securitylayerai/sdkbun add @securitylayerai/sdkBasic setup
import { createSecurityLayer } from "@securitylayerai/sdk";
// Initialize with default config (reads ~/.securitylayer/)
const sl = await createSecurityLayer();
// Or with explicit configuration
const sl = await createSecurityLayer({
configDir: "/path/to/.securitylayer",
sessionId: "session-123",
});Your first check
Every tool call your agent makes should pass through sl.check() before execution:
async function runTool(tool: string, params: Record<string, unknown>) {
const result = await sl.check(tool, params);
switch (result.decision) {
case "ALLOW":
// Safe to execute
return executeToolCall(tool, params);
case "DENY":
// Structurally blocked — do not execute
throw new Error(`Security Layer: ${result.reason}`);
case "REQUIRE_APPROVAL":
// Needs human approval before proceeding
const approved = await sl.waitForApproval(result.approvalId as string);
if (!approved) throw new Error("Approval denied or timed out");
return executeToolCall(tool, params);
}
}You can also override the session ID for a specific check:
const result = await sl.check("exec", { command: "ls" }, {
sessionId: "different-session",
});Understanding decisions
Every check returns a CheckResult with the decision and detailed layer results:
const result = await sl.check("exec", { command: "git push --force" });
// The overall decision
console.log(result.decision); // "ALLOW" | "DENY" | "REQUIRE_APPROVAL"
console.log(result.reason); // Human-readable explanation
// Which layer blocked it?
console.log(result.layers.capability); // { allowed: true }
console.log(result.layers.rules); // { decision: "DENY", reason: "Force push" }
console.log(result.layers.llm); // { decision: "NORMAL", confidence: 0.9 }
// Performance
console.log(result.timing.total); // 12 (ms)
console.log(result.degraded); // false (all layers executed)Tracking taint
When your agent reads external content, update the taint tracker:
// After reading a web page
const webContent = await fetch("https://example.com").then(r => r.text());
sl.ingestContent(webContent, {
source: "web",
url: "https://example.com",
});
// After reading an untrusted file
const fileContent = await readFile("/tmp/downloaded-project/config.js", "utf-8");
sl.ingestContent(fileContent, {
source: "file",
path: "/tmp/downloaded-project/config.js",
});
// After receiving skill output
sl.ingestContent(skillOutput, { source: "skill", path: "summarize" });
// After loading from memory
sl.ingestContent(memoryData, { source: "memory" });
// Check the current taint level
const taint = sl.getSessionTaint(); // "web" (elevated from "owner")Taint only escalates — once a session sees web content, it stays at web taint or higher for the rest of the session.
Scanning outbound content
Before your agent sends data externally, scan for leaked secrets:
const message = agent.generateResponse();
const scan = sl.scanEgress(message);
if (!scan.clean) {
console.error("Secrets detected:", scan.findings.map(f => f.type));
// Don't send the message — it contains sensitive data
}Listening to events
Subscribe to security events for logging, monitoring, or custom logic:
// Listen for security decisions
const unsub = sl.on("action.evaluated", (event) => {
console.log(`${event.action}: ${event.decision}`);
});
// Later, unsubscribe
unsub();Cleanup
Always call destroy() when you're done to release resources:
sl.destroy();This resolves any pending approval requests and clears event handlers.
Error handling
The SDK throws typed errors you can catch:
import {
createSecurityLayer,
ConfigError,
InitializationError,
} from "@securitylayerai/sdk";
try {
const sl = await createSecurityLayer({ configDir: "/bad/path" });
} catch (err) {
if (err instanceof ConfigError) {
console.error("Config problem:", err.message, err.configPath);
} else if (err instanceof InitializationError) {
console.error("Pipeline init failed:", err.message, err.cause);
}
}Next steps
- Integration patterns — Choose the right pattern for your framework
- API reference — Full method and type documentation