AWS SigV4 Plugin
This plugin adds an aws-sigv4 request-signing scheme to the credential proxy. It covers credentials AWS never receives directly: every AWS API request carries a signature computed with the secret access key, so plain placeholder substitution cannot broker them.
With this plugin, the agent’s AWS SDK signs requests normally using the placeholder credentials varlock injects into its environment. The proxy parses the region and service out of the inbound credential scope, strips the placeholder signature, and re-signs the request with the real keys at the network boundary. The secret access key never enters the agent’s environment, and the agent cannot produce a valid signature itself.
# @plugin(@varlock/aws-sigv4-plugin)# ---# @proxy(domain="*.amazonaws.com", transform={# scheme="aws-sigv4", keyId=$AWS_ACCESS_KEY_ID,# allowedServices=[bedrock, s3],# })AWS_SECRET_ACCESS_KEY=yourPreferredPlugin()
# @sensitiveAWS_ACCESS_KEY_ID=yourPreferredPlugin()No SDK configuration is needed beyond pointing it at the proxy (which varlock proxy run does): the SDK signs with the placeholder credentials it sees, and one rule covers every AWS service and region the client talks to.
Beyond AWS
Section titled “Beyond AWS”SigV4 is AWS’s protocol, but it is also the auth standard across the S3-compatible ecosystem, since those services are built to work with the AWS SDKs unchanged: Cloudflare R2, MinIO, Backblaze B2 (S3 API), DigitalOcean Spaces, Wasabi, IBM Cloud Object Storage, and Google Cloud Storage’s XML interop mode with HMAC keys (which signs with an s3 service scope). DynamoDB-compatible endpoints such as ScyllaDB Alternator work the same way.
The client is still an AWS SDK pointed at a custom endpoint, so the request carries a normal SigV4 credential scope, and the rule’s domain decides where the scheme applies:
# @plugin(@varlock/aws-sigv4-plugin)# ---# Broker Cloudflare R2 credentials the same way:# @proxy(domain="myaccount.r2.cloudflarestorage.com", transform={# scheme="aws-sigv4", keyId=$R2_ACCESS_KEY_ID,# })R2_SECRET_ACCESS_KEY=yourPreferredPlugin()
# @sensitiveR2_ACCESS_KEY_ID=yourPreferredPlugin()The same limitations apply as for AWS itself. In particular, current AWS SDKs default requestChecksumCalculation to WHEN_SUPPORTED, which makes S3-style uploads use aws-chunked streaming payloads that the proxy cannot re-sign; set it to WHEN_REQUIRED on the client for those calls. See the limitations below.
Options
Section titled “Options”| Option | Meaning |
|---|---|
keyId | (required) Reference to the item holding the AWS access key id, e.g. keyId=$AWS_ACCESS_KEY_ID (travels in the Credential scope). |
sessionToken | Reference to the item holding a session token for temporary credentials, sent and signed as X-Amz-Security-Token. |
allowedRegions | Only sign requests whose scope names one of these regions, e.g. [us-east-1]. Omitted = any. |
allowedServices | Only sign requests whose scope names one of these services, e.g. [bedrock, s3]. Omitted = any. |
Details and limitations
Section titled “Details and limitations”- A request without an inbound SigV4 signature is blocked with a message explaining the placeholder-signing setup (there is nothing to derive the region/service from).
- Pre-signed URLs (
X-Amz-Credentialin the query string) are not supported and are blocked with a distinct message. - The payload hash covers the exact outbound body bytes, byte-for-byte (binary uploads included). If the client signed with the
UNSIGNED-PAYLOADsentinel, the proxy preserves it.aws-chunkedstreaming payloads (STREAMING-*sentinels, used by newer SDKs’ flexible checksums) cannot be re-signed and are blocked with a pointer at the SDK setting to disable them (requestChecksumCalculation: "WHEN_REQUIRED"). - Signing uses the official AWS SDK v3 signer, including the S3-specific path-encoding rules.
See Request transforms for how transforms work in general.