Execution-boundary authorization for OpenAI Agents JS function tools.
Issues · Discussions · AffixIO
AffixIO OpenAI Agents JS adds a host-side authorization check directly around a function tool's execute function. The decision is awaited before the operation can run.
This is an AffixIO integration for OpenAI Agents JS. It is not an official OpenAI package or integration, and it does not modify @openai/agents.
OpenAI Agent
-> tool requests execution
-> AffixIO checks the proposed action
-> ALLOW: the underlying tool executes
-> DENY: the underlying tool does not execute
-> AffixIO proof and receipt are available on the decision
The wrapper is placed on the function passed to tool({ execute }). The decision is awaited at that boundary, before the wrapped function can run. A denied decision or a gate failure throws without calling the underlying function.
npm install @affixio/openai-agents-js @openai/agents affixioThe integration supports AffixIO SDK versions from 1.4.1 through the current major version. It uses the SDK's existing mcpToolGate execution decision and proof path rather than implementing a parallel authorization protocol.
import { Agent, run, tool } from "@openai/agents";
import { AffixSDK } from "affixio";
import { createAffixioIntegration } from "@affixio/openai-agents-js";
const sdk = new AffixSDK({ apiKey: process.env.AFFIX_API_KEY });
const affixio = createAffixioIntegration({
sdk,
tool: "buy_item",
agentId: process.env.AFFIX_AGENT_ID,
mode: "online",
});
const buyItem = async ({ sku, quantity }) => ({ sku, quantity, status: "reserved" });
const buyTool = tool({
name: "buy_item",
description: "Reserve an item after AffixIO authorizes the action.",
parameters: {
type: "object",
properties: { sku: { type: "string" }, quantity: { type: "integer", minimum: 1 } },
required: ["sku", "quantity"],
additionalProperties: false,
},
execute: affixio.guard(buyItem, {
amount: ({ quantity }) => quantity * 10,
currency: "GBP",
category: "retail",
}),
});
const agent = new Agent({
name: "Store assistant",
instructions: "Use buy_item when the customer asks to reserve an item.",
tools: [buyTool],
});
const result = await run(agent, "Reserve two blue notebooks.");
console.log(result.finalOutput);
sdk.dispose();The original input and run context are passed through unchanged. Successful tool return values are returned unchanged. Use onDecision when an application needs to collect the proof or receipt without changing the tool result:
const guarded = affixio.guard(operation, {
onDecision: async decision => auditStore.append(decision),
});AffixioToolDeniedError is thrown for a valid deny decision. Its decision property contains the AffixIO result, including proof and receipt metadata when returned by the SDK.
AffixioGuardError is thrown if the check fails, returns an invalid decision, or the decision callback fails. The wrapped operation is never called in those cases.
AffixIO already exposes mcpToolGate for server-side MCP tool execution. This package does not replace or duplicate that path. It adapts the same SDK gate for OpenAI Agents JS function tools, where the host application owns the execute function.
The wrapper enforces host-side execution authorization. It does not replace OpenAI Agents JS model guardrails, human-in-the-loop flows, input validation, or tool schemas. Keep those controls enabled for their respective purposes.