Signers#
A signer mediates between a STAC consumer and the three auth boundaries a
cloud-hosted STAC archive can have: the search request, the returned
Item (asset-href rewrite), and the asset read (GDAL env). Every signer
satisfies the Signer protocol — name plus sign_request,
sign_item, sign_href, and gdal_env — so a custom signer need not subclass
anything.
Pick by where the credential lives:
| Signer | Credential boundary | Needs |
|---|---|---|
AnonymousSigner |
none (public catalogs) | — |
AWSRequesterPaysSigner |
asset read (AWS_REQUEST_PAYER=requester) |
— |
BearerTokenSigner |
request + asset read (Authorization: Bearer) |
a token (or a callable) |
Wire a signer into open_client(..., signer=...) (request + item), into
DatasetCollection.from_stac(..., signer=...) / build_vrt_from_stac(..., signer=...)
(href + read), or into load_asset(item, key, signer=...) (href + read).
Bearer tokens and cross-host redirects
BearerTokenSigner puts the token in GDAL's GDAL_HTTP_HEADERS, which GDAL
forwards across HTTP redirects — including to a different host. For catalogs
that redirect asset reads cross-host, prefer a URL-signing signer (one that
rewrites the href via sign_href, e.g. a SAS token in the query string) so
the credential is scoped to the signed URL.
Provider-specific signers live in earthlens
Signers that hardcode a single Earth-observation catalog — Microsoft
Planetary Computer, NASA Earthdata, and Copernicus CDSE — implement this
same Signer protocol but ship in earthlens (earthlens.stac), not
pyramids. They drop into the same signer=... arguments.
pyramids.stac.signers
#
Generic signing abstraction for STAC consumers.
A signer mediates between a STAC consumer (an external client or pyramids'
own from_stac) and the three distinct auth boundaries a cloud-hosted STAC
archive can have:
- search-time — the outgoing
GET/POST/searchHTTP request may need credentials (a bearer token, a signed header). - item-rewrite — returned STAC Items' asset hrefs may need a token grafted on or the URL rewritten.
- asset-read — when GDAL opens the asset, it may need extra environment
(
AWS_REQUEST_PAYER=requester, anAuthorizationheader).
This module ships the generic, dependency-light signers
(:class:AnonymousSigner, :class:AWSRequesterPaysSigner,
:class:BearerTokenSigner). Provider-specific signers that hardcode a single
Earth-observation catalog or need a remote-sensing SDK (Microsoft Planetary
Computer, NASA Earthdata, Copernicus CDSE) live in earthlens, which implements
this :class:Signer protocol downstream; for any other provider, implement the
protocol yourself or pass a token callable to :class:BearerTokenSigner.
Signer
#
Bases: Protocol
Three-boundary signing protocol for STAC consumers.
Any object exposing name plus the four methods below satisfies the
protocol structurally — concrete signers need not subclass it.
Source code in src/pyramids/stac/signers.py
sign_request(request)
#
Modify an outgoing STAC-API HTTP request before it is sent.
Matches pystac_client.Client.open(request_modifier=...). Return
None to signal "mutated in place, send as-is", or return the
(modified) request.
Source code in src/pyramids/stac/signers.py
sign_item(item)
#
Mutate a returned STAC Item / ItemCollection in place.
Matches pystac_client.Client.open(modifier=...) and must return
None (pystac-client warns on a non-None return).
AnonymousSigner
#
Bases: _BaseSigner
Signer that adds no credentials anywhere — for public catalogs.
Examples:
- It is a complete no-op across every boundary:
Source code in src/pyramids/stac/signers.py
AWSRequesterPaysSigner
#
Bases: _BaseSigner
Signer for assets in AWS Requester-Pays buckets.
Adds only the GDAL environment needed to read from buckets such as
s3://usgs-landsat or s3://sentinel-1-grd; no request or href rewrite
is required. The env is assembled by
:class:~pyramids.base.remote.CloudConfig from the shared
:data:~pyramids.base.remote._REQUESTER_PAYS_GDAL_KNOBS, so this signer and
:func:~pyramids.base.remote.RequesterPays stay in lock-step instead of
each carrying their own copy of the knob set.
Note
Building the env from the shared knob set also added two options this
signer did not emit before: GDAL_HTTP_MULTIPLEX=YES and
GDAL_HTTP_VERSION=2. That is a throughput win on a healthy endpoint,
but HTTP/2 is not universally safe — an intercepting proxy, an older
libcurl, or a server that negotiates it badly can stall or fail reads.
A caller who needs the old behaviour can build the env themselves:
CloudConfig(aws_request_payer=True).as_gdal_config().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
region
|
str | None
|
Optional AWS region of the bucket. Emitted as |
None
|
Examples:
- The GDAL env opts into Requester-Pays and trims redundant calls:
- A pinned region reaches GDAL through both region options:
- Without a region only the Requester-Pays knobs are set, so GDAL keeps resolving the region itself:
Source code in src/pyramids/stac/signers.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
__init__(region=None)
#
Store the optional bucket region.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
region
|
str | None
|
AWS region of the Requester-Pays bucket, or |
None
|
gdal_env()
#
Return the GDAL config that opts into Requester-Pays reads.
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A mapping setting |
dict[str, str]
|
cloud-read knobs that avoid extra billable HEAD/list calls |
dict[str, str]
|
( |
dict[str, str]
|
enable HTTP/2 multiplexing, plus |
dict[str, str]
|
|
Examples:
- Read the knobs a Requester-Pays open will run under:
- A pinned region is what GDAL will address the bucket with:
See Also
- :func:
pyramids.base.remote.RequesterPays: the same knobs as a context manager, for reads that do not go through a signer. - :func:
pyramids.base.remote.s3fs_requester_pays_kwargs: the fsspec/s3fs equivalent for non-GDAL readers.
Source code in src/pyramids/stac/signers.py
BearerTokenSigner
#
Bases: _BaseSigner
Signer that injects an Authorization: Bearer header.
The token may be a static string or a zero-argument callable resolved on every use — pass a callable to plug in a provider-specific token cache / refresh routine without coupling pyramids to that provider's SDK.
Security note
gdal_env() carries the token in GDAL's process-wide
GDAL_HTTP_HEADERS config. :func:pyramids.stac.load_asset installs
it only for the duration of the asset open (via CloudConfig) and
tears it down afterwards, so it does not persist globally. However, GDAL
forwards that Authorization header across HTTP redirects, including
redirects to a different host (common with signed-URL / blob-storage
STAC assets) — so the token can be sent to the redirect target. Prefer a
URL-signing signer (rewriting the href via sign_href, e.g. a SAS
token in the query string) for catalogs that redirect cross-host, and
reserve this signer for catalogs that authenticate the asset host
directly with a bearer header.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str | Callable[[], str]
|
A bearer token string, or a callable returning one. |
required |
Examples:
- A static token is injected into the request and the GDAL env:
- A callable token is resolved on each use (e.g. an auto-refresher):
Source code in src/pyramids/stac/signers.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | |
__init__(token)
#
Store the bearer token or token-provider callable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str | Callable[[], str]
|
A static token string or a zero-arg callable returning one. |
required |
sign_request(request)
#
Set the Authorization header on an outgoing request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
Any
|
An object with a mutable |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The same |
Source code in src/pyramids/stac/signers.py
gdal_env()
#
Return the GDAL config carrying the bearer header for asset reads.
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A mapping with |