mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
## Bug
Under `/agents/settings/api-keys`, a personal API key saved for a
Bedrock provider never took effect. AI Gateway forwarded the saved
value, but the Bedrock interceptors re-signed every request with the
deployment's AWS credentials (SigV4), overwriting the `Authorization`
header. The key was silently dropped, so users were unknowingly still
billed to the administrator's AWS account with no way to bring their own
credentials.
## Fix
Apply the user's Bedrock key instead of discarding it. AWS Bedrock API
keys are bearer tokens (`Authorization: Bearer <key>`), so when a
personal key is present AI Gateway now sends it as a bearer token and
skips SigV4 signing. This covers every Bedrock route:
- **InvokeModel** (`/v1/messages`): applies the same wire transform as
the signed path (`/model/{model}/invoke[-with-response-stream]`,
`anthropic_version`, `anthropic-beta` → body, `model`/`stream`
stripping) but sets a bearer `Authorization` header instead of signing.
- **Mantle** (`/v1/messages`, `/v1/responses`, `/v1/chat/completions`):
passthrough with a bearer `Authorization` header instead of signing.
The bearer paths resolve no deployment AWS credentials, so BYOK works
even where the deployment has none. Requests without a personal key keep
the existing SigV4 behavior.
This also reverts the earlier interim guard that hid the key field and
rejected Bedrock key upserts: the field is shown again and the API
accepts the keys, because they now work.
<details>
<summary>Implementation notes</summary>
**Gateway (`aibridge`)**
- `messages.newMessagesService` detects BYOK on a Bedrock interception
and routes it through bearer-token option builders instead of the SigV4
path.
- `withBedrockInvokeModelBYOKOptions` /
`bedrockInvokeModelBearerMiddleware` reimplement the Anthropic SDK's
`bedrock.WithConfig` wire transform without signing, because that helper
couples the transform with SigV4 and would resolve deployment
credentials a BYOK request must not depend on.
- `bedrocksig.BearerMiddleware` is shared by the Messages, Responses,
and chat-completions interceptors for the Mantle passthrough; each
installs it in place of `SignMiddleware` when the credential is BYOK.
- Streaming decoding is unchanged: the Bedrock event-stream decoder is
registered by the SDK package's `init` and selected by response
content-type, independent of `bedrock.WithConfig`.
**coderd / SDK / frontend / docs**
- Removed the interim guard and `supports_user_api_key` capability flag;
restored the API-key field for Bedrock providers.
- Docs describe the Bedrock personal key as an AWS Bedrock API key
forwarded as a bearer token for every model family Bedrock serves.
**Tests**
- Unit: bearer middleware transform + auth for InvokeModel; shared
bearer middleware; option-builder validation.
- Integration: end-to-end through the bridge for InvokeModel, Mantle
Messages, Mantle Responses, and Mantle chat completions, asserting
`Authorization: Bearer <key>`, no `X-Amz-*` headers, correct upstream
path/model, no `X-Api-Key` leak, and that InvokeModel streaming decodes
real AWS binary event-stream frames.
- coderd: Bedrock key upserts succeed.
</details>
Closes
[CODAGT-699](https://linear.app/codercom/issue/CODAGT-699/bedrock-provider-settings-for-byok-only-expose-one-api-key).
---
*This PR was generated by Coder Agents on behalf of @f0ssel.*