feat: optional AWS SigV4 auth for the Anthropic provider
- I have looked for existing issues (including closed) about this
Feature Request
Let the Anthropic provider authenticate with AWS SigV4, so it can reach an
Anthropic-compatible endpoint that sits behind AWS, behind a default-off
sigv4 feature.
Motivation
Some AWS endpoints accept Anthropic's own /v1/messages request body but
authenticate with SigV4 rather than an x-api-key header. Today the Anthropic
provider can only send a static API-key header, so those endpoints are
unreachable — not because the wire format differs, but purely because of the
auth scheme.
Concretely, this is what blocks using rig against such an endpoint while still
sending Anthropic-shaped request parameters (thinking, output_config) that
only the Anthropic-compatible surface carries.
Proposal
Add one method to AnthropicCompatibleProvider, with a default:
fn sigv4_region(&self) -> Option<&str> { None }None means no signing is attempted, so every existing implementor is
unaffected and none needs editing. AnthropicExt overrides it, and
AnthropicKey gains a SigV4 { region } variant alongside ApiKey(String).
Signing lives in both request builders, immediately before the body is attached — the SigV4 payload hash covers the exact bytes sent, so it has to follow every mutation of the body. The SigV4 variant emits no static header, because the signature covers the clock as well as the body and so can't be computed once at client construction.
Going through the trait rather than a concrete field is deliberate: completions
run through GenericCompletionModel<Ext, T>, so a concrete field isn't
reachable from the generic path. This matches the provider-integration
checklist in CONTRIBUTING.md, which asks for wire-dialect differences to live
in the trait's hooks.
Considered drawbacks:
- It adds a method to a public trait. Defaulted, so it is not a breaking change, but it does widen the trait's surface.
- The
sigv4feature needsaws-config/default-https-clientandaws-config/rt-tokio, because the workspace pinsaws-configwithdefault-features = falseandload_defaultswalks the full credential chain. Both of those fail at runtime, not compile time, so they're easy to miss. Feature unification means enablingsigv4also givesrig-bedrock'saws-configthose features — additive, but worth stating. - Selecting SigV4 in a build without the feature is a hard error rather than a silently unsigned request, because an unsigned request 401s with a message about a missing API key, which points at the wrong problem.
Alternatives
Use rig-bedrock. It speaks the Bedrock Runtime InvokeModel API — a
different wire protocol against a different endpoint. It doesn't carry the
Anthropic-shaped request body, so it doesn't solve this. The two are
complementary rather than overlapping.
Sign in a custom HttpClientExt. Signing has to happen after the final
request body exists, and the region has to travel from the client to the
request site. Doing it in a client wrapper means duplicating enough of the
provider's request construction to know what the body will be, which is
strictly more coupling than one trait method.
Hand-roll a separate provider. CONTRIBUTING.md explicitly asks for
Anthropic-shaped APIs to go through AnthropicCompatibleProvider instead of a
hand-rolled CompletionModel, so this would work against the stated
architecture.
I have a branch ready with this implemented, clippy-clean and with both test
arms passing (1551 with the feature, 1550 without — the delta is one new test
asserting the signer doesn't emit a host header). Happy to open it as a PR,
or to adjust the shape first if you'd rather the region arrive some other way.
Source: 0xPlaygrounds/rig