feat(llm): Amazon Bedrock provider over a standard-library SigV4 signer

Kind `bedrock` speaks the Converse API for chat roles and InvokeModel for
Titan and Cohere embeddings. Requests are signed with AWS Signature
Version 4 implemented with crypto/hmac and crypto/sha256 only; the signer
is pinned by tests to signatures botocore produces for the same requests,
with and without a session token, so drift fails the build.

The credential is one secret reference, ACCESS_KEY_ID:SECRET_ACCESS_KEY
[:SESSION_TOKEN], encrypted together like every other provider key. The
region is read from the endpoint host, which must be a Bedrock runtime
host over HTTPS unless private endpoints are explicitly allowed; other
hosts are refused. Provider errors are scrubbed of the secret and token.

Migration 0024 widens the provider kind constraint; existing rows are
untouched and the down migration refuses while bedrock rows exist rather
than dropping configuration. UI kind selects, docs/llm-providers.md,
ADR-0010, ARCHITECTURE and the changelog are updated.
This commit is contained in:
Andy Dixon
2026-08-24 22:03:48 +01:00
parent 7d608c2783
commit f165adc5f2
14 changed files with 497 additions and 6 deletions
+6 -1
View File
@@ -116,10 +116,13 @@ const (
KindOpenAI ProviderKind = "openai"
KindAnthropic ProviderKind = "anthropic"
KindOllama ProviderKind = "ollama"
KindBedrock ProviderKind = "bedrock" // Amazon Bedrock Converse API, SigV4-signed
)
// Valid reports whether k is supported.
func (k ProviderKind) Valid() bool { return k == KindOpenAI || k == KindAnthropic || k == KindOllama }
func (k ProviderKind) Valid() bool {
return k == KindOpenAI || k == KindAnthropic || k == KindOllama || k == KindBedrock
}
// DefaultEndpoint suggests a base URL per kind.
func (k ProviderKind) DefaultEndpoint() string {
@@ -130,6 +133,8 @@ func (k ProviderKind) DefaultEndpoint() string {
return "https://api.anthropic.com"
case KindOllama:
return "http://127.0.0.1:11434"
case KindBedrock:
return "https://bedrock-runtime.eu-west-2.amazonaws.com"
}
return ""
}