LangChain Integration
The Logos Lexicon SDK provides first-class support for LangChain agents through the LangChainGuard and VocabularyRegistry classes. Every LangChain tool call can be gated against a CSIV token before execution — with zero network latency for synchronous policy checks.
How it works
Each LangChain tool name is mapped to a CSIV token ID in a LangChainToolMapping.
Before calling tool._run(), invoke guard.checkTool(toolName, input). This is synchronous and offline — no network required.
If the decision is blocked, throw or skip execution. If allowed, continue. The guard fires onBlock callbacks for audit logging.
For critical tokens (CSIV_EXEC_002, CSIV_INFRA_001), resolve a VINAC certificate before the guard will approve.
Installation
The LangChain integration is included in the core SDK package. No additional dependencies required.
npm install @silentauth/logos-lexicon
All LangChain integration classes are exported from the main package entry point:
import {
LangChainGuard,
VocabularyRegistry,
buildLangChainGuard,
type LangChainToolMapping,
type ToolCheckResult,
} from '@silentauth/logos-lexicon';Quick Start — buildLangChainGuard
The fastest path. Pass a flat list of tool-to-token mappings and get back a configured guard.
import { buildLangChainGuard } from '@silentauth/logos-lexicon';
const guard = buildLangChainGuard([
{ toolName: 'web_search', csivTokenId: 'CSIV_EXEC_001' },
{ toolName: 'read_file', csivTokenId: 'CSIV_EXEC_001' },
{ toolName: 'write_file', csivTokenId: 'CSIV_EXEC_002' },
{ toolName: 'deploy_service', csivTokenId: 'CSIV_INFRA_001' },
{ toolName: 'send_payment', csivTokenId: 'CSIV_TXN_001', policyOverride: { value_limit_usd: 500 } },
{ toolName: 'transfer_funds', csivTokenId: 'CSIV_TXN_002' },
{ toolName: 'rotate_api_keys', csivTokenId: 'CSIV_KEY_001' },
], {
defaultDenyUnmapped: true,
onBlock: (result) => {
console.warn(`[CSIV BLOCK] ${result.toolName} → ${result.decision.reason}`);
},
});
// Usage in your agent loop
const result = guard.checkTool('send_payment', { value_usd: 250 });
if (!result.allowed) {
throw new Error(`Tool blocked: ${result.decision.reason}`);
}
// proceed with tool executionWrapping LangChain Tools
The recommended pattern is a thin wrapper class that intercepts _run() before delegating to the underlying tool.
import { Tool } from '@langchain/core/tools';
import { buildLangChainGuard, type LangChainGuard } from '@silentauth/logos-lexicon';
class GuardedTool extends Tool {
name: string;
description: string;
private _inner: Tool;
private _guard: LangChainGuard;
constructor(inner: Tool, guard: LangChainGuard) {
super();
this.name = inner.name;
this.description = inner.description;
this._inner = inner;
this._guard = guard;
}
async _run(input: string): Promise<string> {
const parsed = JSON.parse(input);
const check = this._guard.checkTool(this.name, parsed);
if (!check.allowed) {
return JSON.stringify({
error: 'CSIV_BLOCK',
reason: check.decision.reason,
token: check.csivTokenId,
});
}
return this._inner._run(input);
}
}
// Wrap your tool set
const guard = buildLangChainGuard([
{ toolName: 'file_writer', csivTokenId: 'CSIV_EXEC_002' },
{ toolName: 'db_query', csivTokenId: 'CSIV_EXEC_001' },
], { defaultDenyUnmapped: true });
const guardedTools = rawTools.map((t) => new GuardedTool(t, guard));Using the Callback Handler
If you prefer not to wrap tools, attach a LangChain callback handler that fires on handleToolStart.
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
import { buildLangChainGuard } from '@silentauth/logos-lexicon';
class CsivCallbackHandler extends BaseCallbackHandler {
name = 'CsivCallbackHandler';
private _guard: ReturnType<typeof buildLangChainGuard>;
private _blocked = new Set<string>();
constructor(guard: ReturnType<typeof buildLangChainGuard>) {
super();
this._guard = guard;
}
async handleToolStart(
tool: { name: string },
input: string
): Promise<void> {
let parsed: Record<string, unknown> = {};
try { parsed = JSON.parse(input); } catch { /* scalar input */ }
const result = this._guard.checkTool(tool.name, parsed);
if (!result.allowed) {
this._blocked.add(tool.name);
throw new Error(`[CSIV] Tool "${tool.name}" blocked: ${result.decision.reason}`);
}
}
async handleToolEnd(): Promise<void> { /* optional audit */ }
}
// Attach to agent executor
const handler = new CsivCallbackHandler(guard);
const executor = AgentExecutor.fromAgentAndTools({
agent,
tools,
callbacks: [handler],
});VocabularyRegistry — Advanced Usage
The VocabularyRegistry manages the full lifecycle of token-to-tool bindings. It lets you bind and unbind tools from tokens at runtime and serialize the registry to JSON for persistence.
import { VocabularyRegistry } from '@silentauth/logos-lexicon';
const registry = new VocabularyRegistry();
// Bind LangChain tool names to existing CSIV tokens
registry.bindTool('CSIV_EXEC_001', 'web_search');
registry.bindTool('CSIV_EXEC_001', 'read_file');
registry.bindTool('CSIV_EXEC_002', 'write_file');
registry.bindTool('CSIV_TXN_001', 'stripe_charge');
// Add a custom token for your own domain
registry.register({
token_id: 'CSIV_CUSTOM_REPORT_GEN',
action_label: 'generate_report',
action_namespace: 'analytics.reporting',
risk_tier: 'medium',
required_layer: 2,
requires_vinac: false,
is_active: true,
is_builtin: false,
description: 'Authorizes PDF/CSV report generation',
langchain_tools: ['generate_pdf', 'generate_csv'],
execution_policy: { max_uses: 50, rate_limit_per_hour: 100 },
});
// Build a ready-to-use guard from the registry
const guard = registry.buildGuard({ defaultDenyUnmapped: true });
// Serialize for storage / audit
const snapshot = JSON.stringify(registry.toJSON());VocabularyRegistry.fromJSON().Context Mapping
Policy rules like value_limit_usd or dual_approval need to read specific fields from the tool input. Use a contextMapper to normalise your tool's input shape.
import { LangChainGuard, type LangChainToolMapping } from '@silentauth/logos-lexicon';
const mappings: LangChainToolMapping[] = [
{
toolName: 'stripe_transfer',
csivTokenId: 'CSIV_TXN_001',
// Normalise Stripe tool input → standard CSIV context keys
contextMapper: (input) => ({
value_usd: (input['amount'] as number) / 100, // cents → dollars
dual_approved: input['requires_dual_sign'] ?? false,
}),
},
];
const guard = new LangChainGuard({ mappings });
// input from LangChain: { amount: 150000, requires_dual_sign: false }
const result = guard.checkTool('stripe_transfer', { amount: 150000, requires_dual_sign: false });
// → blocked: value_usd 1500 > value_limit_usd 1000 (if override set)
console.log(result.decision.reason);Full Agent Example
A complete example with a LangChain ReAct agent, guarded tool set, and audit logging.
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { ChatOpenAI } from '@langchain/openai';
import { VocabularyRegistry, LangChainGuard } from '@silentauth/logos-lexicon';
import type { ToolCheckResult } from '@silentauth/logos-lexicon';
// 1. Build registry
const registry = new VocabularyRegistry();
registry.bindTool('CSIV_EXEC_001', 'search_web');
registry.bindTool('CSIV_EXEC_001', 'read_file');
registry.bindTool('CSIV_EXEC_002', 'write_file');
registry.bindTool('CSIV_INFRA_001', 'deploy_to_production');
registry.bindTool('CSIV_TXN_001', 'process_payment');
// 2. Build guard with audit hook
const blocked: ToolCheckResult[] = [];
const guard = registry.buildGuard({
defaultDenyUnmapped: true,
onBlock: (result) => {
blocked.push(result);
console.warn('[BLOCK]', result.toolName, '→', result.decision.reason);
},
});
// 3. Wrap tools
const rawTools = [searchTool, readFileTool, writeFileTool, deployTool, paymentTool];
const guardedTools = rawTools.map((tool) => ({
...tool,
invoke: async (input: Record<string, unknown>) => {
const check = guard.checkTool(tool.name, input);
if (!check.allowed) {
return { error: 'CSIV_BLOCK', reason: check.decision.reason };
}
return tool.invoke(input);
},
}));
// 4. Build and run agent
const model = new ChatOpenAI({ model: 'gpt-4o' });
const agent = createReactAgent({ llm: model, tools: guardedTools });
const result = await agent.invoke({
messages: [{ role: 'user', content: 'Summarise the sales report and email it to the team.' }],
});
// 5. Review any blocks
console.log('Blocked actions:', blocked.map(b => b.toolName));Policy Decision Reference
Every call to checkTool() returns a ToolCheckResult:
allowedbooleanWhether the tool call is permitted under current policy.toolNamestringThe LangChain tool name that was checked.csivTokenIdCsivTokenIdThe CSIV token the tool is mapped to.decision.risk_tierRiskTierlow | medium | high | critical — informs escalation path.decision.required_layer1 | 2 | 3 | 4Minimum verification layer required for this token.decision.reasonstring?Human-readable denial reason. Present only when allowed = false.decision.execution_policyExecutionPolicy?The merged execution policy that was evaluated.Token Selection Guide
Choose the right CSIV token for common LangChain tool categories:
CSIV_EXEC_001highWeb search, file reads, API GET calls, database reads
Standard agent execution — requires auth but not dual approval
CSIV_EXEC_002criticalFile writes, code execution, database mutations, shell cmds
Critical execution — requires dual approval by default
CSIV_TXN_001highPayment processing, invoice creation, billing API calls
Financial transactions — value-limited, rate-capped
CSIV_TXN_002criticalWire transfers, high-value purchases, payroll mutations
High-value transactions — dual approval required
CSIV_INFRA_001criticalDeploy, scale, destroy infrastructure, DNS changes
Infrastructure mutations — change window required
CSIV_KEY_001criticalAPI key rotation, secret generation, certificate issuance
Key ceremonies — quorum of 2 required
CSIV_AUTH_001highIdentity binding, session escalation, SSO flows
Identity operations — max 1 use, 10/hour rate limit
CSIV_EXEC_002, not CSIV_EXEC_001.