AWS Bedrock

Connect AWS Bedrock to ACOG with access keys or a role ACOG assumes, including GovCloud, batch processing and native boto3 access.

4 min read Updated View as Markdown Report a problem

A Bedrock connection calls models in your own AWS account: Claude and the other models Bedrock hosts. Requests are signed with AWS Signature Version 4 for the connection’s region.

Before you start

  • Enable the models you want under Model access in the Bedrock console, in the region you will use.
  • Choose how ACOG authenticates:
MethodWhat ACOG storesNotes
Access keysAn access key ID and secret access key (and optionally a session token), encryptedSimple. Rotate the keys yourself.
Assume roleThe role’s ARN; optionally access keys used only to assume itACOG assumes the role with an external ID issued for your organization. No long-lived key is needed.

The identity needs bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream on the models you declare, and bedrock:ListFoundationModels so ACOG can list them.

Connect with access keys

  1. Create an IAM user (or use an existing one) with the permissions above and create an access key.
  2. In ACOG, open Admin → Providers → Connect provider, choose Bedrock, select Access keys, and enter the region, access key ID and secret access key.
  3. Review the models and choose a default.

Connect with a role (assume role)

When ACOG assumes a role in your account, it passes an external ID that ACOG issues for your organization. This is AWS’s protection against the confused deputy problem: someone who learns your role’s ARN still cannot use it through ACOG, because only your organization’s requests carry your external ID.

  1. In ACOG, start a Bedrock connection and select Assume role. The console shows your organization’s external ID and the AWS principal ACOG uses.
  2. In AWS, create a role with the Bedrock permissions above and this trust policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "<the principal shown in the console>" },
      "Action": "sts:AssumeRole",
      "Condition": { "StringEquals": { "sts:ExternalId": "<your organization's external ID>" } }
    }
  ]
}
  1. Enter the role ARN in ACOG and save.

When ACOG’s own identity assumes the role, ACOG checks the trust policy before saving: it must be able to assume the role with your external ID, and it must be refused with no external ID and with several IDs that differ from yours. A trust policy without the sts:ExternalId condition, or one that matches by pattern (StringLike), is refused with the same message as a role ACOG cannot assume. Use StringEquals with exactly your ID.

If you supply your own access keys on an assume-role connection, your keys assume the role, and ACOG still passes your organization’s external ID.

You can read your external ID at any time with GET /v1/orgs/{org}/providers/bedrock-external-id. It never changes.

Connections created before external IDs were issued

A role connection saved before ACOG issued external IDs keeps its old external ID (or none) until a switch date, 90 days after your organization’s ID was issued. Your admins are told the date. On that date the connection switches to your organization’s ID, and if the role does not require exactly that ID, the connection is suspended until you fix the trust policy and edit the connection. To switch early, allow both IDs in the trust policy ("sts:ExternalId": ["<old>", "<new>"]), then edit the connection to use the new one.

Regions and GovCloud

Enter any Bedrock region, including the AWS GovCloud (US) regions us-gov-west-1 and us-gov-east-1. Signing follows the region’s partition, and role and bucket ARNs in GovCloud use the arn:aws-us-gov: prefix.

Cross-region inference profiles work: declare the profile id (for example us.anthropic.claude-sonnet-4-5-20250929-v1:0) as a model.

Batch processing (optional)

With a storage location, ACOG can run requests nobody is waiting for as Bedrock batch inference jobs, at about half the on-demand price. See Batch routing.

SettingValue
Batch storages3://bucket[/path]. The bucket name may not contain dots.
Batch role ARNThe IAM role Bedrock’s CreateModelInvocationJob runs as, with read and write access to the bucket

The connection’s identity also needs bedrock:CreateModelInvocationJob, bedrock:GetModelInvocationJob and iam:PassRole on the batch role, plus read and write access to the bucket. Leave all batch settings empty to turn batch processing off for the connection.

Native Bedrock access with boto3

Code that already uses boto3 can call Bedrock through ACOG with only two changes: the endpoint URL and the credentials. ACOG verifies your request’s signature, then re-signs it to Bedrock with the connection’s own credentials.

  1. Issue an ACOG Bedrock credential (requires the Create and revoke API keys permission, admin:keys):
curl -s -X POST https://acog.tessarac.com/api/v1/orgs/$ORG_ID/bedrock-credentials \
  -H "Authorization: Bearer $ACOG_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "batch-jobs"}'

The response contains an access_key_id that begins with ACOG and a secret_access_key that is shown only once.

  1. Point boto3 at ACOG:
import boto3

bedrock = boto3.client(
    "bedrock-runtime",
    region_name="us-east-1",
    endpoint_url="https://gateway.acog.tessarac.com/bedrock",
    aws_access_key_id="ACOG...",
    aws_secret_access_key="...",
)

response = bedrock.converse(
    modelId="anthropic.claude-haiku-4-5-20251001-v1:0",
    messages=[{"role": "user", "content": [{"text": "Hello"}]}],
)
print(response["output"]["message"]["content"][0]["text"])

Signatures are accepted within five minutes of ACOG’s clock. See Native provider routes.

Troubleshooting

What you seeCauseFix
422 model_access_requiredThe model is not enabled in Bedrock Model access for the regionRequest access in the Bedrock console
Save refused: role cannot be assumedThe trust policy does not allow ACOG’s principal with exactly your external ID, or allows other IDs tooUse the trust policy above, with StringEquals
The connection card says suspendedThe role does not require your organization’s external ID after the switch dateUpdate the trust policy, then edit and save the connection
403 with “request signature verification failed” on the /bedrock routeThe signature does not match an issued ACOG credential, or the clock is more than five minutes offUse the ACOG… credential and check the client’s clock