diff --git a/docs/ai-coder/ai-gateway/setup.md b/docs/ai-coder/ai-gateway/setup.md index be830a74c2..06a0e2637a 100644 --- a/docs/ai-coder/ai-gateway/setup.md +++ b/docs/ai-coder/ai-gateway/setup.md @@ -53,18 +53,40 @@ Anthropic does not allow [API keys](https://console.anthropic.com/settings/keys) Set the following when routing [Amazon Bedrock](https://coder.com/docs/reference/cli/server#--aibridge-bedrock-region) traffic through AI Gateway: -- `CODER_AIBRIDGE_BEDROCK_REGION` or `--aibridge-bedrock-region` -- `CODER_AIBRIDGE_BEDROCK_ACCESS_KEY` or `--aibridge-bedrock-access-key` -- `CODER_AIBRIDGE_BEDROCK_ACCESS_KEY_SECRET` or `--aibridge-bedrock-access-key-secret` +**Required:** + +- `CODER_AIBRIDGE_BEDROCK_REGION` or `--aibridge-bedrock-region`. +Alternatively, set `CODER_AIBRIDGE_BEDROCK_BASE_URL` or `--aibridge-bedrock-base-url` to a full URL (e.g., when routing through a proxy between AI Gateway and AWS Bedrock or using a non-standard endpoint that doesn't follow the `https://bedrock-runtime..amazonaws.com` format). +If both are set, `CODER_AIBRIDGE_BEDROCK_BASE_URL` takes precedence. - `CODER_AIBRIDGE_BEDROCK_MODEL` or `--aibridge-bedrock-model` - `CODER_AIBRIDGE_BEDROCK_SMALL_FAST_MODEL` or `--aibridge-bedrock-small-fast-model` -> [!NOTE] -> `CODER_AIBRIDGE_BEDROCK_BASE_URL` or `--aibridge-bedrock-base-url` may be used instead of `CODER_AIBRIDGE_BEDROCK_REGION`/`--aibridge-bedrock-region` -if you would like to specify a URL which does not follow the form of `https://bedrock-runtime..amazonaws.com` - for example if using a -proxy between AI Gateway and AWS Bedrock. +**Optional:** -#### Obtaining Bedrock credentials +- `CODER_AIBRIDGE_BEDROCK_ACCESS_KEY` or `--aibridge-bedrock-access-key` +- `CODER_AIBRIDGE_BEDROCK_ACCESS_KEY_SECRET` or `--aibridge-bedrock-access-key-secret` + +#### Authentication + +AI Gateway supports two credential configuration paths: + +##### AWS SDK default credential chain (recommended) + +When no credentials are set in AI Gateway config, the AWS SDK resolves them automatically from the environment. +This includes IAM Roles (instance profiles, IRSA, ECS task roles), shared config files, environment variables, SSO, and more. + +**IAM Roles are the recommended approach** when AI Gateway runs on AWS infrastructure. +Attach an IAM Role with Bedrock permissions to the compute running AI Gateway (EC2 instance, EKS pod via IRSA, or ECS task), no credentials need to be configured in AI Gateway itself. + +The IAM Role must have permission to invoke the Bedrock models configured for AI Gateway (`bedrock:InvokeModel` and `bedrock:InvokeModelWithResponseStream`). +See [Amazon Bedrock identity-based policy examples](https://docs.aws.amazon.com/bedrock/latest/userguide/security_iam_id-based-policy-examples.html) for policy examples, +and [AWS IAM role creation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html) for general guidance on attaching roles to AWS services. + +This aligns with [AWS best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) for using temporary credentials instead of long-lived access keys. + +##### Static credentials + +For deployments when explicit credentials are preferred, provide an access key and secret for an IAM User: 1. **Choose a region** where you want to use Bedrock. diff --git a/enterprise/cli/aibridged.go b/enterprise/cli/aibridged.go index 3c03e0b18b..163b3036a8 100644 --- a/enterprise/cli/aibridged.go +++ b/enterprise/cli/aibridged.go @@ -159,7 +159,11 @@ func bedrockConfigFromProvider(p codersdk.AIBridgeProviderConfig) *aibridge.AWSB } func getBedrockConfig(cfg codersdk.AIBridgeBedrockConfig) *aibridge.AWSBedrockConfig { - if cfg.Region.String() == "" && cfg.BaseURL.String() == "" && cfg.AccessKey.String() == "" && cfg.AccessKeySecret.String() == "" { + // Bedrock is considered disabled when no region or base URL is configured. + // Static credentials are optional. When not provided, the AWS SDK default + // credential chain resolves credentials (environment variables, shared config, + // IAM roles, etc.). + if cfg.Region.String() == "" && cfg.BaseURL.String() == "" { return nil } diff --git a/go.mod b/go.mod index 69cdd26e09..17bd65bb7c 100644 --- a/go.mod +++ b/go.mod @@ -504,7 +504,7 @@ require ( github.com/aymanbagabas/go-udiff v0.4.1 github.com/brianvoe/gofakeit/v7 v7.14.0 github.com/coder/agentapi-sdk-go v0.0.0-20250505131810-560d1d88d225 - github.com/coder/aibridge v1.1.2 + github.com/coder/aibridge v1.1.3-0.20260420072253-d474d6813420 github.com/coder/aisdk-go v0.0.9 github.com/coder/boundary v0.8.4-0.20260304164748-566aeea939ab github.com/coder/preview v1.0.8 diff --git a/go.sum b/go.sum index dfe400b24d..935599ddc2 100644 --- a/go.sum +++ b/go.sum @@ -312,8 +312,8 @@ github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/coder/agentapi-sdk-go v0.0.0-20250505131810-560d1d88d225 h1:tRIViZ5JRmzdOEo5wUWngaGEFBG8OaE1o2GIHN5ujJ8= github.com/coder/agentapi-sdk-go v0.0.0-20250505131810-560d1d88d225/go.mod h1:rNLVpYgEVeu1Zk29K64z6Od8RBP9DwqCu9OfCzh8MR4= -github.com/coder/aibridge v1.1.2 h1:DLz0B7j9qzGj/nVQUbWDluux2c/y7+a7xGgc+63uOUM= -github.com/coder/aibridge v1.1.2/go.mod h1:k2/JzBF/jW2h4xKYyXXy9gbD7qaf0kKvfXxwA2JCYxE= +github.com/coder/aibridge v1.1.3-0.20260420072253-d474d6813420 h1:vSgHLbHvty3Y9DXAKZimP/GXKI23o52PlTC+EJYh6tM= +github.com/coder/aibridge v1.1.3-0.20260420072253-d474d6813420/go.mod h1:k2/JzBF/jW2h4xKYyXXy9gbD7qaf0kKvfXxwA2JCYxE= github.com/coder/aisdk-go v0.0.9 h1:Vzo/k2qwVGLTR10ESDeP2Ecek1SdPfZlEjtTfMveiVo= github.com/coder/aisdk-go v0.0.9/go.mod h1:KF6/Vkono0FJJOtWtveh5j7yfNrSctVTpwgweYWSp5M= github.com/coder/anthropic-sdk-go v0.0.0-20260415160422-a31d7d0e7067 h1:v1RAkUO21u0QH6UlUueSHMbgFf++BZZW41Rj6LM2eWo=