boto3-refresh-session 1.0.39__tar.gz → 6.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of boto3-refresh-session might be problematic. Click here for more details.

@@ -0,0 +1,464 @@
1
+ Metadata-Version: 2.4
2
+ Name: boto3-refresh-session
3
+ Version: 6.0.2
4
+ Summary: A simple Python package for refreshing the temporary security credentials in a boto3.session.Session object automatically.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ License-File: NOTICE
8
+ Keywords: boto3,botocore,aws,sts,credentials,token,refresh,iot,x509,mqtt
9
+ Author: Mike Letts
10
+ Author-email: lettsmt@gmail.com
11
+ Maintainer: Michael Letts
12
+ Maintainer-email: lettsmt@gmail.com
13
+ Requires-Python: >=3.10
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Requires-Dist: awscrt
22
+ Requires-Dist: awsiotsdk
23
+ Requires-Dist: boto3
24
+ Requires-Dist: botocore
25
+ Requires-Dist: requests
26
+ Requires-Dist: typing-extensions
27
+ Project-URL: Documentation, https://michaelthomasletts.github.io/boto3-refresh-session/index.html
28
+ Project-URL: Repository, https://github.com/michaelthomasletts/boto3-refresh-session
29
+ Description-Content-Type: text/markdown
30
+
31
+ <div align="center">
32
+ <img src="https://raw.githubusercontent.com/michaelthomasletts/boto3-refresh-session/refs/heads/main/doc/brs.png" />
33
+ </div>
34
+
35
+ </br>
36
+
37
+ <div align="center"><em>
38
+ A simple Python package for refreshing the temporary security credentials in a <code>boto3.session.Session</code> object automatically.
39
+ </em></div>
40
+
41
+ </br>
42
+
43
+ <div align="center">
44
+
45
+ <a href="https://pypi.org/project/boto3-refresh-session/">
46
+ <img
47
+ src="https://img.shields.io/pypi/v/boto3-refresh-session?color=%23FF0000FF&logo=python&label=Latest%20Version"
48
+ alt="pypi_version"
49
+ />
50
+ </a>
51
+
52
+ <a href="https://pypi.org/project/boto3-refresh-session/">
53
+ <img
54
+ src="https://img.shields.io/pypi/pyversions/boto3-refresh-session?style=pypi&color=%23FF0000FF&logo=python&label=Compatible%20Python%20Versions"
55
+ alt="py_version"
56
+ />
57
+ </a>
58
+
59
+ <a href="https://github.com/michaelthomasletts/boto3-refresh-session/actions/workflows/push.yml">
60
+ <img
61
+ src="https://img.shields.io/github/actions/workflow/status/michaelthomasletts/boto3-refresh-session/push.yml?logo=github&color=%23FF0000FF&label=Build"
62
+ alt="workflow"
63
+ />
64
+ </a>
65
+
66
+ <a href="https://github.com/michaelthomasletts/boto3-refresh-session/commits/main">
67
+ <img
68
+ src="https://img.shields.io/github/last-commit/michaelthomasletts/boto3-refresh-session?logo=github&color=%23FF0000FF&label=Last%20Commit"
69
+ alt="last_commit"
70
+ />
71
+ </a>
72
+
73
+ <a href="https://github.com/michaelthomasletts/boto3-refresh-session/stargazers">
74
+ <img
75
+ src="https://img.shields.io/github/stars/michaelthomasletts/boto3-refresh-session?style=flat&logo=github&labelColor=555&color=FF0000&label=Stars"
76
+ alt="stars"
77
+ />
78
+ </a>
79
+
80
+ <a href="https://pepy.tech/projects/boto3-refresh-session">
81
+ <img
82
+ src="https://img.shields.io/endpoint?url=https%3A%2F%2Fmichaelthomasletts.github.io%2Fpepy-stats%2Fboto3-refresh-session.json&style=flat&logo=python&labelColor=555&color=FF0000"
83
+ alt="downloads"
84
+ />
85
+ </a>
86
+
87
+
88
+ <a href="https://michaelthomasletts.github.io/boto3-refresh-session/index.html">
89
+ <img
90
+ src="https://img.shields.io/badge/Official%20Documentation-📘-FF0000?style=flat&labelColor=555&logo=readthedocs"
91
+ alt="documentation"
92
+ />
93
+ </a>
94
+
95
+ <a href="https://github.com/michaelthomasletts/boto3-refresh-session">
96
+ <img
97
+ src="https://img.shields.io/badge/Source%20Code-💻-FF0000?style=flat&labelColor=555&logo=github"
98
+ alt="github"
99
+ />
100
+ </a>
101
+
102
+ <a href="https://michaelthomasletts.github.io/boto3-refresh-session/qanda.html">
103
+ <img
104
+ src="https://img.shields.io/badge/Q%26A-❔-FF0000?style=flat&labelColor=555&logo=vercel&label=Q%26A"
105
+ alt="qanda"
106
+ />
107
+ </a>
108
+
109
+ <a href="https://michaelthomasletts.github.io/blog/brs-rationale/">
110
+ <img
111
+ src="https://img.shields.io/badge/Blog%20Post-📘-FF0000?style=flat&labelColor=555&logo=readthedocs"
112
+ alt="blog"
113
+ />
114
+ </a>
115
+
116
+ <a href="https://github.com/sponsors/michaelthomasletts">
117
+ <img
118
+ src="https://img.shields.io/badge/Sponsor%20this%20Project-💙-FF0000?style=flat&labelColor=555&logo=githubsponsors"
119
+ alt="sponsorship"
120
+ />
121
+ </a>
122
+
123
+ </div>
124
+
125
+ ## 😛 Features
126
+
127
+ - Drop-in replacement for `boto3.session.Session`
128
+ - MFA support included for STS
129
+ - Supports automatic temporary credential refresh for:
130
+ - **STS**
131
+ - **IoT Core**
132
+ - X.509 certificates w/ role aliases over mTLS (PEM files and PKCS#11)
133
+ - MQTT actions are available!
134
+ - Custom authentication methods
135
+ - Natively supports all parameters supported by `boto3.session.Session`
136
+ - [Tested](https://github.com/michaelthomasletts/boto3-refresh-session/tree/main/tests), [documented](https://michaelthomasletts.github.io/boto3-refresh-session/index.html), and [published to PyPI](https://pypi.org/project/boto3-refresh-session/)
137
+
138
+ ## 😌 Recognition and Testimonials
139
+
140
+ [Featured in TL;DR Sec.](https://tldrsec.com/p/tldr-sec-282)
141
+
142
+ [Featured in CloudSecList.](https://cloudseclist.com/issues/issue-290)
143
+
144
+ Recognized during AWS Community Day Midwest on June 5th, 2025 (the founder's birthday!).
145
+
146
+ A testimonial from a Cyber Security Engineer at a FAANG company:
147
+
148
+ > _Most of my work is on tooling related to AWS security, so I'm pretty choosy about boto3 credentials-adjacent code. I often opt to just write this sort of thing myself so I at least know that I can reason about it. But I found boto3-refresh-session to be very clean and intuitive [...] We're using the RefreshableSession class as part of a client cache construct [...] We're using AWS Lambda to perform lots of operations across several regions in hundreds of accounts, over and over again, all day every day. And it turns out that there's a surprising amount of overhead to creating boto3 clients (mostly deserializing service definition json), so we can run MUCH more efficiently if we keep a cache of clients, all equipped with automatically refreshing sessions._
149
+
150
+ ## 💻 Installation
151
+
152
+ ```bash
153
+ pip install boto3-refresh-session
154
+ ```
155
+
156
+ ## 📝 Usage
157
+
158
+ <details>
159
+ <summary><strong>Core Concepts (click to expand)</strong></summary>
160
+
161
+ ### Core Concepts
162
+
163
+ 1. `RefreshableSession` is the intended interface for using `boto3-refresh-session`. Whether you're using this package to refresh temporary credentials returned by STS, the IoT credential provider (which is really just STS, but I digress), or some custom authentication or credential provider, `RefreshableSession` is where you *ought to* be working when using `boto3-refresh-session`.
164
+
165
+ 2. *You can use all of the same keyword parameters normally associated with `boto3.session.Session`!* For instance, suppose you want to pass `region_name` to `RefreshableSession` as a parameter, whereby it's passed to `boto3.session.Session`. That's perfectly fine! Just pass it like you normally would when initializing `boto3.session.Session`. These keyword parameters are *completely optional*, though. If you're confused, the main idea to remember is this: if initializing `boto3.session.Session` *requires* a particular keyword parameter then pass it to `RefreshableSession`; if not, don't worry about it.
166
+
167
+ 3. To tell `RefreshableSession` which AWS service you're working with for authentication and credential retrieval purposes (STS vs. IoT vs. some custom credential provider), you'll need to pass a `method` parameter to `RefreshableSession`. Since the `service_name` namespace is already occupied by `boto3.sesssion.Session`, [`boto3-refresh-session` uses `method` instead of "service" so as to avoid confusion](https://github.com/michaelthomasletts/boto3-refresh-session/blob/04acb2adb34e505c4dc95711f6b2f97748a2a489/boto3_refresh_session/utils/typing.py#L40). If you're using `RefreshableSession` for STS, however, then `method` is set to `"sts"` by default. You don't need to pass the `method` keyword argument in that case.
168
+
169
+ 4. Using `RefreshableSession` for STS, IoT, or custom flows requires different keyword parameters that are unique to those particular methods. For instance, `STSRefreshableSession`, which is the engine for STS in `boto3-refresh-session`, requires `assume_role_kwargs` and optionally allows `sts_client_kwargs` whereas `CustomRefreshableSession` and `IoTX509RefreshableSession` do not. To familiarize yourself with the keyword parameters for each method, check the documentation for each of those engines [in the Refresh Strategies section here](https://michaelthomasletts.com/boto3-refresh-session/modules/index.html).
170
+
171
+ 5. Irrespective of whatever `method` you pass as a keyword parameter, `RefreshableSession` accepts a keyword parameter named `defer_refresh`. Basically, this boolean tells `boto3-refresh-session` either to refresh credentials *the moment they expire* or to *wait until credentials are explicitly needed*. If you are working in a low-latency environment then `defer_refresh = False` might be helpful. For most users, however, `defer_refresh = True` is most desirable. For that reason, `defer_refresh = True` is the default value. Most users, therefore, should not concern themselves too much with this feature.
172
+
173
+ 6. Some developers struggle to imagine where `boto3-refresh-session` might be helpful. To figure out if `boto3-refresh-session` is for your use case, or whether `credential_process` satisfies your needs, check out [this blog post](https://michaelthomasletts.com/blog/brs-rationale/). `boto3-refresh-session` is not for every developer or use-case; it is a niche tool.
174
+
175
+ </details>
176
+
177
+ <details>
178
+ <summary><strong>Clients and Resources (click to expand)</strong></summary>
179
+
180
+ ### Clients and Resources
181
+
182
+ Most developers who use `boto3` interact primarily with `boto3.client` or `boto3.resource` instead of `boto3.session.Session`. But many developers may not realize that `boto3.session.Session` belies `boto3.client` and `boto3.resource`! In fact, that's precisely what makes `boto3-refresh-session` possible!
183
+
184
+ To use the `boto3.client` or `boto3.resource` interface, but with the benefits of `boto3-refresh-session`, you have a few options!
185
+
186
+ In the following examples, let's assume you want to use STS for retrieving temporary credentials for the sake of simplicity. Let's also focus specifically on `client`. Switching to `resource` follows the same exact idioms as below, except that `client` must be switched to `resource` in the pseudo-code, obviously. If you are not sure how to use `RefreshableSession` for STS (or custom auth flows) then check the usage instructions in the following sections!
187
+
188
+ ##### `RefreshableSession.client` (Recommended)
189
+
190
+ So long as you reuse the same `session` object when creating `client` and `resource` objects, this approach can be used everywhere in your code. It is very simple and straight-forward!
191
+
192
+ ```python
193
+ from boto3_refresh_session import RefreshableSession
194
+
195
+ assume_role_kwargs = {
196
+ "RoleArn": "<your-role-arn>",
197
+ "RoleSessionName": "<your-role-session-name>",
198
+ "DurationSeconds": "<your-selection>",
199
+ ...
200
+ }
201
+ session = RefreshableSession(assume_role_kwargs=assume_role_kwargs)
202
+ s3 = session.client("s3")
203
+ ```
204
+
205
+ ##### `DEFAULT_SESSION`
206
+
207
+ This technique can be helpful if you want to use the same instance of `RefreshableSession` everywhere in your code without reference to `boto3_refresh_session`!
208
+
209
+ ```python
210
+ from boto3 import DEFAULT_SESSION, client
211
+ from boto3_refresh_session import RefreshableSession
212
+
213
+ assume_role_kwargs = {
214
+ "RoleArn": "<your-role-arn>",
215
+ "RoleSessionName": "<your-role-session-name>",
216
+ "DurationSeconds": "<your-selection>",
217
+ ...
218
+ }
219
+ DEFAULT_SESSION = RefreshableSession(assume_role_kwargs=assume_role_kwargs)
220
+ s3 = client("s3")
221
+ ```
222
+
223
+ ##### `botocore_session`
224
+
225
+ ```python
226
+ from boto3 import client
227
+ from boto3_refresh_session import RefreshableSession
228
+
229
+ assume_role_kwargs = {
230
+ "RoleArn": "<your-role-arn>",
231
+ "RoleSessionName": "<your-role-session-name>",
232
+ "DurationSeconds": "<your-selection>",
233
+ ...
234
+ }
235
+ s3 = client(
236
+ service_name="s3",
237
+ botocore_session=RefreshableSession(assume_role_kwargs=assume_role_kwargs)
238
+ )
239
+ ```
240
+
241
+ </details>
242
+
243
+ <details>
244
+ <summary><strong>STS (click to expand)</strong></summary>
245
+
246
+ ### STS
247
+
248
+ Most developers use AWS STS to assume an IAM role and return a set of temporary security credentials. boto3-refresh-session can be used to ensure those temporary credentials refresh automatically. For additional information on the exact parameters that `RefreshableSession` takes for STS, [check this documentation](https://michaelthomasletts.com/boto3-refresh-session/modules/generated/boto3_refresh_session.methods.sts.STSRefreshableSession.html).
249
+
250
+ ```python
251
+ import boto3_refresh_session as brs
252
+
253
+ # OPTIONAL - you can pass all of the params normally associated with boto3.session.Session
254
+ profile_name = "<your-profile-name>"
255
+ region_name = "us-east-1"
256
+ ...
257
+
258
+ # REQUIRED - as well as all of the params associated with STS.Client.assume_role
259
+ assume_role_kwargs = {
260
+ "RoleArn": "<your-role-arn>",
261
+ "RoleSessionName": "<your-role-session-name>",
262
+ "DurationSeconds": "<your-selection>",
263
+ ...
264
+ }
265
+
266
+ # OPTIONAL - as well as all of the params associated with STS.Client, except for 'service_name'
267
+ sts_client_kwargs = {
268
+ "region_name": region_name,
269
+ ...
270
+ }
271
+
272
+ # basic initialization of boto3.session.Session
273
+ session = brs.RefreshableSession(
274
+ assume_role_kwargs=assume_role_kwargs, # required
275
+ sts_client_kwargs=sts_client_kwargs, # optional
276
+ region_name=region_name, # optional
277
+ profile_name=profile_name, # optional
278
+ ... # misc. params for boto3.session.Session
279
+ )
280
+ ```
281
+
282
+ </details>
283
+
284
+ <details>
285
+ <summary><strong>MFA (click to expand)</strong></summary>
286
+
287
+ ### MFA Support
288
+
289
+ When assuming a role that requires MFA, `boto3-refresh-session` supports automatic token provisioning through the `mfa_token_provider` parameter. This parameter accepts a callable that returns a fresh MFA token code (string) whenever credentials need to be refreshed.
290
+
291
+ The `mfa_token_provider` approach is **strongly recommended** over manually providing `TokenCode` in `assume_role_kwargs`, as MFA tokens expire after 30 seconds while AWS temporary credentials can last for hours. By using a callable, your application can automatically fetch fresh tokens on each refresh without manual intervention. There is nothing preventing you from manually providing `TokenCode` *without* `mfa_token_provider`; however, *you* will be responsible for updating `TokenCode` *before* automatic temporary credential refresh occurs, which is likely to be a fragile and complicated approach.
292
+
293
+ When using `mfa_token_provider`, you must also provide `SerialNumber` (your MFA device ARN) in `assume_role_kwargs`. For additional information on the exact parameters that `RefreshableSession` takes for MFA, [check this documentation](https://michaelthomasletts.com/boto3-refresh-session/modules/generated/boto3_refresh_session.methods.sts.STSRefreshableSession.html).
294
+
295
+ ```python
296
+ import boto3_refresh_session as brs
297
+
298
+ # Example 1: Interactive prompt for MFA token
299
+ def get_mfa_token():
300
+ return input("Enter MFA token: ")
301
+
302
+ assume_role_kwargs = {
303
+ "RoleArn": "<your-role-arn>",
304
+ "RoleSessionName": "<your-role-session-name>",
305
+ "SerialNumber": "arn:aws:iam::123456789012:mfa/your-user", # required with mfa_token_provider
306
+ }
307
+
308
+ session = brs.RefreshableSession(
309
+ assume_role_kwargs=assume_role_kwargs,
310
+ mfa_token_provider=get_mfa_token, # callable that returns MFA token
311
+ )
312
+
313
+ # Example 2: Using pyotp for TOTP-based MFA
314
+ import pyotp
315
+
316
+ def get_totp_token():
317
+ totp = pyotp.TOTP("<your-secret-key>")
318
+ return totp.now()
319
+
320
+ session = brs.RefreshableSession(
321
+ assume_role_kwargs=assume_role_kwargs,
322
+ mfa_token_provider=get_totp_token,
323
+ )
324
+
325
+ # Example 3: Retrieving token from environment variable or external service
326
+ import os
327
+
328
+ def get_env_token():
329
+ return os.environ.get("AWS_MFA_TOKEN", "")
330
+
331
+ session = brs.RefreshableSession(
332
+ assume_role_kwargs=assume_role_kwargs,
333
+ mfa_token_provider=get_env_token,
334
+ )
335
+ ```
336
+ </details>
337
+
338
+ <details>
339
+ <summary><strong>Custom (click to expand)</strong></summary>
340
+
341
+ ### Custom
342
+
343
+ If you have a highly sophisticated, novel, or idiosyncratic authentication flow not included in boto3-refresh-session then you will need to provide your own custom temporary credentials callable object. `RefreshableSession` accepts custom credentials callable objects, as shown below. For additional information on the exact parameters that `RefreshableSession` takes for custom authentication flows, [check this documentation](https://michaelthomasletts.com/boto3-refresh-session/modules/generated/boto3_refresh_session.methods.custom.CustomRefreshableSession.html#boto3_refresh_session.methods.custom.CustomRefreshableSession).
344
+
345
+ ```python
346
+ # create (or import) your custom credential method
347
+ def your_custom_credential_getter(...):
348
+ ...
349
+ return {
350
+ "access_key": ...,
351
+ "secret_key": ...,
352
+ "token": ...,
353
+ "expiry_time": ...,
354
+ }
355
+
356
+ # and pass it to RefreshableSession
357
+ session = RefreshableSession(
358
+ method="custom", # required
359
+ custom_credentials_method=your_custom_credential_getter, # required
360
+ custom_credentials_method_args=..., # optional
361
+ region_name=region_name, # optional
362
+ profile_name=profile_name, # optional
363
+ ... # misc. params for boto3.session.Session
364
+ )
365
+ ```
366
+
367
+ </details>
368
+
369
+ <details>
370
+ <summary><strong>IoT Core X.509 (click to expand)</strong></summary>
371
+
372
+ ### IoT Core X.509
373
+
374
+ AWS IoT Core can vend temporary AWS credentials through the **credentials provider** when you connect with an X.509 certificate and a **role alias**. `boto3-refresh-session` makes this flow seamless by automatically refreshing credentials over **mTLS**.
375
+
376
+ For additional information on the exact parameters that `IOTX509RefreshableSession` takes, [check this documentation](https://michaelthomasletts.com/boto3-refresh-session/modules/generated/boto3_refresh_session.methods.iot.x509.IOTX509RefreshableSession.html).
377
+
378
+ ### PEM file
379
+
380
+ ```python
381
+ import boto3_refresh_session as brs
382
+
383
+ # PEM certificate + private key example
384
+ session = brs.RefreshableSession(
385
+ method="iot",
386
+ endpoint="<your-credentials-endpoint>.credentials.iot.<region>.amazonaws.com",
387
+ role_alias="<your-role-alias>",
388
+ certificate="/path/to/certificate.pem",
389
+ private_key="/path/to/private-key.pem",
390
+ thing_name="<your-thing-name>", # optional, if used in policies
391
+ duration_seconds=3600, # optional, capped by role alias
392
+ region_name="us-east-1",
393
+ )
394
+
395
+ # Now you can use the session like any boto3 session
396
+ s3 = session.client("s3")
397
+ print(s3.list_buckets())
398
+ ```
399
+
400
+ ### PKCS#11
401
+
402
+ ```python
403
+ session = brs.RefreshableSession(
404
+ method="iot",
405
+ endpoint="<your-credentials-endpoint>.credentials.iot.<region>.amazonaws.com",
406
+ role_alias="<your-role-alias>",
407
+ certificate="/path/to/certificate.pem",
408
+ pkcs11={
409
+ "pkcs11_lib": "/usr/local/lib/softhsm/libsofthsm2.so",
410
+ "user_pin": "1234",
411
+ "slot_id": 0,
412
+ "token_label": "MyToken",
413
+ "private_key_label": "MyKey",
414
+ },
415
+ thing_name="<your-thing-name>",
416
+ region_name="us-east-1",
417
+ )
418
+ ```
419
+
420
+ ### MQTT
421
+
422
+ After initializing a session object, you can can begin making actions with MQTT using the [mqtt method](https://github.com/michaelthomasletts/boto3-refresh-session/blob/deb68222925bf648f26e878ed4bc24b45317c7db/boto3_refresh_session/methods/iot/x509.py#L367)! You can reuse the same certificate, private key, et al as that used to initialize `RefreshableSession`. Or, alternatively, you can provide separate PKCS#11 or certificate information, whether those be file paths or bytes values. Either way, at a minimum, you will need to provide the endpoint and client identifier (i.e. thing name).
423
+
424
+ ```python
425
+ from awscrt.mqtt.QoS import AT_LEAST_ONCE
426
+ conn = session.mqtt(
427
+ endpoint="<your endpoint>-ats.iot.<region>.amazonaws.com",
428
+ client_id="<your thing name or client ID>",
429
+ )
430
+ conn.connect()
431
+ conn.connect().result()
432
+ conn.publish(topic="foo/bar", payload=b"hi", qos=AT_LEAST_ONCE)
433
+ conn.disconnect().result()
434
+ ```
435
+
436
+ </details>
437
+
438
+ ## ⚠️ Changes
439
+
440
+ Browse through the various changes to `boto3-refresh-session` over time.
441
+
442
+ #### 😥 v3.0.0
443
+
444
+ **The changes introduced by v3.0.0 will not impact ~99% of users** who generally interact with `boto3-refresh-session` by only `RefreshableSession`, *which is the intended usage for this package after all.*
445
+
446
+ Advanced users, however, particularly those using low-level objects such as `BaseRefreshableSession | refreshable_session | BRSSession | utils.py`, may experience breaking changes.
447
+
448
+ Please review [this PR](https://github.com/michaelthomasletts/boto3-refresh-session/pull/75) for additional details.
449
+
450
+ #### ✂️ v4.0.0
451
+
452
+ The `ecs` module has been dropped. For additional details and rationale, please review [this PR](https://github.com/michaelthomasletts/boto3-refresh-session/pull/78).
453
+
454
+ #### 😛 v5.0.0
455
+
456
+ Support for IoT Core via X.509 certificate-based authentication (over HTTPS) is now available!
457
+
458
+ #### ➕ v5.1.0
459
+
460
+ MQTT support added for IoT Core via X.509 certificate-based authentication.
461
+
462
+ #### ➕ v6.0.0
463
+
464
+ MFA support for STS added!