The GAIA C++ framework executes tool calls requested by the LLM. Without guardrails, a prompt injection could trick the model into calling a sensitive tool with malicious arguments. This guide describes the security primitives available to restrict, validate, and confirm tool calls before they execute.
Every ToolInfo has a policy field that determines what happens when the registry is asked to execute it:
#include <gaia/types.h>enum class ToolPolicy { ALLOW, // Execute immediately (default) CONFIRM, // Ask the user before executing DENY, // Never execute; return an error to the LLM};
The default policy for locally registered tools is ToolPolicy::ALLOW — they execute without prompting unless you explicitly set CONFIRM, change the default with setDefaultPolicy(), or mark individual tools DENY. New agents should be explicit about policy on every tool with side effects.MCP tools are the exception: they are CONFIRM-gated automatically unless the server proves them read-only. See MCP tools are CONFIRM-gated by default.
Example: require confirmation before a side-effecting tool
The policy field is set on the ToolInfo struct before you declare the tool’s callback and before you register it with the registry. This is where you choose what gate, if any, the framework places between the LLM’s request and execution.
gaia::ToolInfo info;info.name = "flush_dns";info.description = "Flush the system DNS cache";info.policy = gaia::ToolPolicy::CONFIRM;info.callback = [](const gaia::json& /*args*/) -> gaia::json { return gaia::json{{"status", "ok"}, {"message", "DNS cache flushed"}};};agent.toolRegistry().registerTool(std::move(info));
A tool discovered from an MCP server is named by that server, so it can never be matched against a static list of known-dangerous names. connectMcpServer() therefore classifies every discovered tool and registers it with ToolPolicy::CONFIRMunless the server proves it read-only. A tool is exempt only when both hold:
the tool’s annotations.readOnlyHint is the JSON boolean true — a missing annotations object, a non-object value, false, or the string"true" all count as unproven; and
the tool name contains no state-changing verb token (delete, write, push, execute, start, interact, …), matched across snake_case, kebab-case and camelCase (including WRITEFile).
So a server that advertises delete_file with readOnlyHint: true still gets gated — the name overrides the claim.
// No opt-in required — this is the behaviour after connectMcpServer() returns.agent.connectMcpServer("fs", {{"command", "npx"}, {"args", {"-y", "some-fs-server"}}});// Given what the server reported for each tool:// read_file {"readOnlyHint": true} -> mcp_fs_read_file ALLOW// write_file {"readOnlyHint": true} -> mcp_fs_write_file CONFIRM (mutating verb)// list_dir (no annotations) -> mcp_fs_list_dir CONFIRM (unproven)
Because CONFIRM is fail-closed, an agent with silentMode = true (no confirm callback) cannot execute any gated MCP tool. For headless automation that legitimately needs them, install an explicit callback with setToolConfirmCallback() — an intentional opt-in, visible in your code — or pre-approve specific tools through the always-allow store.
The classifier’s verdict is a floor. setDefaultPolicy(ToolPolicy::CONFIRM) or DENY can still raise a proven-read-only MCP tool to a stricter policy; nothing lowers a gated tool back to ALLOW.What the exemption does not cover.readOnlyHint is the server’s own claim, and the verb check is the only counterweight — it knows a fixed vocabulary, so it protects against a careless server, not a hostile one. Two consequences worth knowing:
A read-only tool can still be an exfiltration channel. A gated-out web_search or fetch_url reads your context and puts it in a query string; the classifier does not consult openWorldHint.
For a server you have not vetted, call setDefaultPolicy(ToolPolicy::CONFIRM) before connectMcpServer() so nothing from it is exempt.
The framework default is ToolPolicy::ALLOW. For a high-security agent — one where every side-effecting local tool should prompt — you can change the blanket default:
// All local and MCP tools inherit CONFIRM unless explicitly overridden.agent.setDefaultPolicy(gaia::ToolPolicy::CONFIRM);// Explicit ALLOW override for a specific read-only tool:gaia::ToolInfo status_info;status_info.name = "get_status";status_info.policy = gaia::ToolPolicy::ALLOW;status_info.callback = [](const gaia::json&) -> gaia::json { return {{"status", "ok"}}; };agent.toolRegistry().registerTool(std::move(status_info));// Raises even proven-read-only MCP tools to CONFIRM:agent.connectMcpServer("untrusted", {{"command", "npx"}, {"args", {"-y", "server"}}});
Call setDefaultPolicy() before registering tools or calling connectMcpServer(). Tools registered afterwards inherit the new default; tools already registered are unaffected.For MCP tools the default is applied as a raise, never a lower: a tool the classifier gated at CONFIRM stays gated even under the framework default of ALLOW.Use ToolPolicy::DENY for tools the LLM should never invoke — for example, internal-only tools registered for programmatic use but not accessible to the model.
The LLM controls what arguments it passes to your tools. A prompt injection or confused model could supply malicious paths, oversized payloads, or unexpected types. The validateArgs callback intercepts arguments before the tool callback runs — and before the user sees a confirmation prompt — giving you a chance to sanitize or reject them.
// Returns sanitized args or throws std::invalid_argument to reject.using ToolValidateCallback = std::function<json(const std::string& toolName, const json& args)>;
Tools that accept file paths from the LLM are vulnerable to path traversal attacks. An argument like ../../etc/passwd can escape a sandboxed directory. validatePath() canonicalizes both paths using the OS (resolving .., symlinks on POSIX) and verifies containment.
#include <gaia/security.h>// Returns true only if requestedPath is inside basePathbool ok = gaia::validatePath("/var/gaia/data", userSuppliedPath);if (!ok) { // reject}
On POSIX this uses realpath(), which resolves symlinks and .. components. On Windows it uses GetFullPathName(), which normalizes .. components but does not follow symlinks. Returns false if either path cannot be resolved.
If your tool builds a shell command string from LLM-supplied arguments, a single semicolon can turn a filename into arbitrary code execution. isSafeShellArg() rejects strings containing any shell metacharacter, ensuring the argument is safe to interpolate into a command.
#include <gaia/security.h>std::string userArg = args.value("interface", "");if (!gaia::isSafeShellArg(userArg)) { throw std::invalid_argument("unsafe shell argument: " + userArg);}// Safe to interpolate into a command stringstd::string cmd = "netsh interface show interface name=" + userArg;
Rejected characters include: spaces, tabs, newlines, ;, |, &, <, >, $, `, ", ', !, {, }, (, ), [, ], ~, *, ?, #, ^, %, =.Backslash (\) is not rejected because it is a path separator on Windows. If you are building POSIX-only commands, add an explicit backslash check in your validateArgs callback.
When a tool’s policy is CONFIRM, the registry calls a ToolConfirmCallback before executing:
enum class ToolConfirmResult { ALLOW_ONCE, // Execute this one call; ask again next time ALWAYS_ALLOW, // Execute and remember the permission permanently DENY, // Reject this call; return an error to the LLM};using ToolConfirmCallback = std::function<ToolConfirmResult(const std::string& toolName, const json& args)>;
For agents running in a terminal (silentMode = false, which is the default), the Agent constructor automatically installs a stdin/stderr confirm callback. Setting policy = ToolPolicy::CONFIRM on a tool is all you need:
// Registers a tool that auto-prompts in terminal agents — no extra setup required.toolRegistry().registerTool("flush_dns", "Clear DNS cache", [](const json&) { /* ... */ return gaia::json{{"ok", true}}; }, {}, false, gaia::ToolPolicy::CONFIRM);
When the LLM calls flush_dns, the user sees:
"flush_dns" requires confirmation. Allow this tool to run? ============================================ [1] Allow once [2] Always allow [3] Deny ============================================ Choice:
Agents constructed with config.silentMode = true (e.g., unit tests, background automation) receive no confirm callback. Any tool with CONFIRM policy is denied automatically (fail-closed). There is no user to ask in a headless context, so blocking is the safe default.This includes MCP tools, which are gated automatically — a headless agent that calls connectMcpServer() will be denied every discovered tool the server did not prove read-only.If your headless agent needs to approve specific tools automatically, pre-populate AllowedToolsStore before the agent starts:
auto store = std::make_shared<gaia::AllowedToolsStore>();store->addAlwaysAllowed("read_config"); // pre-approved for this agentstore->addAlwaysAllowed("mcp_windows_Shell"); // MCP names are prefixedagent.toolRegistry().setAllowedToolsStore(store);
Alternatively, install an auto-approving callback — an explicit, greppable opt-in rather than a silent default:
The default stdin callback is designed for interactive terminals. GUI applications, Electron apps, or remote approval workflows need their own callback. Call setToolConfirmCallback() after construction to replace the default:
agent.setToolConfirmCallback([](const std::string& tool, const json& args) { // Show a dialog, send a notification, or call a remote approval API. // Return ALLOW_ONCE, ALWAYS_ALLOW, or DENY based on the response. bool approved = showConfirmDialog(tool, args.dump()); return approved ? gaia::ToolConfirmResult::ALLOW_ONCE : gaia::ToolConfirmResult::DENY;});
If you use ToolRegistry without an Agent — for unit tests, CLI tools, or embedding tool execution in a non-agent application — install the built-in callback yourself:
Fail-closed: if a tool’s policy is CONFIRM and no callback is set, the tool is denied. This prevents accidental execution of sensitive tools in contexts where no user is present.
The store is global — all GAIA agents on the machine share one allowed set.
Known limitation: Permissions are stored by tool name only, with no per-agent namespacing. If two agents both register a tool named read_file, a user’s “Always Allow” decision for one agent applies to both. Use distinct tool names if you need per-agent permission boundaries.
The security_demo example in cpp/examples/security_demo.cpp provides an interactive four-mode demo of all features on this page. It requires no Lemonade Server — build it with the rest of the examples and run ./security_demo.
Call setDefaultPolicy(ToolPolicy::CONFIRM) in production agents that want stricter blanket defaults for their local tools. MCP tools are already gated automatically.
Use validateArgs for every tool that touches the file system or executes shell commands.
Combine validatePath + isSafeShellArg for tools that build shell command strings from LLM-supplied arguments.
Use DENY for tools the LLM should never invoke — for example, internal-only tools registered for programmatic use but not accessible to the model.
Review ~/.gaia/security/allowed_tools.json periodically to audit permanently-allowed tools.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"GAIA SDK","colors":{"primary":"#A87B2D","light":"#E2A33E","dark":"#E2A33E"},"logo":{"light":"https://mintcdn.com/amd-fe836e11/PgPhi3UrqFX2lV53/assets/favicon.ico?fit=max\u0026auto=format\u0026n=PgPhi3UrqFX2lV53\u0026q=85\u0026s=77bcf8b2d70613766cc02f16b0e208a0","dark":"https://mintcdn.com/amd-fe836e11/PgPhi3UrqFX2lV53/assets/favicon.ico?fit=max\u0026auto=format\u0026n=PgPhi3UrqFX2lV53\u0026q=85\u0026s=77bcf8b2d70613766cc02f16b0e208a0","href":"https://github.com/amd/gaia"},"favicon":"https://mintcdn.com/amd-fe836e11/PgPhi3UrqFX2lV53/assets/favicon.ico?fit=max\u0026auto=format\u0026n=PgPhi3UrqFX2lV53\u0026q=85\u0026s=77bcf8b2d70613766cc02f16b0e208a0","appearance":{"default":"system"},"navbar":{"links":[{"href":"https://github.com/amd/gaia/releases","label":"v0.25.1 · Lemonade 2026.43.3"},{"href":"https://amd-gaia.ai","label":"Main Site"}],"primary":{"type":"button","label":"Download","href":"https://amd-gaia.ai/#install"}},"footer":{"socials":{"github":"https://github.com/amd/gaia","discord":"https://discord.com/invite/5xXzkMu8Zk","twitter":"https://twitter.com/amd","linkedin":"https://linkedin.com/company/amd"}},"fonts":{"heading":{"family":"Inter"},"body":{"family":"Inter"}},"contextual":{"options":["copy","view","chatgpt","claude","cursor","vscode"],"display":"header"},"metadata":{"timestamp":false},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"GitHub","icon":"github","href":"https://github.com/amd/gaia"},{"anchor":"Discord","icon":"discord","href":"https://discord.com/invite/5xXzkMu8Zk"},{"anchor":"PyPI","icon":"python","href":"https://pypi.org/project/amd-gaia/"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"amd-fe836e11","hasAudioNarration":false,"actualSubdomain":"amd-fe836e11","customDomains":["amd-gaia.ai"],"gitSource":{"type":"github","owner":"amd","repo":"gaia","deployBranch":"release","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ade720d531268f76f8ae9c4","collectionId":"8e2093a5-a49b-4254-ac9a-c0367535f98d","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ade720d531268f76f8ae9c4"},"feedback":{"thumbs":true},"entitlements":{},"buildId":"6ade720d531268f76f8ae9c4","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"default","tag":"Documentation","count":94},{"language":"default","tag":"Python Framework","count":81},{"language":"default","tag":"SDK Reference","count":35},{"language":"default","tag":"Releases","count":31},{"language":"default","tag":"Release Notes","count":31},{"language":"default","tag":"User Guides","count":29},{"language":"default","tag":"Python Specifications","count":29},{"language":"default","tag":"Roadmap","count":25},{"language":"default","tag":"SDKs","count":20},{"language":"default","tag":"Python Reference","count":17}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"/docs","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":".nav-tabs .nav-tabs-item{color:rgb(156 163 175)!important}.dark .nav-tabs .nav-tabs-item{color:rgb(209 213 219)!important}.nav-tabs .nav-tabs-item:has(>div.bg-primary){color:rgb(31 41 55)!important}.dark .nav-tabs .nav-tabs-item:has(>div.bg-primary){color:rgb(229 231 235)!important}.nav-tabs .nav-tabs-item>div{height:3.5px}#navbar{border-bottom:1px solid rgb(var(--gray-500)/.3)}.dark #navbar{border-bottom:1px solid rgb(var(--gray-500)/.4)}"}],"page":{"pagePath":"cpp/security","slug":"/cpp/security","pageMetadata":{"title":"C++ Security","description":"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.","icon":"lock","href":"/cpp/security"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,hr:`hr`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`overview`,children:`Overview`}),`\n`,_jsx(_components.p,{children:`The GAIA C++ framework executes tool calls requested by the LLM. Without guardrails, a prompt injection could trick the model into calling a sensitive tool with malicious arguments. This guide describes the security primitives available to restrict, validate, and confirm tool calls before they execute.`}),`\n`,_jsx(Heading,{level:`2`,id:`threat-model`,children:`Threat Model`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Threat`}),_jsx(_components.th,{children:`Mitigation`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`LLM requests a sensitive tool it should never call`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`ToolPolicy::DENY`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`LLM passes malformed or dangerous arguments`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`validateArgs`}),` callback`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`LLM calls a high-risk tool without user awareness`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`ToolPolicy::CONFIRM`}),` callback`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`Injected content triggers a destructive `,_jsx(_components.strong,{children:`MCP`}),` tool`]}),_jsx(_components.td,{children:_jsx(_components.a,{href:`#mcp-tools-are-confirm-gated-by-default`,children:`Automatic MCP confirmation gate`})})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`Path traversal via `,_jsx(_components.code,{children:`..`}),` in file arguments`]}),_jsx(_components.td,{children:_jsx(_components.code,{children:`gaia::validatePath()`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Shell injection via user-controlled argument strings`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`gaia::isSafeShellArg()`})})]})]})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`tool-policies`,children:`Tool Policies`}),`\n`,_jsxs(_components.p,{children:[`Every `,_jsx(_components.code,{children:`ToolInfo`}),` has a `,_jsx(_components.code,{children:`policy`}),` field that determines what happens when the registry is asked to execute it:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cgaia/types.h>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`enum`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ToolPolicy`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` ALLOW`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Execute immediately (default)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` CONFIRM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Ask the user before executing`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` DENY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Never execute; return an error to the LLM`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`};`})}),`\n`]})})}),`\n`,_jsxs(Warning,{children:[_jsxs(_components.p,{children:[`The default policy for `,_jsx(_components.strong,{children:`locally registered`}),` tools is `,_jsx(_components.code,{children:`ToolPolicy::ALLOW`}),` — they execute without prompting unless you explicitly set `,_jsx(_components.code,{children:`CONFIRM`}),`, change the default with `,_jsx(_components.code,{children:`setDefaultPolicy()`}),`, or mark individual tools `,_jsx(_components.code,{children:`DENY`}),`. New agents should be explicit about policy on every tool with side effects.`]}),_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`MCP tools are the exception:`}),` they are `,_jsx(_components.code,{children:`CONFIRM`}),`-gated automatically unless the server proves them read-only. See `,_jsx(_components.a,{href:`#mcp-tools-are-confirm-gated-by-default`,children:`MCP tools are CONFIRM-gated by default`}),`.`]})]}),`\n`,_jsx(Heading,{level:`3`,id:`example-require-confirmation-before-a-side-effecting-tool`,children:`Example: require confirmation before a side-effecting tool`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`policy`}),` field is set on the `,_jsx(_components.code,{children:`ToolInfo`}),` struct before you declare the tool’s callback and before you register it with the registry. This is where you choose what gate, if any, the framework places between the LLM’s request and execution.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::ToolInfo info;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"flush_dns\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`description`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Flush the system DNS cache\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`policy`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ToolPolicy`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::CONFIRM;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`callback`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [](`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` /*args*/`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`gaia::json`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::json{{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"ok\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}, {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"message\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"DNS cache flushed\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}};`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`};`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`toolRegistry`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`registerTool`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`move`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(info));`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`#confirmation-callbacks`,children:`Confirmation Callbacks`}),` below for details on the prompt flow.`]}),`\n`,_jsx(Heading,{level:`3`,id:`mcp-tools-are-confirm-gated-by-default`,children:`MCP tools are CONFIRM-gated by default`}),`\n`,_jsxs(_components.p,{children:[`A tool discovered from an MCP server is named by that server, so it can never be matched against a static list of known-dangerous names. `,_jsx(_components.code,{children:`connectMcpServer()`}),` therefore classifies every discovered tool and registers it with `,_jsx(_components.code,{children:`ToolPolicy::CONFIRM`}),` `,_jsx(_components.strong,{children:`unless the server proves it read-only`}),`. A tool is exempt only when both hold:`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`the tool’s `,_jsx(_components.code,{children:`annotations.readOnlyHint`}),` is the JSON boolean `,_jsx(_components.code,{children:`true`}),` — a missing `,_jsx(_components.code,{children:`annotations`}),` object, a non-object value, `,_jsx(_components.code,{children:`false`}),`, or the `,_jsx(_components.em,{children:`string`}),` `,_jsx(_components.code,{children:`\"true\"`}),` all count as unproven; and`]}),`\n`,_jsxs(_components.li,{children:[`the tool name contains no state-changing verb token (`,_jsx(_components.code,{children:`delete`}),`, `,_jsx(_components.code,{children:`write`}),`, `,_jsx(_components.code,{children:`push`}),`, `,_jsx(_components.code,{children:`execute`}),`, `,_jsx(_components.code,{children:`start`}),`, `,_jsx(_components.code,{children:`interact`}),`, …), matched across `,_jsx(_components.code,{children:`snake_case`}),`, `,_jsx(_components.code,{children:`kebab-case`}),` and `,_jsx(_components.code,{children:`camelCase`}),` (including `,_jsx(_components.code,{children:`WRITEFile`}),`).`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`So a server that advertises `,_jsx(_components.code,{children:`delete_file`}),` with `,_jsx(_components.code,{children:`readOnlyHint: true`}),` still gets gated — the name overrides the claim.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// No opt-in required — this is the behaviour after connectMcpServer() returns.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`connectMcpServer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"fs\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, {{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"command\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"npx\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}, {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"args\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"-y\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"some-fs-server\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}}});`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Given what the server reported for each tool:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// read_file {\"readOnlyHint\": true} -> mcp_fs_read_file ALLOW`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// write_file {\"readOnlyHint\": true} -> mcp_fs_write_file CONFIRM (mutating verb)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// list_dir (no annotations) -> mcp_fs_list_dir CONFIRM (unproven)`})}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Because `,_jsx(_components.code,{children:`CONFIRM`}),` is fail-closed, an agent with `,_jsx(_components.code,{children:`silentMode = true`}),` (no confirm callback) `,_jsx(_components.strong,{children:`cannot execute any gated MCP tool`}),`. For headless automation that legitimately needs them, install an explicit callback with `,_jsx(_components.code,{children:`setToolConfirmCallback()`}),` — an intentional opt-in, visible in your code — or pre-approve specific tools through the `,_jsx(_components.a,{href:`#persistent-permissions`,children:`always-allow store`}),`.`]})}),`\n`,_jsxs(_components.p,{children:[`The classifier’s verdict is a floor. `,_jsx(_components.code,{children:`setDefaultPolicy(ToolPolicy::CONFIRM)`}),` or `,_jsx(_components.code,{children:`DENY`}),` can still raise a proven-read-only MCP tool to a stricter policy; nothing lowers a gated tool back to `,_jsx(_components.code,{children:`ALLOW`}),`.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`What the exemption does not cover.`}),` `,_jsx(_components.code,{children:`readOnlyHint`}),` is the server’s own claim, and the verb check is the only counterweight — it knows a fixed vocabulary, so it protects against a careless server, not a hostile one. Two consequences worth knowing:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`A read-only tool can still be an exfiltration channel. A gated-out `,_jsx(_components.code,{children:`web_search`}),` or `,_jsx(_components.code,{children:`fetch_url`}),` reads your context and puts it in a query string; the classifier does not consult `,_jsx(_components.code,{children:`openWorldHint`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`For a server you have not vetted, call `,_jsx(_components.code,{children:`setDefaultPolicy(ToolPolicy::CONFIRM)`}),` before `,_jsx(_components.code,{children:`connectMcpServer()`}),` so nothing from it is exempt.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`changing-the-default-policy`,children:`Changing the Default Policy`}),`\n`,_jsxs(_components.p,{children:[`The framework default is `,_jsx(_components.code,{children:`ToolPolicy::ALLOW`}),`. For a high-security agent — one where every side-effecting local tool should prompt — you can change the blanket default:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`12`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// All local and MCP tools inherit CONFIRM unless explicitly overridden.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`setDefaultPolicy`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ToolPolicy`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::CONFIRM);`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Explicit ALLOW override for a specific read-only tool:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::ToolInfo status_info;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status_info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"get_status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status_info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`policy`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ToolPolicy`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::ALLOW;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`status_info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`callback`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [](`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`gaia::json`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"status\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"ok\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}}; };`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`toolRegistry`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`registerTool`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`move`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(status_info));`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Raises even proven-read-only MCP tools to CONFIRM:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`connectMcpServer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"untrusted\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, {{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"command\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"npx\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}, {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"args\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"-y\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"server\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}}});`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Call `,_jsx(_components.code,{children:`setDefaultPolicy()`}),` before registering tools or calling `,_jsx(_components.code,{children:`connectMcpServer()`}),`. Tools registered afterwards inherit the new default; tools already registered are unaffected.`]}),`\n`,_jsxs(_components.p,{children:[`For MCP tools the default is applied as a `,_jsx(_components.em,{children:`raise`}),`, never a lower: a tool the classifier gated at `,_jsx(_components.code,{children:`CONFIRM`}),` stays gated even under the framework default of `,_jsx(_components.code,{children:`ALLOW`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`ToolPolicy::DENY`}),` for tools the LLM should never invoke — for example, internal-only tools registered for programmatic use but not accessible to the model.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`argument-validation`,children:`Argument Validation`}),`\n`,_jsxs(_components.p,{children:[`The LLM controls what arguments it passes to your tools. A prompt injection or confused model could supply malicious paths, oversized payloads, or unexpected types. The `,_jsx(_components.code,{children:`validateArgs`}),` callback intercepts arguments before the tool callback runs — and before the user sees a confirmation prompt — giving you a chance to sanitize or reject them.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Returns sanitized args or throws std::invalid_argument to reject.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`using`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ToolValidateCallback`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::function`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`json`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::string`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` toolName, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` args)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`example-restrict-file-access-to-a-safe-directory`,children:`Example: restrict file access to a safe directory`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`11`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cgaia/security.h>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`ToolInfo info;`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"read_file\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`info`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`validateArgs`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [](`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`string`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` args`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`json`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::string path `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` args`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"path\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`validatePath`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"/var/gaia/data\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, path)) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` throw`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`invalid_argument`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"path escapes allowed directory\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` args;`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // args are safe; return unchanged`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`};`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Throwing `,_jsx(_components.code,{children:`std::invalid_argument`}),` causes `,_jsx(_components.code,{children:`executeTool()`}),` to return an error JSON. Any other exception propagates normally.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`path-validation`,children:`Path Validation`}),`\n`,_jsxs(_components.p,{children:[`Tools that accept file paths from the LLM are vulnerable to path traversal attacks. An argument like `,_jsx(_components.code,{children:`../../etc/passwd`}),` can escape a sandboxed directory. `,_jsx(_components.code,{children:`validatePath()`}),` canonicalizes both paths using the OS (resolving `,_jsx(_components.code,{children:`..`}),`, symlinks on POSIX) and verifies containment.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cgaia/security.h>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Returns true only if requestedPath is inside basePath`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`bool`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ok `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`validatePath`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"/var/gaia/data\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, userSuppliedPath);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`ok) {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // reject`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`On POSIX this uses `,_jsx(_components.code,{children:`realpath()`}),`, which resolves symlinks and `,_jsx(_components.code,{children:`..`}),` components. On Windows it uses `,_jsx(_components.code,{children:`GetFullPathName()`}),`, which normalizes `,_jsx(_components.code,{children:`..`}),` components but does `,_jsx(_components.strong,{children:`not`}),` follow symlinks. Returns `,_jsx(_components.code,{children:`false`}),` if either path cannot be resolved.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`shell-argument-safety`,children:`Shell Argument Safety`}),`\n`,_jsxs(_components.p,{children:[`If your tool builds a shell command string from LLM-supplied arguments, a single semicolon can turn a filename into arbitrary code execution. `,_jsx(_components.code,{children:`isSafeShellArg()`}),` rejects strings containing any shell metacharacter, ensuring the argument is safe to interpolate into a command.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cgaia/security.h>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::string userArg `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` args`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"interface\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`isSafeShellArg`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(userArg)) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` throw`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`invalid_argument`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"unsafe shell argument: \"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` userArg);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Safe to interpolate into a command string`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::string cmd `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"netsh interface show interface name=\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` userArg;`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Rejected characters include: spaces, tabs, newlines, `,_jsx(_components.code,{children:`;`}),`, `,_jsx(_components.code,{children:`|`}),`, `,_jsx(_components.code,{children:`\u0026`}),`, `,_jsx(_components.code,{children:`\u003c`}),`, `,_jsx(_components.code,{children:`>`}),`, `,_jsx(_components.code,{children:`$`}),`, `,_jsx(_components.code,{children:\"`\"}),`, `,_jsx(_components.code,{children:`\"`}),`, `,_jsx(_components.code,{children:`'`}),`, `,_jsx(_components.code,{children:`!`}),`, `,_jsx(_components.code,{children:`{`}),`, `,_jsx(_components.code,{children:`}`}),`, `,_jsx(_components.code,{children:`(`}),`, `,_jsx(_components.code,{children:`)`}),`, `,_jsx(_components.code,{children:`[`}),`, `,_jsx(_components.code,{children:`]`}),`, `,_jsx(_components.code,{children:`~`}),`, `,_jsx(_components.code,{children:`*`}),`, `,_jsx(_components.code,{children:`?`}),`, `,_jsx(_components.code,{children:`#`}),`, `,_jsx(_components.code,{children:`^`}),`, `,_jsx(_components.code,{children:`%`}),`, `,_jsx(_components.code,{children:`=`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Backslash (`,_jsx(_components.code,{children:`\\\\`}),`) is `,_jsx(_components.strong,{children:`not`}),` rejected because it is a path separator on Windows. If you are building POSIX-only commands, add an explicit backslash check in your `,_jsx(_components.code,{children:`validateArgs`}),` callback.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`confirmation-callbacks`,children:`Confirmation Callbacks`}),`\n`,_jsxs(_components.p,{children:[`When a tool’s policy is `,_jsx(_components.code,{children:`CONFIRM`}),`, the registry calls a `,_jsx(_components.code,{children:`ToolConfirmCallback`}),` before executing:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`enum`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ToolConfirmResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` ALLOW_ONCE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Execute this one call; ask again next time`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` ALWAYS_ALLOW`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Execute and remember the permission permanently`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` DENY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Reject this call; return an error to the LLM`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`};`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`using`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ToolConfirmCallback`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::function`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ToolConfirmResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::string`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` toolName, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` args)`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`zero-config-terminal-agents`,children:`Zero-config terminal agents`}),`\n`,_jsxs(_components.p,{children:[`For agents running in a terminal (`,_jsx(_components.code,{children:`silentMode = false`}),`, which is the default), the `,_jsx(_components.code,{children:`Agent`}),` constructor `,_jsx(_components.strong,{children:`automatically installs a stdin/stderr confirm callback`}),`. Setting `,_jsx(_components.code,{children:`policy = ToolPolicy::CONFIRM`}),` on a tool is all you need:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Registers a tool that auto-prompts in terminal agents — no extra setup required.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`toolRegistry`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`registerTool`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"flush_dns\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Clear DNS cache\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [](`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` /* ... */`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::json{{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"ok\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}}; },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {}, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ToolPolicy`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::CONFIRM);`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`When the LLM calls `,_jsx(_components.code,{children:`flush_dns`}),`, the user sees:`]}),`\n`,_jsx(CodeBlock,{numberOfLines:`8`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` \"flush_dns\" requires confirmation. Allow this tool to run?`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ============================================`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` [1] Allow once`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` [2] Always allow`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` [3] Deny`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ============================================`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` Choice:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(Heading,{level:`3`,id:`silent-/-headless-agents`,children:`Silent / headless agents`}),`\n`,_jsxs(_components.p,{children:[`Agents constructed with `,_jsx(_components.code,{children:`config.silentMode = true`}),` (e.g., unit tests, background automation) receive `,_jsx(_components.strong,{children:`no confirm callback`}),`. Any tool with `,_jsx(_components.code,{children:`CONFIRM`}),` policy is denied automatically (fail-closed). There is no user to ask in a headless context, so blocking is the safe default.`]}),`\n`,_jsxs(_components.p,{children:[`This includes MCP tools, which are `,_jsx(_components.a,{href:`#mcp-tools-are-confirm-gated-by-default`,children:`gated automatically`}),` — a headless agent that calls `,_jsx(_components.code,{children:`connectMcpServer()`}),` will be denied every discovered tool the server did not prove read-only.`]}),`\n`,_jsxs(_components.p,{children:[`If your headless agent needs to approve specific tools automatically, pre-populate `,_jsx(_components.code,{children:`AllowedToolsStore`}),` before the agent starts:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`auto`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` store `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`make_shared`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`AllowedToolsStore`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`>();`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`store`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addAlwaysAllowed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"read_config\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // pre-approved for this agent`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`store`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addAlwaysAllowed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"mcp_windows_Shell\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // MCP names are prefixed`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`toolRegistry`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`setAllowedToolsStore`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(store);`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Alternatively, install an auto-approving callback — an explicit, greppable opt-in rather than a silent default:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`setToolConfirmCallback`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`([](`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`string`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ToolConfirmResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::ALLOW_ONCE;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`custom-ui-agents`,children:`Custom UI agents`}),`\n`,_jsxs(_components.p,{children:[`The default stdin callback is designed for interactive terminals. GUI applications, Electron apps, or remote approval workflows need their own callback. Call `,_jsx(_components.code,{children:`setToolConfirmCallback()`}),` after construction to replace the default:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`agent`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`setToolConfirmCallback`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`([](`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` std`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`string`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` tool`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` json`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` args`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Show a dialog, send a notification, or call a remote approval API.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Return ALLOW_ONCE, ALWAYS_ALLOW, or DENY based on the response.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` bool`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` approved `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` showConfirmDialog`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(tool, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`args`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`dump`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`());`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` approved `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`?`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ToolConfirmResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::ALLOW_ONCE`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` :`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ToolConfirmResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::DENY;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`standalone-toolregistry-usage`,children:`Standalone ToolRegistry usage`}),`\n`,_jsxs(_components.p,{children:[`If you use `,_jsx(_components.code,{children:`ToolRegistry`}),` without an `,_jsx(_components.code,{children:`Agent`}),` — for unit tests, CLI tools, or embedding tool execution in a non-agent application — install the built-in callback yourself:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cgaia/security.h>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::ToolRegistry registry;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`registry`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`setConfirmCallback`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`makeStdinConfirmCallback`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`());`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Fail-closed:`}),` if a tool’s policy is `,_jsx(_components.code,{children:`CONFIRM`}),` and no callback is set, the tool is denied. This prevents accidental execution of sensitive tools in contexts where no user is present.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`persistent-permissions`,children:`Persistent Permissions`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`ALWAYS_ALLOW`}),` decisions are persisted to disk so the user is not asked again across sessions.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Storage location:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`POSIX: `,_jsx(_components.code,{children:`~/.gaia/security/allowed_tools.json`})]}),`\n`,_jsxs(_components.li,{children:[`Windows: `,_jsx(_components.code,{children:`%USERPROFILE%\\\\.gaia\\\\security\\\\allowed_tools.json`})]}),`\n`]}),`\n`,_jsx(_components.p,{children:`The file format is:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`4`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"version\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"allowed_tools\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"read_file\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"check_adapter\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`Agent`}),` constructor creates an `,_jsx(_components.code,{children:`AllowedToolsStore`}),` automatically. You can also manage it directly:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`9`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \u003cgaia/security.h>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`gaia`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::AllowedToolsStore store;`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // uses ~/.gaia/security/`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`store`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`isAlwaysAllowed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"read_file\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // check`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`store`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`addAlwaysAllowed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"read_file\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // add (persists)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`store`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`removeAlwaysAllowed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"read_file\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // remove (persists)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`store`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`clearAll`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // wipe all (persists)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`auto`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` names `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` store`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`allAllowed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // list`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The store is global — all GAIA agents on the machine share one allowed set.`}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Known limitation:`}),` Permissions are stored by tool name only, with no per-agent namespacing. If two agents both register a tool named `,_jsx(_components.code,{children:`read_file`}),`, a user’s “Always Allow” decision for one agent applies to both. Use distinct tool names if you need per-agent permission boundaries.`]})}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`security_demo`}),` example in `,_jsx(_components.code,{children:`cpp/examples/security_demo.cpp`}),` provides an interactive four-mode demo of all features on this page. It requires no Lemonade Server — build it with the rest of the examples and run `,_jsx(_components.code,{children:`./security_demo`}),`.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`recommendations`,children:`Recommendations`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Call `,_jsx(_components.code,{children:`setDefaultPolicy(ToolPolicy::CONFIRM)`})]}),` in production agents that want stricter blanket defaults for their `,_jsx(_components.em,{children:`local`}),` tools. MCP tools are already gated automatically.`]}),`\n`,_jsx(_components.li,{children:_jsxs(_components.strong,{children:[`Use `,_jsx(_components.code,{children:`validateArgs`}),` for every tool that touches the file system or executes shell commands.`]})}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Combine `,_jsx(_components.code,{children:`validatePath`}),` + `,_jsx(_components.code,{children:`isSafeShellArg`})]}),` for tools that build shell command strings from LLM-supplied arguments.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Use `,_jsx(_components.code,{children:`DENY`}),` for tools the LLM should never invoke`]}),` — for example, internal-only tools registered for programmatic use but not accessible to the model.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Review `,_jsx(_components.code,{children:`~/.gaia/security/allowed_tools.json`})]}),` periodically to audit permanently-allowed tools.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"C++ Security","description":"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.","icon":"lock","href":"/cpp/security"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Overview","slug":"overview","depth":2,"children":[]},{"title":"Threat Model","slug":"threat-model","depth":2,"children":[]},{"title":"Tool Policies","slug":"tool-policies","depth":2,"children":[{"title":"Example: require confirmation before a side-effecting tool","slug":"example-require-confirmation-before-a-side-effecting-tool","depth":3,"children":[]},{"title":"MCP tools are CONFIRM-gated by default","slug":"mcp-tools-are-confirm-gated-by-default","depth":3,"children":[]},{"title":"Changing the Default Policy","slug":"changing-the-default-policy","depth":3,"children":[]}]},{"title":"Argument Validation","slug":"argument-validation","depth":2,"children":[{"title":"Example: restrict file access to a safe directory","slug":"example-restrict-file-access-to-a-safe-directory","depth":3,"children":[]}]},{"title":"Path Validation","slug":"path-validation","depth":2,"children":[]},{"title":"Shell Argument Safety","slug":"shell-argument-safety","depth":2,"children":[]},{"title":"Confirmation Callbacks","slug":"confirmation-callbacks","depth":2,"children":[{"title":"Zero-config terminal agents","slug":"zero-config-terminal-agents","depth":3,"children":[]},{"title":"Silent / headless agents","slug":"silent-/-headless-agents","depth":3,"children":[]},{"title":"Custom UI agents","slug":"custom-ui-agents","depth":3,"children":[]},{"title":"Standalone ToolRegistry usage","slug":"standalone-toolregistry-usage","depth":3,"children":[]}]},{"title":"Persistent Permissions","slug":"persistent-permissions","depth":2,"children":[]},{"title":"Recommendations","slug":"recommendations","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/amd-fe836e11/8c80882acf24ecda/server.js"],"subdomain":"amd-fe836e11","siteName":"GAIA SDK","title":"C++ Security - GAIA SDK","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-08-13T13:11:36.144Z","originalFileLocation":"cpp/security.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.\">\u003cmeta data-mint-head name=\"application-name\" content=\"GAIA SDK\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"C++ Security - GAIA SDK\">\u003cmeta data-mint-head property=\"og:description\" content=\"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"GAIA SDK\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://amd-gaia.ai/docs/cpp/security\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://amd-fe836e11.mintlify.app/_mintlify/api/og/v2?division=C%2B%2B+Framework\u0026amp;title=C%2B%2B+Security\u0026amp;description=Production-ready+guardrails+for+the+GAIA+C%2B%2B+agent+framework%3A+tool+policies%2C+argument+validation%2C+user+confirmation%2C+and+path+safety.\u0026amp;theme=930f36e80adfafeb4328e01d\u0026amp;signature=01e7b5633c4e9779793041fe2e4986c2c5410b7d30ee418df3bc045f1a5d941c\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"C++ Security - GAIA SDK\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://amd-fe836e11.mintlify.app/_mintlify/api/og/v2?division=C%2B%2B+Framework\u0026amp;title=C%2B%2B+Security\u0026amp;description=Production-ready+guardrails+for+the+GAIA+C%2B%2B+agent+framework%3A+tool+policies%2C+argument+validation%2C+user+confirmation%2C+and+path+safety.\u0026amp;theme=930f36e80adfafeb4328e01d\u0026amp;signature=01e7b5633c4e9779793041fe2e4986c2c5410b7d30ee418df3bc045f1a5d941c\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/amd-fe836e11/Dg3wj8yq7cr3ck3W/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"GAIA SDK\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#A87B2D\">\u003clink data-mint-head rel=\"canonical\" href=\"https://amd-gaia.ai/docs/cpp/security\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/cpp/security.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://amd-gaia.ai/#organization\",\"name\":\"GAIA SDK\",\"url\":\"https://amd-gaia.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/amd-fe836e11/PgPhi3UrqFX2lV53/assets/favicon.ico?fit=max\u0026auto=format\u0026n=PgPhi3UrqFX2lV53\u0026q=85\u0026s=77bcf8b2d70613766cc02f16b0e208a0\"}},{\"@type\":\"WebSite\",\"@id\":\"https://amd-gaia.ai/docs#website\",\"name\":\"GAIA SDK\",\"url\":\"https://amd-gaia.ai/docs\",\"publisher\":{\"@id\":\"https://amd-gaia.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://amd-gaia.ai/docs/cpp/security#webpage\",\"url\":\"https://amd-gaia.ai/docs/cpp/security\",\"name\":\"C++ Security\",\"description\":\"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.\",\"dateModified\":\"2026-08-13T13:11:36.144Z\",\"isPartOf\":{\"@id\":\"https://amd-gaia.ai/docs#website\"},\"breadcrumb\":{\"@id\":\"https://amd-gaia.ai/docs/cpp/security#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://amd-gaia.ai/docs/cpp/security#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"C++ Framework\",\"item\":\"https://amd-gaia.ai/docs/cpp/setup\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"C++ Security\",\"item\":\"https://amd-gaia.ai/docs/cpp/security\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://amd-gaia.ai/docs/cpp/security#article\",\"headline\":\"C++ Security\",\"name\":\"C++ Security\",\"description\":\"Production-ready guardrails for the GAIA C++ agent framework: tool policies, argument validation, user confirmation, and path safety.\",\"url\":\"https://amd-gaia.ai/docs/cpp/security\",\"mainEntityOfPage\":{\"@id\":\"https://amd-gaia.ai/docs/cpp/security#webpage\"},\"dateModified\":\"2026-08-13T13:11:36.144Z\",\"publisher\":{\"@id\":\"https://amd-gaia.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://amd-gaia.ai/docs#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"GAIA SDK\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"GAIA SDK","nav":{"global":{"anchors":[{"anchor":"GitHub","icon":"github","href":"https://github.com/amd/gaia"},{"anchor":"Discord","icon":"discord","href":"https://discord.com/invite/5xXzkMu8Zk"},{"anchor":"PyPI","icon":"python","href":"https://pypi.org/project/amd-gaia/"}]},"tabs":[{"tab":"Documentation","groups":[{"group":"Getting Started","pages":[{"title":"Welcome","icon":"hand-wave","href":""}]},{"group":"C++ Framework","pages":[{"title":"Setup","icon":"wrench","href":"/cpp/setup"},{"title":"Quickstart","icon":"rocket","href":"/cpp/quickstart"},{"title":"Overview","icon":"code","href":"/cpp/overview"},{"title":"Integration Guide","icon":"puzzle-piece","href":"/cpp/integration"},{"title":"Testing","icon":"flask-vial","href":"/cpp/testing"},{"title":"API Reference","description":"Error handling, thread safety, security, deployment, and complete API for the C++ agent framework","icon":"book-open","href":"/cpp/api-reference"},{"title":"C++ Security","icon":"lock","href":"/cpp/security"},{"group":"User Guides","pages":[{"title":"Bash Coding Agent","description":"AI-powered bash scripting assistant — write, review, test, and debug shell scripts locally on AMD hardware","icon":"terminal","href":"/cpp/bash-agent"},{"title":"System Health Agent","icon":"desktop","href":"/cpp/health-agent"},{"title":"Wi-Fi Troubleshooter Agent","icon":"wifi","href":"/cpp/wifi-agent"},{"title":"Process Analyst Agent","icon":"microchip","href":"/cpp/process-agent"},{"title":"Custom Agent","icon":"sliders","href":"/cpp/custom-agent"}]}]},{"group":"Python Framework","pages":[{"title":"Install GAIA","icon":"download","href":"/guides/install"},{"title":"Setup","icon":"wrench","href":"/setup"},{"title":"Quickstart","icon":"rocket","href":"/quickstart"},{"title":"Agent UI","icon":"desktop","href":"/guides/agent-ui"},{"title":"Terminal UI","icon":"terminal","href":"/guides/tui"},{"title":"Agent Memory","icon":"brain","href":"/guides/memory"},{"group":"User Guides","pages":[{"title":"User Guides","icon":"book","href":"/guides/index"},{"group":"Setup \u0026 Hardware","pages":[{"title":"Hardware Advisor","icon":"microchip","href":"/guides/hardware-advisor"},{"title":"NPU Acceleration","icon":"bolt","href":"/guides/npu"},{"title":"AMD LLM Gateway","href":"/guides/llm-gateway"}]},{"group":"Core Agents","pages":[{"title":"GAIA Agent","icon":"sparkles","href":"/guides/gaia"},{"title":"Complete document inventories","href":"/guides/document-extraction"},{"title":"Choose an AI provider","href":"/guides/ai-providers"},{"title":"Document Q\u0026A","icon":"file-lines","href":"/guides/chat"},{"title":"Browser Use","icon":"globe","href":"/guides/browser-use"},{"title":"Improve GAIA while using it","href":"/guides/harness-engineering"},{"title":"Voice Interaction","icon":"microphone","href":"/guides/talk"},{"title":"Transcription \u0026 Meeting Notes","icon":"file-audio","href":"/guides/transcription"}]},{"group":"Developer Tools","pages":[{"title":"Code Index","icon":"folder-magnifying-glass","href":"/guides/code-index"},{"title":"Project Map","icon":"map","href":"/guides/project-map"}]},{"group":"Connected Agents","pages":[{"title":"Email","icon":"envelope","href":"/guides/email"},{"title":"Slack","icon":"slack","href":"/guides/slack"},{"title":"Telegram Adapter","icon":"paper-plane","href":"/guides/telegram-adapter"}]},{"group":"Build \u0026 Extend","pages":[{"title":"Starter Skills","icon":"puzzle-piece","href":"/guides/starter-skills"},{"title":"Custom Agents","icon":"wand-magic-sparkles","href":"/guides/custom-agent"},{"title":"Composing Skills and Skill Sets","icon":"layer-group","href":"/guides/composing-skills"}]},{"group":"MCP Integration","pages":[{"title":"Agent UI MCP Server","icon":"plug","href":"/guides/mcp/agent-ui"},{"title":"TUI Control MCP Server","icon":"terminal","href":"/guides/mcp/tui"},{"title":"MCP Client","href":"/guides/mcp/client"},{"title":"Windows MCP System Health Agent","icon":"heart-pulse","href":"/guides/mcp/windows-system-health"}]}]},{"group":"Connectors","pages":[{"title":"Connectors","icon":"plug","href":"/connectors/index"},{"title":"Google","icon":"google","href":"/connectors/google"},{"title":"Microsoft","icon":"microsoft","href":"/connectors/microsoft"},{"title":"GitHub","icon":"github","href":"/connectors/github"},{"title":"Tavily","icon":"globe","href":"/connectors/tavily"},{"title":"Connections Security Model","icon":"shield","href":"/security/connections"},{"title":"OAuth Connection Threat Model","icon":"lock","href":"/security/connectors"}]},{"group":"Agent Eval","pages":[{"title":"Agent Eval","icon":"microscope","href":"/guides/eval"},{"title":"Scenario Authoring","icon":"file-pen","href":"/guides/eval-scenarios"},{"title":"CI/CD Integration","icon":"gears","href":"/guides/eval-ci"}]},{"group":"Playbooks","pages":[{"title":"GAIA Playbooks","icon":"book-atlas","href":"/playbooks/index"},{"group":"Hardware Advisor Agent","pages":[{"title":"Building a Hardware Advisor Agent","icon":"microchip","href":"/playbooks/hardware-advisor/index"}]},{"group":"Document Q\u0026A Agent","pages":[{"title":"Part 1: Getting Started with Document Q\u0026A Agents","icon":"book-open-reader","href":"/playbooks/chat-agent/part-1-getting-started"},{"title":"Part 2: Advanced Features \u0026 Customization","icon":"wrench","href":"/playbooks/chat-agent/part-2-advanced-features"},{"title":"Part 3: Deployment \u0026 Optimization","icon":"graduation-cap","href":"/playbooks/chat-agent/part-3-deployment"}]},{"group":"Custom Installer","pages":[{"title":"Custom Installer Playbook","icon":"play","href":"/playbooks/custom-installer/index"}]}]},{"group":"SDK Reference","pages":[{"title":"SDK Reference","icon":"book","href":"/sdk/index"},{"group":"Core Concepts","pages":[{"title":"Understanding the Agent System","icon":"robot","href":"/sdk/core/agent-system"},{"title":"Creating Tools: Giving Agents Superpowers","icon":"screwdriver-wrench","href":"/sdk/core/tools"},{"title":"Output Handlers","icon":"terminal","href":"/sdk/core/console"},{"title":"Agent Patterns Cookbook","icon":"code","href":"/sdk/patterns"}]},{"group":"SDKs","pages":[{"title":"Agent SDK","icon":"comments","href":"/sdk/sdks/chat"},{"title":"Memory SDK","icon":"brain","href":"/sdk/sdks/memory"},{"title":"Agent UI SDK","icon":"desktop","href":"/sdk/sdks/agent-ui"},{"title":"RAG: Teaching Your Agent About Documents","href":"/sdk/sdks/rag"},{"title":"Code Index SDK","icon":"folder-magnifying-glass","href":"/sdk/sdks/code-index"},{"title":"MCP Client","icon":"plug","href":"/sdk/sdks/mcp"},{"title":"LLM Integration","icon":"brain","href":"/sdk/sdks/llm"},{"title":"Vision-Language Models","icon":"eye","href":"/sdk/sdks/vlm"},{"title":"Audio \u0026 Voice","href":"/sdk/sdks/audio"},{"title":"Governance: Optional Policy Layer for Agents","href":"/sdk/sdks/governance"},{"title":"Skills SDK","href":"/sdk/sdks/skills"}]},{"group":"Infrastructure","pages":[{"title":"API Server","href":"/sdk/infrastructure/api-server"},{"title":"MCP Integration","href":"/sdk/infrastructure/mcp"},{"title":"Connectors SDK","href":"/sdk/infrastructure/connectors"}]},{"group":"Agents","pages":[{"title":"Specialized","href":"/sdk/agents/specialized"},{"title":"Talk SDK","href":"/sdk/agents/talk"}]},{"group":"Mixins \u0026 Utilities","pages":[{"title":"Tool Mixins","icon":"puzzle-piece","href":"/sdk/mixins/tool-mixins"},{"title":"DatabaseMixin","icon":"database","href":"/sdk/mixins/database-mixin"},{"title":"FileWatcher","icon":"file-magnifying-glass","href":"/sdk/utils/file-watcher"}]},{"group":"Guides","pages":[{"title":"Application Packaging","icon":"box","href":"/sdk/packaging"},{"title":"Configuration","icon":"gear","href":"/sdk/configuration"},{"title":"Testing","icon":"vial","href":"/sdk/testing"},{"title":"Performance Analysis Plotter","icon":"chart-bar","href":"/sdk/performance-analysis-plotter"},{"title":"Security","icon":"shield-halved","href":"/sdk/security"},{"title":"Best Practices","icon":"star","href":"/sdk/best-practices"}]},{"group":"Resources","pages":[{"title":"Complete Examples","icon":"lightbulb","href":"/sdk/examples"},{"title":"Advanced Patterns","icon":"diagram-project","href":"/sdk/advanced-patterns"},{"title":"API Reference Summary","icon":"book-open","href":"/sdk/api-reference"},{"title":"Migration Guide","icon":"arrow-right-arrow-left","href":"/sdk/migration"},{"title":"Troubleshooting","icon":"circle-question","href":"/sdk/troubleshooting"}]}]}]}]},{"tab":"Python Specifications","pages":[{"title":"Python Specifications","href":"/spec/agent-base"}]},{"tab":"Python Reference","pages":[{"title":"Python Reference","href":"/reference/cli"}]},{"tab":"Python Deployment","pages":[{"title":"Python Deployment","href":"/integrations/vscode"}]},{"tab":"Roadmap","pages":[{"title":"Roadmap","href":"/roadmap"}]},{"tab":"Releases","pages":[{"title":"Releases","href":"/releases"}]}]},"title":"C++ Security - GAIA SDK","buildId":"dpl_GvhK4qVXq51DpfYJLCtPpYNN4YHN","deploymentId":"dpl_GvhK4qVXq51DpfYJLCtPpYNN4YHN","dynamics":[],"chunks":[]}