Tested interoperability guide
NeMo Guardrails tool security with FlareFlow
Keep NeMo's tool allowlist and schema validation, then add a deterministic boundary that controls where a protected value may become plaintext.
authorizeForSink().Why the two layers are complementary
NeMo Guardrails IORails validates tool availability, arguments against JSON Schema, and tool-result linkage and structure. The application remains responsible for executing the tool. That execution boundary is where FlareFlow adds a separate property: an opaque secret token is restored only when its trusted source, detector, runtime-resolved sink, exact JSON Pointer path, and remaining budget all match.
A call can therefore be structurally valid and still be denied. For example, http_fetch may be an allowed tool with a valid URL argument, while policy still forbids moving a protected database credential into that URL.
Define declassification policy in application code
import { createAgentFlow } from 'flare-redact/agent';
const flow = createAgentFlow({
sinks: {
'postgres.execute': {
capabilities: [{
id: 'database-connection',
sources: ['application.config'],
detectors: ['url_credentials'],
paths: ['/args/connectionString'],
maxUses: 1,
}],
budget: { maxUses: 1, maxUniqueValues: 1, maxBytes: 256 },
},
'http.fetch': { capabilities: [] },
},
});
Neither the sink id nor this policy belongs in model output. Build both from deployment configuration and resolve the validated tool name through a closed application registry.
Authorize the NeMo-validated call before execution
const toolRegistry = new Map([
['postgres_execute', { sink: 'postgres.execute', execute: runQuery }],
['http_fetch', { sink: 'http.fetch', execute: runFetch }],
]);
function executeValidatedToolCall(toolCall) {
const tool = toolRegistry.get(toolCall.function.name);
if (!tool) throw new Error('Tool is not in the runtime registry.');
const args = JSON.parse(toolCall.function.arguments);
const local = flow.authorizeForSink(tool.sink, { args });
return tool.execute(local.args);
}
Call protectForModel('application.config', value) before protected data enters model context. A transplanted token inside /args/url is then denied atomically at http.fetch; the same token can be restored at postgres.execute only at /args/connectionString.
Run the proof without a model or API key
git clone https://github.com/flare-collection/flare-redact.git
cd flare-redact
npm install
npm run build
npm --prefix examples/nemo-guardrails-flareflow install
npm --prefix examples/nemo-guardrails-flareflow start
The runnable example uses the same OpenAI-shaped tool-call object that crosses the application boundary. Assertions prove the unauthorized HTTP path is denied, the approved database path works, and the printed report contains no database password.
Security boundary and limitations
- FlareFlow controls exact placeholder restoration; it does not detect prompt injection.
- It cannot protect information that was already sent to the model or leaked by a malicious tool.
- NeMo validation, tool permissions, sandboxing, network egress policy, and least-privilege credentials remain necessary.
- The example is an application-side interoperability pattern, not an NVIDIA plugin or an endorsement.
Inspect the complete integration
Run the tested example, read the normative FlareFlow specification, and compare it with the official NeMo Guardrails architecture.