Bedrock Web Search: External Access and Domain Filters

TL;DR
30 sec3 min coredeep dive optional

Bedrock web search gained two upgrades on August 19, 2026: an external_web_access switch that lets model calls reach the live web, and AgentCore domain plus publish-date filters that agents cannot bypass at the API layer.

  • external_web_access defaults to true, but live retrieval silently fails without the bedrock-websearch:ExternalWebAccess IAM permission, and AmazonBedrockFullAccess does not include it.
  • The whole feature runs server-side against an Amazon-operated index of tens of billions of documents; with external access off, zero data leaves AWS.
  • The AgentCore side of Bedrock web search, connector 1.2.0, adds runtime domain allow and deny lists of 100 domains each, plus inclusive ISO-8601 date bounds that can narrow, never widen, admin scope.
  • AgentCore Web Search now runs in us-east-1, eu-west-1, and ap-northeast-1, priced at $7.00 per 1,000 queries.

Giving a managed model a search bar used to mean pasting API keys from a third-party search vendor into your agent and hoping compliance nods along. Amazon built the alternative: Web Search on Amazon Bedrock runs the entire search lifecycle inside AWS against its own continuously refreshed index. First announced on August 4 and extended on August 19, 2026, the feature now reaches the live web on request and gives AgentCore agents filter controls that operate at the API layer rather than in a prompt. This tutorial wires both sides and shows where the quiet traps sit.

What changed on August 19

The August 4 general availability gave OpenAI models hosted on Bedrock, specifically GPT-5.4, GPT-5.5, and GPT-5.6 in its Sol, Terra, and Luna variants, a built-in server-side search tool. Two operations power it: Search surfaces page titles, links, and excerpt text drawn from the Amazon index and a built-in knowledge graph, while Fetch pulls the full content of one specific URL. The index reflects new or changed pages within minutes, and one API call returns a grounded answer with citations attached.

The August 19 pair of announcements layered control onto Bedrock web search. Calls on the Bedrock side gained the external_web_access parameter, which decides whether Fetch may leave the AWS boundary on a cache miss. AgentCore’s Web Search connector jumped to version 1.2.0, adding runtime domain allow and deny lists plus published-date bounds, and expanded from a single US region to Ireland and Tokyo. Same-day launches, but they solve different problems: one is about where data may go, the other about which results an agent may see.

Wiring the Bedrock side through bedrock-mantle

Here is the first surprise for experienced Bedrock hands: Bedrock web search is not reachable through bedrock-runtime, Converse, or InvokeModel. Web Search is exposed through the OpenAI Responses API on a dedicated endpoint, https://bedrock-mantle.{REGION}.api.aws/openai/v1, and authentication is not an OpenAI key. You mint a short-lived bearer token, valid up to 12 hours, from your IAM credentials with the aws-bedrock-token-generator package, then hand that token to a standard OpenAI client.

pip install aws-bedrock-token-generator openai

# Mint a bearer token from your IAM credentials (SigV4), valid up to 12 hours
export OPENAI_API_KEY=$(aws-bedrock-token-generator \
  --region us-east-1)
from openai import OpenAI

client = OpenAI(
    base_url="https://bedrock-mantle.us-east-1.api.aws/openai/v1",
)

response = client.responses.create(
    model="openai.gpt-5.6-sol",
    input="Summarize the latest AWS announcements about Bedrock web search.",
    tools=[{"type": "web_search", "external_web_access": True}],
)
print(response.output_text)

Citations come back as url_citation annotations carrying the title, URL, and character offsets into the answer text, and streaming exposes them through annotation events. The search_context_size parameter budgets each Search call at up to 5, 11, or 25 observations for low, medium, and high settings. When results cannot support an answer, the model is documented to say so rather than improvise, which is the behavior you want from a grounding tool.

The external_web_access trap

The parameter defaults to true, and that default hides the sharpest edge in this launch. Live fetching requires the bedrock-websearch:ExternalWebAccess IAM permission, and that permission is not included in AmazonBedrockFullAccess, AmazonMantleFullAccess, or the other broad policies you would expect to cover it. The failure mode is nasty: each Fetch fails its backend authorization, yet the Responses call can still return HTTP 200 with citations drawn from Search observations alone. Your application sees success while the model quietly answers without live page content, and nothing guarantees the model discloses the failed fetch.

Three defenses keep this honest. Set external_web_access explicitly rather than leaning on the default, and pair false with sensitive workloads, because the documentation warns that a live-fetching agent could encode data into a URL it then fetches, a genuine exfiltration channel.

Turn on CloudTrail data events for InvokeSearch and InvokeFetch, which are off by default and billable, and read the fetchedSources field to audit where a Bedrock web search answer got its pages, cache or live web; a citation alone proves nothing about a fetch. And note that denying only InvokeSearch does not disable the tool, since Fetch still works on any URL including model-generated ones; a full opt-out requires denying bedrock-websearch:*

AgentCore filters the model cannot bypass

The AgentCore side of Bedrock web search fixes a different weakness: prompts are not enforcement. Telling an agent in its system prompt to only use.gov sources is a suggestion; the 1.2.0 connector’s filters object is an API-level constraint applied to every tools/call before results return. Each call can carry a domainFilter with include and exclude lists, up to 100 domains per list, and a publishedDateFilter with inclusive ISO-8601 UTC bounds.

{
  "query": "AWS documentation for Bedrock agent web search filters",
  "maxResults": 10,
  "filters": {
    "domainFilter": {
      "include": ["docs.aws.amazon.com", "aws.amazon.com"],
      "exclude": ["medium.com"]
    },
    "publishedDateFilter": {
      "from": "2026-06-01T00:00:00Z",
      "to": "2026-08-19T23:59:59Z"
    }
  }
}

The governance model is where this gets clever. Admin domain lists are attached to the Gateway target and hidden from calling agents; runtime lists arrive per call. Merging follows two rules: include lists intersect across admin and runtime, while exclude lists union. A runtime filter can narrow what the administrator allowed, never widen it, and domains outside the admin allowlist are dropped without ceremony. Root-domain matching covers subdomains, so an include entry for sec.gov covers its subdomain paths.

Expect precision, not recall. When a domain filter is active, results lacking a recognizable domain vanish; when a date filter is active, undated results vanish with them. Set two include lists that share no domains and you get zero results, which is the system telling you your scopes are disjoint. Connector 1.2.0 is additive and backward compatible, and an UpdateGatewayTarget call re-pins an existing 1.1.0 target without recreating it.

Regions and pricing

Bedrock web search with external access runs in US East (N. Virginia), US East (Ohio), and US West (Oregon), with a subset of models in the GovCloud us-gov-west-1 region. AgentCore’s Web Search Tool now serves us-east-1, eu-west-1, and ap-northeast-1, and the Ireland region matters for EU data-proximity requirements. The architecture is strictly regional: every region hosts its own retrieval backend, so a request’s queries, retrieved pages, and results stay inside the region where they arrived, and no query is ever handed to a third-party search engine.

SurfacePricing signal
AgentCore Web Search$7.00 per 1,000 queries, consumption based
AgentCore Gateway$0.005 per 1,000 API invocations
Gateway Search API$0.025 per 1,000 invocations
Bedrock Web Search$12.00 per 1,000 queries per the pricing page
CloudTrail data eventsOpt-in, billable, never logs query text or URLs

A lockdown checklist worth running

Bedrock web search’s security posture is strong by default, and a short checklist keeps it that way after the sprint ships.

Why does a Bedrock feature ride on the OpenAI Responses API?

The answer is the model lineup. Bedrock web search ships for the OpenAI models AWS hosts, and those models already speak the Responses API, the protocol surface their own ecosystem standardized on. Rather than reinvent a server-side tool contract on Converse or InvokeModel, AWS exposed a dedicated bedrock-mantle endpoint that speaks Responses natively, so the web_search tool definition, the annotation format for citations, and the streaming event shapes all match what OpenAI-model tooling already expects.

The practical consequence cuts both ways. Teams whose agents already target the OpenAI SDK can point the client at the AWS endpoint, swap in a token from IAM, and keep their code, which makes adopting Bedrock web search a remarkably short migration.

Teams whose stack is built on Converse or InvokeModel face an awkward fit: the grounded-search path for these models simply is not there yet, and mixing two API families in one application is real complexity. Whether Amazon extends server-side web search to Nova or Anthropic models on the native APIs is the thing to watch; nothing in the current launch suggests it, and nothing forbids it later either.

The Codex detail confirms the strategy. Codex desktop and CLI 0.147.0 and later can use Bedrock Web Search through the same endpoint, with Codex itself choosing external_web_access false so results come back text-only. An OpenAI-native client treating AWS’s endpoint as just another Responses provider is the strongest signal of what this surface is for: meeting developers in the tooling they already run, inside AWS’s data boundary.

For architects, the takeaway is to treat bedrock-mantle as a distinct surface in your diagram, with its own IAM actions, its own token lifecycle, and its own regional endpoints, not as a feature flag on your existing bedrock-runtime integration. That framing prevents the classic mistake of assuming a policy that covers Converse calls also covers Search.

One cost-planning nuance lives in the search_context_size parameter worth knowing before your first bill. The budget caps observations per Search call, not the number of Search calls a model may make in a turn: a model that reformulates and searches four times at the high setting can return up to 25 observations per call. That is usually the right behavior for answer quality, and the token line item stays bounded per call, but dashboards that assume one search per user turn will under-count. Size your alerts on Search-call counts from CloudTrail rather than on user query counts.

How do admin and runtime filter scopes actually merge?

Picture four lists. At the Gateway target, the administrator configures an include list and an exclude list, and calling agents never see them. At call time, the agent may pass its own include and exclude lists in the filters object. The effective scope is then computed: the two include lists intersect, so a domain must appear in both to pass, while the two exclude lists union, so a single deny anywhere is fatal. The asymmetry is deliberate. Narrowing is always permitted; widening never is.

The edge cases are where implementations trip. If the admin include list is unset, the runtime include list operates alone against the whole index. If both include lists are set and disjoint, the result is zero hits, not fallback to the wider scope, which surprises teams that expected union semantics. Root-domain matching extends to subdomains, so sec.gov admits www.sec.gov and any other subdomain path, which is convenient for allowlisting but means you cannot exclude a single subdomain of an included root without listing it in an exclude list and relying on exclude taking precedence.

Date filters obey the same precision-first philosophy. The bounds are inclusive on both ends and apply to the result’s published date, but results with no recognizable publication date are dropped entirely when the filter is active rather than passed through as unknown. For an analyst pulling quarterly guidance, that is the correct trade: an undated document is a citation risk. For a general assistant, it means a date-filtered query reads as “only dated results in this window,” and you should say so in your agent’s user-facing behavior.

The layering maps cleanly onto org design. Compliance owns the admin lists and reviews changes like any production config; product teams own runtime filters and tune them per task without filing tickets. Because runtime can only narrow, the blast radius of a product-team mistake is a thinner result set, never a policy breach. That is what API-level enforcement buys over prompt-level instructions, which a prompt-injection or a careless edit can silently undo.

What can you actually audit when queries never appear in logs?

Start with what CloudTrail records. InvokeSearch and InvokeFetch appear as data events, which are disabled by default and require an enabled trail or event data store, with extra charges. Once on, they log the API activity, but never the query text, the result URLs, or the fetched page content, because query text is treated like an inference prompt and gets the same privacy posture as model input. Your audit trail tells you that searches happened and who invoked them, not what was searched.

The fetchedSources field is the audit bridge. It records whether the pages behind an answer came from the Amazon cache or the live web, which is exactly the question a compliance review asks about an external_web_access-enabled workload. Its subtlety matters: a citation in the answer proves a Search observation existed, not that the cited page was ever fetched, so any control that assumes “cited means retrieved” will over-report live-web access. Build your checks on fetchedSources and the CloudTrail data events together.

Failure auditing is better served than you might expect. When a Fetch fails backend authorization, the AccessDeniedException events name the denied permission and can carry the IAM authorization message, which turns the silent-success trap from the core section into a diagnosable pattern: a workload returning confident answers with no fetch events and a stream of access denied entries is answering from the index alone, and you will know it within one review cycle.

Region isolation closes the audit loop on the data-residency side. Because every region keeps its own retrieval backend, with requests, fetched pages, and results never routed across regional boundaries, the eu-west-1 entry point is not just latency plumbing: a compliance review can scope its questions to one region’s CloudTrail trail and the answer is complete. That property is rare among managed search integrations and worth stating explicitly in your data-flow documentation.

The privacy posture has an operational cost worth budgeting: because query text never lands in CloudTrail, debugging a wrong answer means reproducing it, not grepping a log. Teams that need answer-level lineage capture it at their own application layer, storing the request, the response identifier, and the citation list alongside their business data, where their retention policy can govern it. Design that capture before launch rather than after the first dispute, because the service will not reconstruct it for you later.

For teams with heavier obligations, the honest residual is content-level logging, which this design intentionally does not provide inside the service boundary. If your regulator requires the full query-to-source lineage, you have to capture it at your application layer before the call, which is precisely where your own retention policy can govern it. The acceptable-use terms add one more obligation in the other direction: surfaced outputs must retain and display citations and links, and bulk extraction or reproduction of results is banned, so your audit design should record that your UI complied.