Cloud-routed agent
An agent reaching Anthropic, OpenAI, or Google models through AWS Bedrock, Azure OpenAI Service, or Vertex AI — IAM-federated, VPC-bound, region-enforced.
A cloud-routed agent is the shape an enterprise reaches for when
direct provider API keys are forbidden by policy and inference
has to land inside the customer's VPC. The model family is the
same as the direct-API shape — anthropic, openai,
google — but the transport is AWS Bedrock, Azure OpenAI
Service, or Google Vertex AI. IAM federates the credential;
region pinning is enforced by the cloud, not the runtime.
Transport packages not yet published.
@pleach/transport-bedrock, @pleach/transport-azure-openai, and
@pleach/transport-vertex are marked private in the monorepo and are
not on npm yet — the npm install / import lines below will not
resolve today. This page documents the planned integration shape; the
transport packages publish in a later cut.
This page walks the four pieces a security architect asks about: the transport-vs-family separation, IAM-federated credential resolution, region constraints, and the cost row that ties the cloud invoice back to the runtime.
Related shapes. Region-pinned agent if the same buyer also locks family per call class and runs a parity suite. Multi-tenant SaaS agent if one runtime serves many customers, each reaching their own cloud account. Regulated-domain agent if the regulator drives the constraint and the cloud is the substrate that makes the deployment reachable.
What you're building
A turn loop whose provider boundary is the cloud, not the lab. The shape is the same regardless of which cloud the buyer landed on:
- Family is the model's identity (
anthropic,openai,google); transport is the route to it (bedrock,azure-openai,vertex). - The credential is an IAM role, a managed identity, or a workload-identity binding — never a long-lived API key.
- The endpoint is a VPC endpoint, a PrivateLink, or a private service connect URL. The cloud enforces that the call doesn't leave the perimeter.
- The cost row carries the cloud, the region, and the model — so the runtime ledger reconciles to the cloud invoice.
Transport vs family
The same family routes through different transports without
forcing a different cascade decision. A session asking for
anthropic can land on the direct API, Bedrock, or both via
failover — the cascade rules don't change.
// lib/runtime.ts
import { SessionRuntime, definePleachPlugin } from "@pleach/core";
export function buildCloudRoutedRuntime(req: AuthedRequest) {
return new SessionRuntime({
provider: bedrockProvider, // transport
storage: new SupabaseAdapter({ client: supabase }),
checkpointer: new SupabaseSaver({ client: supabase }),
plugins: [definePleachPlugin("cleared-tools", { tools: clearedTools })],
permittedFamilies: new Set(["anthropic"]), // family lock
// Transport ("bedrock") and region ("us-east-1") are pinned at the
// provider — `bedrockProvider` above IS the transport, constructed
// against the cleared AWS region — not via a session-config field.
tenantId: req.tenantId,
});
}Why the separation matters under a contract clause: a buyer who
clears anthropic through Bedrock for us-east-1 hasn't cleared
the same family through Azure OpenAI for westeurope. The
transport pin is the structural piece that keeps the cascade
inside the cleared substrate.
IAM-federated credentials
The credential resolver is per-request: an AWS credential provider for Bedrock, managed identity for Azure, Application Default Credentials (including workload identity) for Vertex. The runtime doesn't hold a long-lived key; the cloud's identity layer hands out a short-lived credential that the transport refreshes.
// lib/providers/bedrock.ts
import { createBedrockProvider } from "@pleach/transport-bedrock";
import { fromContainerMetadata } from "@aws-sdk/credential-providers";
export const bedrockProvider = createBedrockProvider({
region: "us-east-1",
credentialProvider: fromContainerMetadata(), // resolved per request, refreshed before expiry
defaultModelId: "anthropic.claude-3-5-sonnet-20241022-v2:0",
});Pass the provider function itself, not a resolved credential. The
transport calls it on the first request and again before the cached
credentials expire (5 minutes early by default, set with
credentialRefreshSkewMs). Azure's managed identity is opt-in
(credential: "default"), and Vertex falls back to ambient ADC when
credentials is omitted. See each transport page for the per-cloud
rules.
The credential itself never reaches the stream. A credential failure
surfaces as a generic "<transport>: authentication failed" error
event, and the underlying error goes only to the server-side
onAuthError hook.
What today ships
Today, @pleach/core ships the family-strict cascade,
permittedFamilies, the deterministic replay path, and the
audit row that records family, model, and region. Bring-your-
own-provider via the AgentProvider contract is the supported
extension point: a host running a Bedrock, Azure OpenAI, or
Vertex endpoint implements the contract directly and threads
the cascade.
For the direct-API path (provider keys held by the runtime),
AnthropicSdkProvider and AiSdkProvider ship in core.
Roadmap
Roadmap pieces, in expected order:
- Publishing the transport packages.
@pleach/transport-bedrock(per-request AWS credentials),@pleach/transport-azure-openai(opt-in managed identity, deployment-name routing), and@pleach/transport-vertex(ADC and workload identity) are source-complete but not on npm yet. Until they publish, use them as workspace dependencies, or implementAgentProvideragainst the cloud API directly. - Cloud-attestation helpers. Per-cloud signable manifests (unsigned unless a key store is configured) that route audit rows into the cloud's native security surface — AWS Security Hub, Azure Sentinel, GCP Chronicle — so the cloud's existing compliance review absorbs the runtime's audit ledger.
- VPC endpoint discovery. A configuration map at v1; a service-discovery integration that resolves PrivateLink endpoints from VPC metadata later.
No dates. Track the upstream package READMEs and CHANGELOG for landing notices.
Region as a hard constraint
Region is enforced by the cloud at the endpoint URL. A request
to a us-east-1 Bedrock endpoint can't land on a us-west-2
model — the cloud rejects it before the runtime sees the
response. The runtime records the region in the audit row, so
an out-of-region attempt is visible in the ledger even when the
cloud has already rejected it.
A buyer with EU residency policy pins the runtime to a
eu-central-1 transport and rejects any session whose context
asks for a different region. The check is a one-line precondition
on buildCloudRoutedRuntime; the cloud is the enforcement
authority.
Cost reconciliation to the cloud invoice
The audit row carries the cloud, the region, the model, and the token count — the same columns the cloud's billing detail breaks out. Reconciliation is one join, not a parallel cost pipeline.
select
family,
model_id,
region,
count(*) as calls,
sum(input_tokens) as input_tokens,
sum(output_tokens) as output_tokens
from harness_auditable_calls
where transport = 'bedrock'
and created_at >= date_trunc('month', now())
group by family, model_id, region;The cloud invoice rolls up the same dimensions. A finance reviewer reading both surfaces sees the same numbers.
Where to go next
Providers
The AgentProvider contract — the extension point a cloud transport implements.
Family lock
The permittedFamilies constraint that scopes which families a session can ever reach.
Region-pinned agent
The sibling shape for direct-API buyers running per-call-class family pins and parity suites.
Audit ledger
The harness_auditable_calls schema and the columns the cost reconciliation reads.
Multi-tenant SaaS agent
Per-tenant runtime construction when each tenant reaches its own cloud account.
Air-gapped deployment
The substrate posture for a perimeter-bound deployment, when the cloud is fully on-prem.
runtime.tenant facet
The `runtime.tenant` primitive — `tenantId` + `subTenantId` accessors, `EventLogWriter` row stamping, RLS, `withTenantHeader`. The type-level surface.
Region-pinned agent
An agent that pins region, family, and model per call class — with parity-validation suites and deterministic failover discipline a procurement reviewer can read.