Join our Newsletter — 33% off our NHI Course
Home› Guides› Securing OpenAI Agents SDK and Responses API Guide:…
Guide MCP, Protocols & Agent Platforms

Securing OpenAI Agents SDK and Responses API Guide: Tools, Guardrails and Keys

PDF for newsletter subscribers · free to read online

← All guides
By Lalit Choda, NHI Mgmt Group Updated 24 October 2026 16 min read
On this page

An agent built on the OpenAI Agents SDK and the Responses API holds an API key, calls tools with real credentials and sends conversation data to hosted services, so a single over-scoped key or an unapproved tool call can turn a model mistake into a security incident. The SDK gives developers guardrails, approval gates, tool filters and tracing controls, but most of them are opt-in or default to the permissive setting. This guide covers the identity and access model of the OpenAI API platform (organisations, projects, roles, service accounts and key permissions), how tools, MCP servers and handoffs extend an agent's reach, what to log and alert on, and a hardening baseline with the exact SDK settings. It is written for platform engineers, application security teams and identity teams who review or run agents in production. For framework-neutral controls see the Securing Agent Frameworks Guide.

Key takeaways

  • The API key is the agent's identity. The SDK reads OPENAI_API_KEY by default and, unless told otherwise, uses the same key to export traces. Give each agent workload its own project service account key with Restricted permissions.
  • Guardrails are not blocking by default. Input guardrails run in parallel with the agent (run_in_parallel=True), so tools may already have run when a tripwire fires. Set run_in_parallel=False where side effects matter.
  • Approval is opt-in for the riskiest tools. Local ShellTool and ApplyPatchTool default to needs_approval=False, and the SDK's approval step is not a sandbox. Isolation is your job.
  • Hosted tools sit outside the tool guardrail pipeline. Hosted MCP, web search, file search, code interpreter and computer tools, plus handoffs, are not covered by tool_input_guardrails; control them with require_approval, allowed_tools and handoff checks.
  • Traces contain sensitive data unless you say no. trace_include_sensitive_data defaults to True, and Responses objects are stored for 30 days by default. Decide on tracing, store and retention before go-live.

How identity and access work in OpenAI Agents SDK and Responses API

The Agents SDK is a client library: it runs in your process, builds Responses API requests and executes local tools. Every model call, hosted tool call and trace export authenticates to OpenAI with an API key that belongs to a project inside an organisation. The SDK itself has no user model, so who the agent acts for, and what it may do, is decided by the key you give it and the tools you attach.

LayerIdentity or credentialWhere it is setSecurity note
OrganisationHuman members with organisation rolesAPI platform settingsOrganisation owners can see all projects, users and keys
ProjectProject members and service accountsProject settingsResources such as files and stored state are scoped to the project and cannot be moved
API keyUser-owned key or service account keyOPENAI_API_KEY, set_default_openai_key() or a custom clientPermissions All, Restricted or Read Only; the secret is shown once
TracingSame key as model calls by defaultset_tracing_export_api_key()Use a separate key with use_for_tracing=False when model traffic goes elsewhere
Hosted MCP and connectorsOAuth access token in authorizationHostedMCPTool tool_configNot stored by the Responses API; sent on every request
Local MCP and function toolsWhatever credential your code holdsMCPServerStreamableHttp headers, tool codeThe model chooses when the credential is used
End userHashed safety_identifierResponses request parameterAbuse attribution only, not authorisation

Two consequences follow. First, the agent has no notion of the end user's permissions unless your tools enforce them, which is the core of OWASP LLM06:2025 Excessive Agency (excessive functionality, permissions and autonomy). Second, a leaked key gives an attacker the same model, tool and stored-data access as the agent. See the AI Agent Authorisation Guide.

Where state lives

  • Client-managed: result.to_input_list() and SDK session stores keep history in your storage, under your controls.
  • OpenAI-managed: conversation_id (Conversations API) and previous_response_id keep state server side. Anyone holding a key for that project can continue the chain.
  • Retention: OpenAI documents a 30-day application state retention for the Responses API by default or when store=true, plus 30-day abuse monitoring logs. With Zero Data Retention enabled for the organisation, store is always treated as false. Hosted containers, audio outputs and remote MCP servers have their own retention behaviour.

Admin roles and privileged access

Platform roles decide who can mint the keys agents use. Treat them as privileged access and keep the owner population small.

RoleCan doRisk if compromisedControl
Organisation ownerCreate projects, view all projects, users and API keys, set organisation and project spend limits, archive projectsFull control of every agent's credentials and spendTwo to three named owners, SSO with phishing-resistant MFA, quarterly review
Organisation readerJoin projects, run inference, create keys in those projectsCan create new keys in assigned projectsAssign to projects only where needed
Project ownerMember rights plus add users, manage settings, set project spend limits, manage service accounts, archive the projectCan create service accounts and change key permissionsOne owner per project from the owning team, not every developer
Project memberRun inference, use resources, create project keys, read and modify dataKeys with default All permissionsRestrict key creation through custom roles where available
Admin API key holderCall organisation administration endpoints such as /v1/organization/audit_logsOrganisation-wide administrative reachStore in a vault, use only from the security tooling account
  • Default project: every organisation has a Default project that cannot be deleted and inherits the organisation's full configuration. Do not run production agents in it; create one project per agent or per environment.
  • Archiving is permanent: an archived project cannot be restored, so archive only after keys and service accounts have been retired and logs exported.
  • Spend limits: project limits only monitor by default. Turn on "Enforce a hard limit" for agent projects; OpenAI notes enforcement is not instantaneous, so spend can slightly exceed the limit. This also contains OWASP LLM10:2025 Unbounded Consumption.

See the Agentic AI Security Guide for how these roles fit a wider agent governance model.

Integrations, API tokens and service accounts

Service accounts and key permissions

  • Use service accounts for agents: a service account represents a system, is scoped to one project and cannot be used outside it. Creating one issues a key immediately; the secret is shown once, so write it straight into a vault. See the Credential Vaulting for AI Agents Guide.
  • Change the default: a new service account key can read and write all API resources in its project, and its permissions cannot be set in the creation dialog. Edit it afterwards to Restricted, granting Write only to endpoints the agent calls (typically Responses) and None for files, vector stores or fine-tuning it never touches.
  • No user-owned keys in production: user-owned keys default to All permissions and leave with the person. They also break attribution in audit logs.
  • Never in the client: keep keys out of browser and mobile code, notebooks and repositories. The Microsoft Azure OpenAI abuse by Storm-2139 showed exposed customer AI service keys being collected and resold as a hacking-as-a-service offering. See the LLMjacking Guide.

Tool credentials

Tool typeWhere it runsCredential pathPrimary control
Function tools (@function_tool)Your processYour code's credentialstool_input_guardrails, tool_output_guardrails, needs_approval, least-privilege backend scopes
Local MCP (MCPServerStdio, MCPServerStreamableHttp)Your infrastructureAuthorization header in params["headers"]tool_filter, require_approval, server-level tool guardrails
Hosted MCP (HostedMCPTool)OpenAI calls the serverOAuth token in authorizationallowed_tools, require_approval, on_approval_request
Hosted tools (web search, file search, code interpreter)OpenAI infrastructureProject keyAttach only when needed; restrict project key permissions
ShellTool, ApplyPatchTool (local)Your hostHost and process privilegesneeds_approval=True, container or VM isolation, no secrets in environment
ComputerToolYour harnessSigned-in sessions in the browser or desktopon_safety_check, dedicated low-privilege profile
Handoffs and Agent.as_tool()SDK pipelineInherits run contextinput_filter, checks in on_handoff, needs_approval on as_tool
  • Tokens in headers, not URLs: the SDK's MCP documentation says to connect only to trusted servers, use least-privilege credentials, keep access tokens in authorisation fields or headers rather than URLs, and require approval for sensitive operations.
  • Remote MCP servers see your context: OpenAI warns that a malicious server can exfiltrate sensitive data from anything that enters the model's context, and data sent to a remote server follows that server's retention policy. For private servers, Secure MCP Tunnel (tunnel_id) avoids exposing them publicly. See the MCP Security Guide.
  • Per-user OAuth where the tool acts for a person: pass the user's delegated token to the tool rather than a shared integration token, so the backend enforces the user's own rights. See the OAuth Token Exchange and Delegation Guide.
  • Keyless where the platform allows: for your own backends, prefer workload identity federation over static secrets in the agent's environment. See the Cloud Workload Identity Guide.

For a wider view of tool risk, see the AI Agent Tool and Plugin Security Guide; for agents calling other agents, see the Multi-Agent and A2A Security Guide.

Logging and detection

Three log sources matter: the organisation audit log (who changed keys, roles and projects), SDK traces and application logs (what the agent did), and your tool backends (what the credentials actually touched).

SourceEvent or fieldWhat to alert on
Audit logs API (GET /v1/organization/audit_logs, admin key)api_key.created, api_key.updated, api_key.deletedKeys created outside the provisioning pipeline; permission changes to All
Audit logs APIrole.assignment.created, user.added, project.created, project.archivedNew owners, projects outside naming policy
Audit logs APIip_allowlist.updated, login.failedNetwork control changes; repeated failed logins to the platform
Usage and spendProject spend alertsSpikes per key or project, a classic sign of a stolen key
SDK exceptionsInputGuardrailTripwireTriggered, OutputGuardrailTripwireTriggered, ToolInputGuardrailTripwireTriggered, MaxTurnsExceededTripwire rate per agent; repeated tripwires from one safety_identifier
Approval flowToolApprovalItem in RunResult.interruptions, approve or reject decisionsHigh approve rates (rubber-stamping), sticky always_approve decisions
Hosted MCP output itemsmcp_list_tools, mcp_call, mcp_approval_requestTool lists changing between runs; calls to tools not in allowed_tools policy
  • Tracing choices: tracing is on by default. Disable globally with OPENAI_AGENTS_DISABLE_TRACING=1 or set_tracing_disabled(True), per run with RunConfig.tracing_disabled, or keep it and set RunConfig.trace_include_sensitive_data=False (environment variable OPENAI_AGENTS_TRACE_INCLUDE_SENSITIVE_DATA) so generation and function spans omit inputs and outputs. Disabling tracing does not discard data already buffered.
  • Application logs: the SDK uses the openai.agents and openai.agents.tracing loggers. Keep OPENAI_AGENTS_DONT_LOG_MODEL_DATA=1 and OPENAI_AGENTS_DONT_LOG_TOOL_DATA=1 in production so verbose logging does not write prompts and tool payloads to disk.
  • Attribution: send a hashed safety_identifier per end user so abuse can be traced to an account, and correlate it with your own request IDs.

Metrics that show it is working

  1. Percentage of production agent keys that are service account keys with Restricted permissions (target 100%).
  2. Number of organisation and project owners, reviewed quarterly against a named list.
  3. Percentage of write-capable or destructive tools with needs_approval or require_approval="always".
  4. Median age of agent API keys against your rotation policy, and time to revoke after a leak alert.
  5. Guardrail tripwire rate per agent and per thousand runs, with trend.
  6. Approval rejection rate: near zero over months usually means reviewers are not reading.

See the AI Agent Observability and Incident Response Guide.

Hardening baseline

ControlSettingDefaultWhy
Blocking input guardrails@input_guardrail(run_in_parallel=False) for agents with side-effecting toolsParallelPrevents tools running before the tripwire fires
Tool guardrailstool_input_guardrails to block secrets or out-of-policy arguments; tool_output_guardrails to redactNoneChecks each call, not just the final answer
Pre-approval checksToolExecutionConfig(pre_approval_tool_input_guardrails=True)OffReviewers only see calls that already passed policy
Approvalsneeds_approval=True or a callable on write tools; require_approval="always" on hosted MCPOff for local shell and patchHuman or programmatic gate for destructive actions
Tool surfacetool_filter (local MCP), allowed_tools (hosted MCP)All server toolsRemoves excessive functionality
Handoff historyinput_filter or RunConfig.handoff_input_filterFull history passedStops sensitive tool output reaching a less trusted agent
Turn limitKeep max_turns set; never max_turns=None in productionSetBounds loops and spend
Trace datatrace_include_sensitive_data=FalseTrueKeeps prompts and tool data out of traces
Stored statestore=false or ZDR where the use case allowsStored 30 daysReduces data held server side
SpendProject hard limit plus alertsMonitor onlyContains key abuse and runaway agents
  • Keep untrusted text out of instructions: OpenAI's agent safety guidance says to pass untrusted inputs through user messages, not developer messages, and to use structured outputs (enums, fixed schemas) between agents so there is no free-form channel for smuggled instructions. This addresses LLM01:2025 Prompt Injection and ATLAS AML.T0051.001 (indirect prompt injection). See the Prompt Injection Guide.
  • Authorise inside handoffs: is_enabled is evaluated before the model supplies arguments, so it cannot authorise argument values. Do the check at the start of on_handoff and raise on failure.
  • Do not call __wrapped__ in production paths: it bypasses schema validation, guardrails, timeouts and tracing.
  • Scope sticky approvals: always_approve=True persists in the RunContextWrapper and in serialised RunState, and can carry across handoffs to a tool of the same type and name. Use per-call approvals where permissions differ, and a fresh wrapper for new runs.

Rollout plan

  1. Inventory: list every agent, its project, key type, key permissions, tools and MCP servers. Export the audit log baseline.
  2. Re-key: create a project and service account per agent, set Restricted permissions, store keys in a vault, and move traffic over. Keep the old key for a short overlap, then revoke.
  3. Observe: deploy tool guardrails that log but do not trip (return tripwire_triggered=False with output_info) for two weeks to measure false positives.
  4. Enforce in a pilot: turn on blocking guardrails, approvals and tool filters for one agent, then expand by risk tier. Roll back by reverting the agent configuration; keys and projects stay as they are.
  5. Operate: wire audit log events and tripwire metrics into the SIEM, run quarterly role reviews and red-team exercises with injected tool content.

Small team or large estate: a small team can start with one project per environment, Restricted keys and approvals on every write tool. A larger organisation should run one project per agent, enforce key creation only through a pipeline, alert on any api_key.created event from a human, and put an MCP gateway in front of shared servers. See the MCP Gateway and MCP Server Governance Guide.

Framework mapping

RiskATT&CK / ATLASNIST SP 800-53 Rev. 5NIST CSF 2.0OWASP LLM 2025
Leaked or stolen API keyT1552.001 Credentials In Files, T1078.004 Cloud AccountsIA-5, IA-9PR.AA-01LLM10
Over-scoped tools and keysAML.T0053 AI Agent Tool InvocationAC-6, CM-7PR.AA-05LLM06
Injected instructions in tool contentAML.T0051.001 IndirectSI-10DE.CM-09LLM01
Data exfiltration through toolsAML.T0086 Exfiltration via AI Agent Tool InvocationAC-4PR.DS-02LLM02
Missing audit trailNot applicableAU-2, AU-12DE.CM-03Not applicable

Common misconfigurations

  • One key for everything: a single user-owned key with All permissions in development, CI and production. A leak from any one place exposes all of them, and the audit log cannot tell which agent did what.
  • Guardrail that fires too late: an input guardrail left in parallel mode on an agent that sends email or writes records. The guardrail trips, but the tool call has already happened.
  • Shell tool on the host: a local ShellTool with needs_approval=False running in a container that also holds cloud credentials in environment variables. The SDK documentation is explicit that its approval is not a sandbox.
  • Hosted MCP with approvals off: require_approval="never" copied from a sample into production, with every tool on the server allowed and a broad OAuth token in authorization.
  • Full history on handoff: a triage agent with access to customer records hands off to a web-browsing agent, which receives the whole transcript, including tool outputs, because no input_filter was set.
  • Sensitive traces by default: tracing left on with sensitive data included, so prompts, customer data and tool results sit in a trace store that more people can read than the production database.

Practitioner checklist

  • Run each production agent under its own project service account key with Restricted permissions, stored in a vault.
  • Limit organisation owners to a short named list and review all owner and project owner assignments quarterly.
  • Enable project hard spend limits and alerts for every agent project.
  • Set run_in_parallel=False on input guardrails for agents with side-effecting tools, and add tool input and output guardrails.
  • Require approval on every write or destructive tool, and scope always_approve decisions narrowly.
  • Restrict MCP tools with tool_filter or allowed_tools, pass tokens in headers, and keep hosted MCP approvals on.
  • Isolate local shell, patch and computer tools in a sandbox with no secrets and minimal network access.
  • Set input_filter on handoffs and authorise argument-bearing handoffs in on_handoff.
  • Decide tracing, trace_include_sensitive_data, store and ZDR settings and document them.
  • Pull /v1/organization/audit_logs into the SIEM and alert on key and role changes.

Standards and references

Related NHI Mgmt Group resources: Securing Agent Frameworks Guide · Credential Vaulting for AI Agents Guide · AI Agent Tool and Plugin Security Guide · Multi-Agent and A2A Security Guide · Cloud Workload Identity Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Written and reviewed by Lalit Choda, NHI Mgmt Group. Last updated 24 October 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.