AWS SigV4
awsSigV4 signs each request with AWS Signature Version 4 — the request-signing AuthStrategy that core's built-in bearer/apiKey/basic/oauth2 don't cover. Edge-safe Web Crypto, no dependencies.
Core's built-in auth strategies cover bearer,
apiKey, basic, cookieSession, and oauth2 — but not request signing, which AWS
APIs, S3-compatible object stores, and many SigV4-protected endpoints require.
@stitchapi/aws-sigv4 adds it as an AuthStrategy.
awsSigV4(...) signs the fully-built request — method, URI, query, headers, and
payload hash — at call time, attaching the Authorization and x-amz-* headers. As
with every StitchAPI auth strategy, the caller (an agent) gets a
capability, not the credential: the keys
resolve per call and never reach the call site or a trace.
Crypto is the platform's Web Crypto (crypto.subtle), so it runs unchanged on
Node 20+, edge runtimes (Workers / Deno), and the browser; Node 18 falls back to
node:crypto. No runtime dependencies.
Example
npm install @stitchapi/aws-sigv4@rc stitchapi@rcstitchapi is the only peer dependency.
Sign a stitch
Attach awsSigV4(...) as the stitch's auth. Pass the region, service, and
credentials (as Secrets — a string or a call-time getter like env(...)):
import { awsSigV4 } from '@stitchapi/aws-sigv4';
import { stitch } from 'stitchapi';
import { env } from 'stitchapi/auth';
const putObject = stitch({
baseUrl: 'https://my-bucket.s3.us-east-1.amazonaws.com',
path: '/{key}',
method: 'PUT',
auth: awsSigV4({
region: 'us-east-1',
service: 's3',
accessKeyId: env('AWS_ACCESS_KEY_ID'),
secretAccessKey: env('AWS_SECRET_ACCESS_KEY'),
// sessionToken: env('AWS_SESSION_TOKEN'), // temporary STS credentials
}),
});The signature is computed on the final request — after path templating and query
building — so it always matches the bytes the transport sends. A sessionToken
adds and signs x-amz-security-token for temporary credentials.
Payload signing
The x-amz-content-sha256 header is set for you:
- No body → the empty-payload hash (always correct).
- String body → its SHA-256 (exact bytes).
- Non-string body →
UNSIGNED-PAYLOAD— safe over HTTPS, and what S3 and many services accept.
Set signBody: true to hash the body instead. The hash is taken over the exact bytes
the transport sends, chosen by the stitch's
bodyType:
- JSON (
bodyType: 'json'or unset) →JSON.stringify(body). - Form (
bodyType: 'form') → itsapplication/x-www-form-urlencodedencoding — e.g. the query-protocol bodies SQS, SNS, and STS use. - Multipart (
bodyType: 'multipart') → cannot be payload-signed: the transport generates a non-deterministic boundary, so the hash could never match the bytes sent.signBody: truewith a multipart body throws — leave it unset to sendUNSIGNED-PAYLOAD, or pass a pre-serialised string body to sign it.
Low-level signer
signRequestV4(params) is the pure signing function the strategy wraps — exported
for out-of-band signing (presigned URLs, custom flows) and verified against the
official AWS aws-sig-v4-test-suite vectors.
import { EMPTY_PAYLOAD_SHA256, signRequestV4 } from '@stitchapi/aws-sigv4';
const { authorization } = await signRequestV4({
method: 'GET',
url: 'https://example.amazonaws.com/',
headers: {
host: 'example.amazonaws.com',
'x-amz-date': '20150830T123600Z',
},
payloadHash: EMPTY_PAYLOAD_SHA256,
accessKeyId: 'AKID…',
secretAccessKey: '…',
region: 'us-east-1',
service: 'service',
amzDate: '20150830T123600Z',
});Generic per-API HMAC signing isn't shipped as a strategy — each vendor
canonicalises differently, so there's no single contract to standardise.
SigV4 is the one signing scheme common enough to ship; for a one-off scheme,
write a small custom AuthStrategy (an apply(req, ctx) that sets your
header).
See also
JSON Schema
JsonSchema.adapt turns a runtime-discovered JSON Schema into a StitchSchema (a Standard Schema) a stitch accepts — validated with an engine you supply, so it ships none of its own.
Vercel AI SDK
stitchTool exposes a stitch as a Vercel AI SDK tool() the model can call — the stitch runs as the tool's execute, so the model gets typed, validated data and never the credential.