> ## Documentation Index
> Fetch the complete documentation index at: https://docs.visiqlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS Bedrock

> Bedrock is where your model runs, not what VisIQ governs — pick your agent framework and VisIQ governs it exactly as it does anywhere else.

<Note>
  **Start here if your agents run on Bedrock.** This page routes you to the right
  framework guide and tells you what changes (your model line) and what does not
  (everything about governance). Prerequisites are the same as any other
  quickstart: a VisIQ account ([sign in](https://app.visiqlabs.com)) with a
  harness key from **Settings → Harness Keys**. See
  [Before you start](/quickstart#before-you-start).
</Note>

## There is nothing to install for Bedrock

VisIQ governs the **agent**, at the point where the agent decides to run a tool
or read a document. Bedrock is where the **tokens** come from. Those are different
layers, and that is genuinely good news: pointing LangChain at Bedrock instead of
OpenAI changes one constructor and changes nothing at all about your rules, your
audit trail, or your enforcement points.

So there is no "Bedrock integration" to set up. Follow your framework's guide, then
swap its model line for the Bedrock one below.

<Warning>
  **A "Bedrock connector" would be the wrong shape, and we deliberately did not
  build one.** A connector card promises "install this, get enforcement." Nothing
  you could install at the Bedrock layer governs an agent's tool calls — so the
  card would read as covered while covering nothing, which is the worst failure
  mode a security product has. Governance attaches to the framework.
</Warning>

## Pick your framework

Every row below was run end to end against real Bedrock inference — a real model
choosing real tools, governed at that framework's own first-party hook, with an
ungoverned control arm that had to leak for the run to count.
That is 11 framework adapters, each at 15 of 15 Bedrock scenario checks.&#x20;
Neither number is this page's to assert: both are re-derived from the recorded
payloads in `experiments/matrix-v2/bedrock-agentcore/live/results/`, one file per
row below, by the repo's count gate.

| Framework         | Bedrock model line                                                       | Guide                                               |
| ----------------- | ------------------------------------------------------------------------ | --------------------------------------------------- |
| Strands Agents    | `strands.models.BedrockModel` (native — Bedrock is the default provider) | [Strands](/quickstart/strands)                      |
| LangChain         | `langchain_aws.ChatBedrockConverse`                                      | [LangChain](/quickstart/langchain)                  |
| LangGraph         | `langchain_aws.ChatBedrockConverse`                                      | [LangGraph](/quickstart/langgraph)                  |
| Pydantic AI       | `pydantic_ai.models.bedrock.BedrockConverseModel`                        | [Pydantic AI](/quickstart/pydantic-ai)              |
| LlamaIndex        | `llama_index.llms.bedrock_converse.BedrockConverse`                      | [LlamaIndex](/quickstart/llamaindex)                |
| CrewAI            | `crewai.LLM(model="bedrock/…")`                                          | [CrewAI](/quickstart/crewai)                        |
| Google ADK        | `google.adk.models.lite_llm.LiteLlm(model="bedrock/…")`                  | [Google ADK](/quickstart/google-adk)                |
| OpenAI Agents SDK | `LitellmModel(model="bedrock/…")`                                        | [OpenAI Agents SDK](/quickstart/openai-agents-sdk)  |
| Semantic Kernel   | `semantic_kernel.connectors.ai.bedrock.BedrockChatCompletion`            | [Semantic Kernel](/quickstart/semantic-kernel)      |
| AutoGen           | `autogen_ext.models.anthropic.AnthropicBedrockChatCompletionClient`      | [AutoGen](/quickstart/autogen)                      |
| Claude Agent SDK  | no model class — you point the `claude` CLI it drives at Bedrock         | [Bedrock notes below](#claude-agent-sdk-on-bedrock) |

Each guide has a **Run this on AWS Bedrock** section with the exact constructor
and the caveats that apply to that framework. The Claude Agent SDK is the one row
with no guide of its own; everything Bedrock-specific about it is in the section
immediately below.

## Claude Agent SDK on Bedrock

This framework passed the same bar as every other row above — the same assertions,
the same ungoverned control arm. But it reaches Bedrock by a different route, its
proving run had to happen inside a container, and it carries a coverage limit the
others do not. All three points below matter before you plan around it.

<AccordionGroup>
  <Accordion title="There is no model class to swap — you point the CLI at Bedrock" icon="terminal">
    The SDK does not run the agent loop itself. It drives the **`claude` CLI** over a
    bidirectional JSON control protocol, and the CLI is what talks to a model. So the
    Bedrock switch is environment, not code:

    ```bash theme={null}
    export CLAUDE_CODE_USE_BEDROCK=1
    export ANTHROPIC_MODEL=us.anthropic.claude-haiku-4-5-20251001-v1:0
    ```

    Two consequences. It is **Anthropic-only by construction** — the CLI is Claude's, so
    there is no Nova or Mistral path here. And the model id must be a **cross-region
    inference profile** (the `us.` prefix above); the bare `anthropic.*` id is rejected
    with a `ValidationException`. Anthropic models also need the one-time account form
    described further down this page.
  </Accordion>

  <Accordion title="On macOS the CLI reads the login keychain, so a workstation cannot be forced onto Bedrock" icon="triangle-exclamation">
    On macOS the `claude` CLI resolves its own OAuth credential from the **login
    keychain**, and it prefers that session over anything the environment says.

    Measured on an operator-authenticated Mac: the CLI still answered with
    `CLAUDE_CODE_USE_BEDROCK=1` set, a Bedrock-only model id, a clean `HOME`, every
    inherited `CLAUDE_*` variable stripped, **and every AWS credential removed**. A run
    that cannot fail without AWS credentials was never reaching AWS — so a green
    workstation run proves nothing about Bedrock.

    A **container or CI runner has no keychain**, and that is what makes the check
    honest: with no AWS credentials the run fails (`Control request timeout:
            initialize`), and with them it answers. Run this framework's Bedrock path somewhere
    that has no Claude credential of its own, and keep that credential-free failure as
    your control.
  </Accordion>

  <Accordion title="The CLI's built-in tools are outside the governed seam" icon="triangle-exclamation">
    VisIQ governs this SDK at two of its own first-party points: the **`SdkMcpTool`
    handler wrap**, which is what can actually suppress a call, and the
    **`can_use_tool`** permission callback, which carries the decision and any masked
    arguments.

    Neither reaches the tools the **CLI itself ships**. Measured: asked to "send a
    message", the model ignored the governed `mcp__cell__send_message` and answered
    about the CLI's own team-messaging built-in instead. Nothing of ours was invoked, so
    nothing was governed — and the transcript looks like a normal successful turn.

    **The practical risk is a name collision.** A customer tool whose name overlaps a
    built-in can have the model silently pick the ungoverned one. Name your tools so
    they cannot collide, or disable the built-ins you do not want the model reaching
    for.

    One related measurement, because it changes which layer you should rely on: listing
    a tool in `allowed_tools` **auto-approves it before `can_use_tool` runs** (the SDK
    warns `CanUseToolShadowedWarning`). Enforcement in that case comes entirely from the
    handler wrap, so do not treat the permission callback alone as the control.
  </Accordion>
</AccordionGroup>

## Where AgentCore fits and the one distinction that matters

Bedrock AgentCore has two very different postures, and they are not equally
governable. Getting this wrong is the single most expensive mistake available
here, so it is worth thirty seconds.

<AccordionGroup>
  <Accordion title="AgentCore Runtime — your code, your process. Fully governable." icon="circle-check">
    You package **your own agent** — the same Python you run locally — and AWS
    hosts it. Your framework, your tools, your process. The VisIQ hook runs
    exactly where it runs on your laptop, because it is the same code.

    Nothing about the deployment changes the integration: install the harness in
    your container image, set `VISIQ_API_KEY` in the runtime's environment, and
    the agent registers itself on first run like any other.

    This is the posture to choose if governance matters, and it is the one every
    framework guide's Bedrock section assumes.
  </Accordion>

  <Accordion title="Managed harness — AWS's process. NOT hookable in-process." icon="triangle-exclamation">
    AWS runs the agent loop inside its own service. There is no process of yours
    to put a hook in, so the in-process integration in the framework guides
    **does not apply**. Two real chokepoints remain:

    * **Return control.** Declare your tools so the harness pauses and hands the
      tool call back to you (`stopReason: "tool_use"`) instead of running it. Your
      code holds the decision point: evaluate, then return either the result or a
      refusal. This is a genuine enforcement point — the tool body is yours and
      never runs on a deny.
    * **A Gateway request interceptor.** Governance evaluates the transformed
      request before the target is invoked, so a denied call never reaches the
      Lambda behind it.

    **Built-in tools are the honest limit.** A built-in like the harness's own
    `shell` emits a visible `toolUse` block, so it is auditable — but the harness
    never pauses on it, so there is no point at which anything can intervene.
    Visibility without a decision point is monitoring, not governance. If you need
    to *enforce* on a capability, declare it as your own tool rather than relying
    on a built-in.
  </Accordion>
</AccordionGroup>

## Two Bedrock quirks worth knowing before you debug them

These are AWS behaviours, not VisIQ ones. They are here because both present as
something else entirely, and both cost real time to diagnose.

<AccordionGroup>
  <Accordion title="Amazon Nova rejects hyphenated tool names">
    A tool advertised to a Nova model with a hyphen in its name fails at
    generation time with:

    ```
    ModelErrorException: Model produced invalid sequence as part of ToolUse.
    ```

    It reads like an unstable model. It is not — the same request with an
    underscore instead succeeds every time, and the same hyphenated request
    succeeds on Mistral. This matters most for **Semantic Kernel**, which names
    every function `{plugin}-{function}` and has no setting to change the
    separator, so SK plus a Nova model does not work regardless of governance.
    Use a non-Nova Bedrock model with Semantic Kernel, or an underscore-only
    naming scheme elsewhere.
  </Accordion>

  <Accordion title="Anthropic models on Bedrock need a one-time account form">
    Invoking any `anthropic.*` model returns:

    ```
    Model use case details have not been submitted for this account.
    Fill out the Anthropic use case details form before using the model.
    ```

    It is a one-time submission per AWS account, in the Bedrock console under
    **Model access**. It is not a quota, an IAM policy, or a region problem, and
    no retry clears it. Worth knowing up front if you are using **AutoGen** or the
    **Claude Agent SDK**, whose Bedrock transports are both Anthropic-only.
  </Accordion>
</AccordionGroup>

## Verify it's working

Run your agent once against Bedrock, then open the
[dashboard](https://app.visiqlabs.com):

* **Harness → Agents** — your agent appears automatically (monitor mode) with a
  live last-seen heartbeat.
* **Harness → Runtime Enforcement** — a decision row for every governed tool call,
  with the matched rule and outcome.

New agents start in **monitor** mode (observe-only) until you flip them to
**enforce** on the **Harness → Agents** page. That is unchanged on Bedrock.

## Next steps

<CardGroup cols={2}>
  <Card title="Full Quickstart" icon="rocket" href="/quickstart">
    All supported frameworks and what happens behind the scenes.
  </Card>

  <Card title="Python SDK Reference" icon="book" href="/reference-python">
    The complete `Governor` API — gate\_tool, gate\_documents, fail modes.
  </Card>
</CardGroup>
