yggdrasil.aws.fs.sigv4¶
sigv4 ¶
AWS Signature Version 4 signing for S3 over pure HTTP.
A small, dependency-free SigV4 signer (S3 flavor) — enough to sign the
GET / HEAD / PUT / POST / DELETE requests
:class:yggdrasil.aws.fs.path.S3Bucket issues over
:class:yggdrasil.http_.session.HTTPSession, without dragging botocore's S3
client onto the data path. botocore is still the credential source (env /
profile / SSO / STS / instance-metadata resolution lives there); this module
only turns a frozen (access_key, secret_key, token) triple plus a request
into the Authorization + x-amz-* headers AWS expects.
S3-specific rules (vs the generic SigV4):
- the canonical URI is not path-normalized (
a/./banda//bare meaningful S3 keys) and/is left unescaped; - the payload hash may be a real SHA-256 or the literal
UNSIGNED-PAYLOAD(used for large streamed bodies over TLS, where re-hashing the whole object just to sign it would defeat streaming).
Verified byte-for-byte against botocore.auth.S3SigV4Auth — see
tests/test_yggdrasil/test_aws/test_sigv4.py.
SigV4Signer ¶
Signs S3 requests with AWS Signature V4.
Stateless w.r.t. the request — credentials are pulled fresh from
credentials_provider on every :meth:sign so a rotating STS token is
always current. region / service are fixed per bucket.
sign ¶
sign(
method: str,
url: URL,
*,
headers: Optional[Mapping[str, str]] = None,
payload_sha256: str = EMPTY_PAYLOAD_SHA256,
now: Optional[datetime] = None
) -> "dict[str, str]"
Return the headers to add to method url so it's SigV4-authorized.
The returned dict always carries Host, x-amz-date,
x-amz-content-sha256 and Authorization (plus
x-amz-security-token when the credentials are temporary). Merge it
into the request headers and send as-is.