boto3-refresh-session 7.0.1__py3-none-any.whl → 7.1.3__py3-none-any.whl
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.
- boto3_refresh_session/__init__.py +1 -1
- boto3_refresh_session/exceptions.py +6 -6
- boto3_refresh_session/methods/sts.py +54 -103
- boto3_refresh_session/session.py +12 -0
- boto3_refresh_session/utils/__init__.py +3 -1
- boto3_refresh_session/utils/config/__init__.py +10 -0
- boto3_refresh_session/utils/config/config.py +274 -0
- boto3_refresh_session/utils/constants.py +31 -6
- boto3_refresh_session/utils/internal.py +3 -3
- boto3_refresh_session/utils/typing.py +1 -0
- {boto3_refresh_session-7.0.1.dist-info → boto3_refresh_session-7.1.3.dist-info}/METADATA +75 -9
- boto3_refresh_session-7.1.3.dist-info/RECORD +21 -0
- boto3_refresh_session-7.0.1.dist-info/RECORD +0 -19
- {boto3_refresh_session-7.0.1.dist-info → boto3_refresh_session-7.1.3.dist-info}/WHEEL +0 -0
- {boto3_refresh_session-7.0.1.dist-info → boto3_refresh_session-7.1.3.dist-info}/licenses/LICENSE +0 -0
- {boto3_refresh_session-7.0.1.dist-info → boto3_refresh_session-7.1.3.dist-info}/licenses/NOTICE +0 -0
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
"""Custom exception and warning types for boto3-refresh-session."""
|
|
6
6
|
|
|
7
7
|
__all__ = [
|
|
8
|
-
"
|
|
9
|
-
"
|
|
8
|
+
"BRSCacheError",
|
|
9
|
+
"BRSCacheExistsError",
|
|
10
|
+
"BRSCacheNotFoundError",
|
|
10
11
|
"BRSConfigurationError",
|
|
11
|
-
"BRSCredentialError",
|
|
12
12
|
"BRSConnectionError",
|
|
13
|
+
"BRSCredentialError",
|
|
14
|
+
"BRSError",
|
|
13
15
|
"BRSRequestError",
|
|
14
|
-
"
|
|
15
|
-
"BRSCacheNotFoundError",
|
|
16
|
-
"BRSCacheExistsError",
|
|
16
|
+
"BRSValidationError",
|
|
17
17
|
"BRSWarning",
|
|
18
18
|
]
|
|
19
19
|
|
|
@@ -10,12 +10,11 @@ from typing import Callable
|
|
|
10
10
|
|
|
11
11
|
from ..exceptions import BRSConfigurationError, BRSValidationError, BRSWarning
|
|
12
12
|
from ..utils import (
|
|
13
|
-
|
|
14
|
-
ROLE_ARN_PATTERN,
|
|
15
|
-
ROLE_SESSION_NAME_PATTERN,
|
|
13
|
+
AssumeRoleConfig,
|
|
16
14
|
AssumeRoleParams,
|
|
17
15
|
BaseRefreshableSession,
|
|
18
16
|
Identity,
|
|
17
|
+
STSClientConfig,
|
|
19
18
|
STSClientParams,
|
|
20
19
|
TemporaryCredentials,
|
|
21
20
|
refreshable_session,
|
|
@@ -29,7 +28,7 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
|
29
28
|
|
|
30
29
|
Parameters
|
|
31
30
|
----------
|
|
32
|
-
assume_role_kwargs : AssumeRoleParams
|
|
31
|
+
assume_role_kwargs : AssumeRoleParams | AssumeRoleConfig
|
|
33
32
|
Required keyword arguments for :meth:`STS.Client.assume_role` (i.e.
|
|
34
33
|
boto3 STS client). ``RoleArn`` is required. ``RoleSessionName`` will
|
|
35
34
|
default to 'boto3-refresh-session' if not provided.
|
|
@@ -45,7 +44,7 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
|
45
44
|
``TokenCode`` in ``assume_role_kwargs``. You are responsible for
|
|
46
45
|
updating ``assume_role_kwargs["TokenCode"]`` before the token
|
|
47
46
|
expires.
|
|
48
|
-
sts_client_kwargs : STSClientParams, optional
|
|
47
|
+
sts_client_kwargs : STSClientParams | STSClientConfig, optional
|
|
49
48
|
Optional keyword arguments for the :class:`STS.Client` object. Do not
|
|
50
49
|
provide values for ``service_name`` as they are unnecessary. Default
|
|
51
50
|
is None.
|
|
@@ -86,16 +85,39 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
|
86
85
|
kwargs : dict
|
|
87
86
|
Optional keyword arguments for the :class:`boto3.session.Session`
|
|
88
87
|
object.
|
|
88
|
+
|
|
89
|
+
See Also
|
|
90
|
+
--------
|
|
91
|
+
boto3_refresh_session.utils.config.config.AssumeRoleConfig
|
|
92
|
+
boto3_refresh_session.utils.config.config.STSClientConfig
|
|
89
93
|
"""
|
|
90
94
|
|
|
91
95
|
def __init__(
|
|
92
96
|
self,
|
|
93
|
-
assume_role_kwargs: AssumeRoleParams,
|
|
94
|
-
sts_client_kwargs: STSClientParams | None = None,
|
|
97
|
+
assume_role_kwargs: AssumeRoleParams | AssumeRoleConfig,
|
|
98
|
+
sts_client_kwargs: STSClientParams | STSClientConfig | None = None,
|
|
95
99
|
mfa_token_provider: Callable[[], str] | None = None,
|
|
96
100
|
mfa_token_provider_kwargs: dict | None = None,
|
|
97
101
|
**kwargs,
|
|
98
102
|
):
|
|
103
|
+
# initializing asssume_role_kwargs attribute
|
|
104
|
+
match assume_role_kwargs:
|
|
105
|
+
case AssumeRoleConfig():
|
|
106
|
+
self.assume_role_kwargs = assume_role_kwargs
|
|
107
|
+
case _:
|
|
108
|
+
self.assume_role_kwargs = AssumeRoleConfig(
|
|
109
|
+
**assume_role_kwargs
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# initializing sts_client_kwargs attribute
|
|
113
|
+
match sts_client_kwargs:
|
|
114
|
+
case STSClientConfig():
|
|
115
|
+
self.sts_client_kwargs = sts_client_kwargs
|
|
116
|
+
case None:
|
|
117
|
+
self.sts_client_kwargs = STSClientConfig()
|
|
118
|
+
case _:
|
|
119
|
+
self.sts_client_kwargs = STSClientConfig(**sts_client_kwargs)
|
|
120
|
+
|
|
99
121
|
# ensuring 'refresh_method' is not set manually
|
|
100
122
|
if "refresh_method" in kwargs:
|
|
101
123
|
BRSWarning.warn(
|
|
@@ -104,43 +126,10 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
|
104
126
|
)
|
|
105
127
|
del kwargs["refresh_method"]
|
|
106
128
|
|
|
107
|
-
#
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
param="RoleArn",
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
# verifying 'RoleArn' format
|
|
115
|
-
if not ROLE_ARN_PATTERN.match(assume_role_kwargs["RoleArn"]):
|
|
116
|
-
raise BRSValidationError(
|
|
117
|
-
"'RoleArn' in 'assume_role_kwargs' is not a valid AWS "
|
|
118
|
-
"Role ARN!",
|
|
119
|
-
param="RoleArn",
|
|
120
|
-
value=assume_role_kwargs.get("RoleArn"),
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
# setting default 'RoleSessionName' if not provided
|
|
124
|
-
if "RoleSessionName" not in assume_role_kwargs:
|
|
125
|
-
BRSWarning.warn(
|
|
126
|
-
"'RoleSessionName' not provided in "
|
|
127
|
-
"'assume_role_kwargs'! Defaulting to "
|
|
128
|
-
"'boto3-refresh-session'."
|
|
129
|
-
)
|
|
130
|
-
assume_role_kwargs["RoleSessionName"] = "boto3-refresh-session"
|
|
131
|
-
|
|
132
|
-
# verifying 'RoleSessionName' format
|
|
133
|
-
if not ROLE_SESSION_NAME_PATTERN.match(
|
|
134
|
-
assume_role_kwargs["RoleSessionName"]
|
|
135
|
-
):
|
|
136
|
-
raise BRSValidationError(
|
|
137
|
-
"'RoleSessionName' in 'assume_role_kwargs' is not valid! "
|
|
138
|
-
"It must be 2-64 characters long and can contain only "
|
|
139
|
-
"alphanumeric characters and the following symbols: "
|
|
140
|
-
"'+=,.@-'.",
|
|
141
|
-
param="RoleSessionName",
|
|
142
|
-
value=assume_role_kwargs.get("RoleSessionName"),
|
|
143
|
-
)
|
|
129
|
+
# setting 'RoleSessionName' if not provided
|
|
130
|
+
self.assume_role_kwargs.RoleSessionName = self.assume_role_kwargs.get(
|
|
131
|
+
"RoleSessionName", "boto3-refresh-session"
|
|
132
|
+
)
|
|
144
133
|
|
|
145
134
|
# store MFA token provider
|
|
146
135
|
try:
|
|
@@ -158,26 +147,12 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
|
158
147
|
) from err
|
|
159
148
|
|
|
160
149
|
# storing mfa_token_provider_kwargs
|
|
161
|
-
self.mfa_token_provider_kwargs =
|
|
162
|
-
mfa_token_provider_kwargs if mfa_token_provider_kwargs else {}
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
# verifying 'SerialNumber' format if provided
|
|
166
|
-
if "SerialNumber" in assume_role_kwargs:
|
|
167
|
-
if not MFA_SERIAL_PATTERN.match(
|
|
168
|
-
assume_role_kwargs["SerialNumber"]
|
|
169
|
-
):
|
|
170
|
-
raise BRSValidationError(
|
|
171
|
-
"'SerialNumber' in 'assume_role_kwargs' is not a valid "
|
|
172
|
-
"AWS MFA device ARN!",
|
|
173
|
-
param="SerialNumber",
|
|
174
|
-
value=assume_role_kwargs.get("SerialNumber"),
|
|
175
|
-
)
|
|
150
|
+
self.mfa_token_provider_kwargs = mfa_token_provider_kwargs or {}
|
|
176
151
|
|
|
177
152
|
# ensure SerialNumber is set appropriately with mfa_token_provider
|
|
178
153
|
if (
|
|
179
154
|
self.mfa_token_provider
|
|
180
|
-
and
|
|
155
|
+
and self.assume_role_kwargs.SerialNumber is None
|
|
181
156
|
):
|
|
182
157
|
raise BRSConfigurationError(
|
|
183
158
|
"'SerialNumber' must be provided in 'assume_role_kwargs' "
|
|
@@ -185,77 +160,53 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
|
185
160
|
param="SerialNumber",
|
|
186
161
|
)
|
|
187
162
|
|
|
188
|
-
# ensure SerialNumber and TokenCode are set
|
|
163
|
+
# ensure SerialNumber and TokenCode are set in the absence of
|
|
164
|
+
# mfa_token_provider
|
|
189
165
|
if (
|
|
190
166
|
self.mfa_token_provider is None
|
|
191
167
|
and (
|
|
192
|
-
|
|
193
|
-
and
|
|
168
|
+
self.assume_role_kwargs.SerialNumber is not None
|
|
169
|
+
and self.assume_role_kwargs.TokenCode is None
|
|
194
170
|
)
|
|
195
171
|
or (
|
|
196
|
-
|
|
197
|
-
and
|
|
172
|
+
self.assume_role_kwargs.SerialNumber is None
|
|
173
|
+
and self.assume_role_kwargs.TokenCode is not None
|
|
198
174
|
)
|
|
199
175
|
):
|
|
200
176
|
raise BRSConfigurationError(
|
|
201
177
|
"'SerialNumber' and 'TokenCode' must be provided in "
|
|
202
|
-
"'assume_role_kwargs' when 'mfa_token_provider' is not set
|
|
178
|
+
"'assume_role_kwargs' when 'mfa_token_provider' is not set "
|
|
179
|
+
"and 'SerialNumber' or 'TokenCode' is missing!",
|
|
203
180
|
param="SerialNumber/TokenCode",
|
|
204
181
|
)
|
|
205
182
|
|
|
206
183
|
# warn if TokenCode provided with mfa_token_provider
|
|
207
|
-
if
|
|
184
|
+
if (
|
|
185
|
+
self.mfa_token_provider
|
|
186
|
+
and self.assume_role_kwargs.TokenCode is not None
|
|
187
|
+
):
|
|
208
188
|
BRSWarning.warn(
|
|
209
189
|
"'TokenCode' provided in 'assume_role_kwargs' will be "
|
|
210
190
|
"ignored and overridden by 'mfa_token_provider' on each "
|
|
211
191
|
"refresh."
|
|
212
192
|
)
|
|
213
193
|
|
|
214
|
-
# initializing assume role kwargs attribute
|
|
215
|
-
self.assume_role_kwargs = assume_role_kwargs
|
|
216
|
-
|
|
217
194
|
# initializing BRSSession
|
|
218
195
|
super().__init__(refresh_method="sts-assume-role", **kwargs)
|
|
219
196
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if "service_name" in sts_client_kwargs:
|
|
223
|
-
BRSWarning.warn(
|
|
224
|
-
"'sts_client_kwargs' cannot contain values for "
|
|
225
|
-
"'service_name'. Reverting to service_name = 'sts'."
|
|
226
|
-
)
|
|
227
|
-
del sts_client_kwargs["service_name"]
|
|
228
|
-
self._sts_client = self.client(
|
|
229
|
-
service_name="sts", **sts_client_kwargs
|
|
230
|
-
)
|
|
231
|
-
else:
|
|
232
|
-
self._sts_client = self.client(service_name="sts")
|
|
197
|
+
# initializing STS client attribute
|
|
198
|
+
self._sts_client = self.client(**self.sts_client_kwargs)
|
|
233
199
|
|
|
234
200
|
def _get_credentials(self) -> TemporaryCredentials:
|
|
235
|
-
params = dict(self.assume_role_kwargs)
|
|
236
|
-
|
|
237
201
|
# override TokenCode with fresh token from provider if configured
|
|
238
|
-
if self.mfa_token_provider:
|
|
239
|
-
|
|
202
|
+
if self.mfa_token_provider is not None:
|
|
203
|
+
self.assume_role_kwargs.TokenCode = self.mfa_token_provider(
|
|
240
204
|
**self.mfa_token_provider_kwargs
|
|
241
205
|
)
|
|
242
206
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
not isinstance(token_code, str)
|
|
247
|
-
or len(token_code) != 6
|
|
248
|
-
or not token_code.isdigit()
|
|
249
|
-
):
|
|
250
|
-
raise BRSValidationError(
|
|
251
|
-
"'TokenCode' must be a 6-digit string per AWS MFA "
|
|
252
|
-
"token specifications!",
|
|
253
|
-
param="TokenCode",
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
temporary_credentials = self._sts_client.assume_role(**params)[
|
|
257
|
-
"Credentials"
|
|
258
|
-
]
|
|
207
|
+
temporary_credentials = self._sts_client.assume_role(
|
|
208
|
+
**self.assume_role_kwargs
|
|
209
|
+
)["Credentials"]
|
|
259
210
|
|
|
260
211
|
return {
|
|
261
212
|
"access_key": temporary_credentials.get("AccessKeyId"),
|
boto3_refresh_session/session.py
CHANGED
|
@@ -66,6 +66,18 @@ class RefreshableSession:
|
|
|
66
66
|
boto3_refresh_session.methods.custom.CustomRefreshableSession
|
|
67
67
|
boto3_refresh_session.methods.iot.x509.IOTX509RefreshableSession
|
|
68
68
|
boto3_refresh_session.methods.sts.STSRefreshableSession
|
|
69
|
+
|
|
70
|
+
Examples
|
|
71
|
+
--------
|
|
72
|
+
|
|
73
|
+
Basic initialization using STS AssumeRole (i.e. ``method="sts"``):
|
|
74
|
+
|
|
75
|
+
>>> from boto3_refresh_session import AssumeRoleConfig, RefreshableSession
|
|
76
|
+
>>> session = RefreshableSession(
|
|
77
|
+
... AssumeRoleConfig(RoleArn="<your-role-arn>"),
|
|
78
|
+
... region_name="us-east-1"
|
|
79
|
+
... )
|
|
80
|
+
>>> s3 = session.client("s3")
|
|
69
81
|
"""
|
|
70
82
|
|
|
71
83
|
def __new__(
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
__all__ = []
|
|
6
6
|
|
|
7
|
-
from . import cache, constants, internal, typing
|
|
7
|
+
from . import cache, config, constants, internal, typing
|
|
8
8
|
from .cache import *
|
|
9
|
+
from .config import *
|
|
9
10
|
from .constants import *
|
|
10
11
|
from .internal import *
|
|
11
12
|
from .typing import *
|
|
12
13
|
|
|
13
14
|
__all__.extend(cache.__all__)
|
|
15
|
+
__all__.extend(config.__all__)
|
|
14
16
|
__all__.extend(constants.__all__)
|
|
15
17
|
__all__.extend(internal.__all__)
|
|
16
18
|
__all__.extend(typing.__all__)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
|
|
5
|
+
__all__ = []
|
|
6
|
+
|
|
7
|
+
from . import config
|
|
8
|
+
from .config import *
|
|
9
|
+
|
|
10
|
+
__all__.extend(config.__all__)
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
|
|
5
|
+
"""Configurations for AWS STS AssumeRole and STS Client.
|
|
6
|
+
|
|
7
|
+
The following configuration classes do not validate most user inputs except
|
|
8
|
+
'TokenCode' in `AssumeRoleConfig` and `service_name` in `STSClientConfig`.
|
|
9
|
+
It is the user's responsibility to ensure that the provided values conform
|
|
10
|
+
to AWS and boto specifications. The purpose of these configurations is to
|
|
11
|
+
provide a structured way to manage parameters when working with AWS STS.
|
|
12
|
+
|
|
13
|
+
For additional information on AWS specifications, refer to the
|
|
14
|
+
`API Reference for AssumeRole <https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html>`_.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
__all__ = ["AssumeRoleConfig", "STSClientConfig"]
|
|
18
|
+
|
|
19
|
+
from abc import ABC, abstractmethod
|
|
20
|
+
from typing import Any
|
|
21
|
+
|
|
22
|
+
from botocore.config import Config
|
|
23
|
+
|
|
24
|
+
from ...exceptions import BRSValidationError, BRSWarning
|
|
25
|
+
from ..constants import (
|
|
26
|
+
ASSUME_ROLE_CONFIG_PARAMETERS,
|
|
27
|
+
STS_CLIENT_CONFIG_PARAMETERS,
|
|
28
|
+
)
|
|
29
|
+
from ..typing import PolicyDescriptorType, ProvidedContext, Tag
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class BaseConfig(dict, ABC):
|
|
33
|
+
"""Base configuration class."""
|
|
34
|
+
|
|
35
|
+
def __init__(self, **kwargs):
|
|
36
|
+
super().__init__()
|
|
37
|
+
self.update(kwargs)
|
|
38
|
+
|
|
39
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
40
|
+
self._validate(key, value)
|
|
41
|
+
if value is None:
|
|
42
|
+
if key in self:
|
|
43
|
+
super().__delitem__(key)
|
|
44
|
+
return
|
|
45
|
+
super().__setitem__(key, value)
|
|
46
|
+
|
|
47
|
+
def __getattr__(self, name: str) -> Any:
|
|
48
|
+
try:
|
|
49
|
+
return self[name]
|
|
50
|
+
except KeyError:
|
|
51
|
+
try:
|
|
52
|
+
self._validate(name, None)
|
|
53
|
+
except BRSValidationError as exc:
|
|
54
|
+
raise AttributeError(
|
|
55
|
+
f"'{name}' is an unknown attribute."
|
|
56
|
+
) from exc
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
60
|
+
self.__setitem__(name, value)
|
|
61
|
+
|
|
62
|
+
def update(self, *args, **kwargs) -> None:
|
|
63
|
+
for key, value in dict(*args, **kwargs).items():
|
|
64
|
+
self.__setitem__(key, value)
|
|
65
|
+
|
|
66
|
+
def setdefault(self, key: str, default: Any = None):
|
|
67
|
+
if key in self:
|
|
68
|
+
return super().setdefault(key, default)
|
|
69
|
+
self._validate(key, default)
|
|
70
|
+
return super().setdefault(key, default)
|
|
71
|
+
|
|
72
|
+
@abstractmethod
|
|
73
|
+
def _validate(self, key: str, value: Any) -> None: ...
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class AssumeRoleConfig(BaseConfig):
|
|
77
|
+
"""Configuration for AWS STS AssumeRole API.
|
|
78
|
+
|
|
79
|
+
Attributes
|
|
80
|
+
----------
|
|
81
|
+
RoleArn : str
|
|
82
|
+
The Amazon Resource Name (ARN) of the role to assume.
|
|
83
|
+
RoleSessionName : str, optional
|
|
84
|
+
An identifier for the assumed role session.
|
|
85
|
+
PolicyArns : list of PolicyDescriptorType, optional
|
|
86
|
+
The Amazon Resource Names (ARNs) of the IAM managed policies to
|
|
87
|
+
use as managed session policies.
|
|
88
|
+
Policy : str, optional
|
|
89
|
+
An IAM policy in JSON format to use as an inline session policy.
|
|
90
|
+
DurationSeconds : int, optional
|
|
91
|
+
The duration, in seconds, of the role session.
|
|
92
|
+
ExternalId : str, optional
|
|
93
|
+
A unique identifier that might be required when you assume a role
|
|
94
|
+
in another account.
|
|
95
|
+
SerialNumber : str, optional
|
|
96
|
+
The identification number of the MFA device.
|
|
97
|
+
TokenCode : str, optional
|
|
98
|
+
The value provided by the MFA device. Must be a 6-digit numeric
|
|
99
|
+
string.
|
|
100
|
+
Tags : list of Tag, optional
|
|
101
|
+
A list of session tags.
|
|
102
|
+
TransitiveTagKeys : list of str, optional
|
|
103
|
+
A list of keys for session tags that you want to pass to the role
|
|
104
|
+
session.
|
|
105
|
+
SourceIdentity : str, optional
|
|
106
|
+
A unique identifier that is passed in the AssumeRole call.
|
|
107
|
+
ProvidedContexts : list of ProvidedContext, optional
|
|
108
|
+
A list of context keys and values for the session.
|
|
109
|
+
|
|
110
|
+
Notes
|
|
111
|
+
-----
|
|
112
|
+
Values can be accessed via dot-notation (e.g., ``config.RoleArn``)
|
|
113
|
+
or dictionary-style access (e.g., ``config['RoleArn']``).
|
|
114
|
+
|
|
115
|
+
Accessing a valid but unset attribute (e.g., ``SerialNumber``) via
|
|
116
|
+
dot-notation returns ``None`` instead of raising an error. While this
|
|
117
|
+
behavior is convenient, it may surprise users accustomed to seeing
|
|
118
|
+
``AttributeError`` exceptions in similar contexts.
|
|
119
|
+
|
|
120
|
+
For additional information on AWS specifications, refer to the
|
|
121
|
+
`API Reference for AssumeRole <https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html>`_.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
def __init__(
|
|
125
|
+
self,
|
|
126
|
+
*, # enforce keyword-only arguments
|
|
127
|
+
RoleArn: str,
|
|
128
|
+
RoleSessionName: str | None = None,
|
|
129
|
+
PolicyArns: list[PolicyDescriptorType] | None = None,
|
|
130
|
+
Policy: str | None = None,
|
|
131
|
+
DurationSeconds: int | None = None,
|
|
132
|
+
ExternalId: str | None = None,
|
|
133
|
+
SerialNumber: str | None = None,
|
|
134
|
+
TokenCode: str | None = None,
|
|
135
|
+
Tags: list[Tag] | None = None,
|
|
136
|
+
TransitiveTagKeys: list[str] | None = None,
|
|
137
|
+
SourceIdentity: str | None = None,
|
|
138
|
+
ProvidedContexts: list[ProvidedContext] | None = None,
|
|
139
|
+
):
|
|
140
|
+
super().__init__(
|
|
141
|
+
RoleArn=RoleArn,
|
|
142
|
+
RoleSessionName=RoleSessionName,
|
|
143
|
+
PolicyArns=PolicyArns,
|
|
144
|
+
Policy=Policy,
|
|
145
|
+
DurationSeconds=DurationSeconds,
|
|
146
|
+
ExternalId=ExternalId,
|
|
147
|
+
SerialNumber=SerialNumber,
|
|
148
|
+
TokenCode=TokenCode,
|
|
149
|
+
Tags=Tags,
|
|
150
|
+
TransitiveTagKeys=TransitiveTagKeys,
|
|
151
|
+
SourceIdentity=SourceIdentity,
|
|
152
|
+
ProvidedContexts=ProvidedContexts,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
def _validate(self, key: str, value: Any) -> None:
|
|
156
|
+
if not isinstance(key, str):
|
|
157
|
+
raise BRSValidationError("Attribute name must be a string.")
|
|
158
|
+
|
|
159
|
+
if key not in ASSUME_ROLE_CONFIG_PARAMETERS:
|
|
160
|
+
raise BRSValidationError(
|
|
161
|
+
f"'{key}' is not a valid attribute for AssumeRoleConfig."
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
if (
|
|
165
|
+
key == "TokenCode"
|
|
166
|
+
and isinstance(value, str)
|
|
167
|
+
and (len(value) != 6 or not value.isdigit())
|
|
168
|
+
):
|
|
169
|
+
raise BRSValidationError(
|
|
170
|
+
f"'{key}' must be a 6-digit numeric string."
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class STSClientConfig(BaseConfig):
|
|
175
|
+
"""Configuration for boto3 STS Client.
|
|
176
|
+
|
|
177
|
+
Attributes
|
|
178
|
+
----------
|
|
179
|
+
service_name : str, optional
|
|
180
|
+
The name of the AWS service. Defaults to 'sts'.
|
|
181
|
+
region_name : str, optional
|
|
182
|
+
The AWS region name.
|
|
183
|
+
api_version : str, optional
|
|
184
|
+
The API version to use.
|
|
185
|
+
use_ssl : bool, optional
|
|
186
|
+
Whether to use SSL.
|
|
187
|
+
verify : bool or str, optional
|
|
188
|
+
Whether to verify SSL certificates or a path to a CA bundle.
|
|
189
|
+
endpoint_url : str, optional
|
|
190
|
+
The complete URL to use for the constructed client.
|
|
191
|
+
aws_access_key_id : str, optional
|
|
192
|
+
The AWS access key ID.
|
|
193
|
+
aws_secret_access_key : str, optional
|
|
194
|
+
The AWS secret access key.
|
|
195
|
+
aws_session_token : str, optional
|
|
196
|
+
The AWS session token.
|
|
197
|
+
config : botocore.config.Config, optional
|
|
198
|
+
Advanced client configuration options.
|
|
199
|
+
aws_account_id : str, optional
|
|
200
|
+
The AWS account ID associated with the credentials.
|
|
201
|
+
|
|
202
|
+
Notes
|
|
203
|
+
-----
|
|
204
|
+
Values can be accessed via dot-notation (e.g., ``config.RoleArn``)
|
|
205
|
+
or dictionary-style access (e.g., ``config['RoleArn']``).
|
|
206
|
+
|
|
207
|
+
Accessing a valid but unset attribute (e.g., ``SerialNumber``) via
|
|
208
|
+
dot-notation returns ``None`` instead of raising an error. While this
|
|
209
|
+
behavior is convenient, it may surprise users accustomed to seeing
|
|
210
|
+
``AttributeError`` exceptions in similar contexts.
|
|
211
|
+
|
|
212
|
+
``service_name`` is enforced to be 'sts'. If a different value is
|
|
213
|
+
provided, it will be overridden to 'sts' with a warning.
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
def __init__(
|
|
217
|
+
self,
|
|
218
|
+
*, # enforce keyword-only arguments
|
|
219
|
+
service_name: str | None = None,
|
|
220
|
+
region_name: str | None = None,
|
|
221
|
+
api_version: str | None = None,
|
|
222
|
+
use_ssl: bool | None = None,
|
|
223
|
+
verify: bool | str | None = None,
|
|
224
|
+
endpoint_url: str | None = None,
|
|
225
|
+
aws_access_key_id: str | None = None,
|
|
226
|
+
aws_secret_access_key: str | None = None,
|
|
227
|
+
aws_session_token: str | None = None,
|
|
228
|
+
config: Config | None = None,
|
|
229
|
+
aws_account_id: str | None = None,
|
|
230
|
+
):
|
|
231
|
+
super().__init__(
|
|
232
|
+
service_name=service_name,
|
|
233
|
+
region_name=region_name,
|
|
234
|
+
api_version=api_version,
|
|
235
|
+
use_ssl=use_ssl,
|
|
236
|
+
verify=verify,
|
|
237
|
+
endpoint_url=endpoint_url,
|
|
238
|
+
aws_access_key_id=aws_access_key_id,
|
|
239
|
+
aws_secret_access_key=aws_secret_access_key,
|
|
240
|
+
aws_session_token=aws_session_token,
|
|
241
|
+
config=config,
|
|
242
|
+
aws_account_id=aws_account_id,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
246
|
+
"""Override to enforce 'sts' as service_name."""
|
|
247
|
+
|
|
248
|
+
if key == "service_name":
|
|
249
|
+
match value:
|
|
250
|
+
case None:
|
|
251
|
+
value = "sts"
|
|
252
|
+
case str() if value != "sts":
|
|
253
|
+
BRSWarning.warn(
|
|
254
|
+
"The 'service_name' for STSClientConfig should be "
|
|
255
|
+
"'sts'. Overriding to 'sts'."
|
|
256
|
+
)
|
|
257
|
+
value = "sts"
|
|
258
|
+
case str():
|
|
259
|
+
...
|
|
260
|
+
case _:
|
|
261
|
+
raise BRSValidationError(
|
|
262
|
+
"'service_name' must be a string."
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
super().__setitem__(key, value)
|
|
266
|
+
|
|
267
|
+
def _validate(self, key: str, value: Any) -> None:
|
|
268
|
+
if not isinstance(key, str):
|
|
269
|
+
raise BRSValidationError("Attribute name must be a string.")
|
|
270
|
+
|
|
271
|
+
if key not in STS_CLIENT_CONFIG_PARAMETERS:
|
|
272
|
+
raise BRSValidationError(
|
|
273
|
+
f"'{key}' is not a valid attribute for STSClientConfig."
|
|
274
|
+
)
|
|
@@ -2,15 +2,40 @@
|
|
|
2
2
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
|
|
5
|
-
__all__ = [
|
|
6
|
-
"ROLE_ARN_PATTERN",
|
|
7
|
-
"MFA_SERIAL_PATTERN",
|
|
8
|
-
"ROLE_SESSION_NAME_PATTERN",
|
|
9
|
-
]
|
|
5
|
+
__all__ = ["ASSUME_ROLE_CONFIG_PARAMETERS", "STS_CLIENT_CONFIG_PARAMETERS"]
|
|
10
6
|
|
|
11
7
|
from re import compile
|
|
12
8
|
|
|
13
|
-
#
|
|
9
|
+
# THESE CONSTANTS WILL BE DEPRECATED IN A FUTURE RELEASE!!
|
|
14
10
|
ROLE_ARN_PATTERN = compile(r"^arn:aws[a-z-]*:iam::\d{12}:role/[\w+=,.@-]+$")
|
|
15
11
|
MFA_SERIAL_PATTERN = compile(r"^arn:aws[a-z-]*:iam::\d{12}:mfa/[\w+=,.@-]+$")
|
|
16
12
|
ROLE_SESSION_NAME_PATTERN = compile(r"^[a-zA-Z0-9+=,.@-]{2,64}$")
|
|
13
|
+
|
|
14
|
+
# config parameter names
|
|
15
|
+
ASSUME_ROLE_CONFIG_PARAMETERS = (
|
|
16
|
+
"RoleArn",
|
|
17
|
+
"RoleSessionName",
|
|
18
|
+
"PolicyArns",
|
|
19
|
+
"Policy",
|
|
20
|
+
"DurationSeconds",
|
|
21
|
+
"ExternalId",
|
|
22
|
+
"SerialNumber",
|
|
23
|
+
"TokenCode",
|
|
24
|
+
"Tags",
|
|
25
|
+
"TransitiveTagKeys",
|
|
26
|
+
"SourceIdentity",
|
|
27
|
+
"ProvidedContexts",
|
|
28
|
+
)
|
|
29
|
+
STS_CLIENT_CONFIG_PARAMETERS = (
|
|
30
|
+
"service_name",
|
|
31
|
+
"region_name",
|
|
32
|
+
"api_version",
|
|
33
|
+
"use_ssl",
|
|
34
|
+
"verify",
|
|
35
|
+
"endpoint_url",
|
|
36
|
+
"aws_access_key_id",
|
|
37
|
+
"aws_secret_access_key",
|
|
38
|
+
"aws_session_token",
|
|
39
|
+
"config",
|
|
40
|
+
"aws_account_id",
|
|
41
|
+
)
|
|
@@ -36,9 +36,9 @@ common surface and registration behavior for subclasses like STS or IoT X.509.
|
|
|
36
36
|
|
|
37
37
|
__all__ = [
|
|
38
38
|
"AWSCRTResponse",
|
|
39
|
+
"BRSSession",
|
|
39
40
|
"BaseIoTRefreshableSession",
|
|
40
41
|
"BaseRefreshableSession",
|
|
41
|
-
"BRSSession",
|
|
42
42
|
"CredentialProvider",
|
|
43
43
|
"Registry",
|
|
44
44
|
"refreshable_session",
|
|
@@ -276,9 +276,9 @@ class BRSSession(Session):
|
|
|
276
276
|
Parameters
|
|
277
277
|
----------
|
|
278
278
|
*args : Any
|
|
279
|
-
Positional arguments for :
|
|
279
|
+
Positional arguments for :meth:`boto3.session.Session.client`.
|
|
280
280
|
**kwargs : Any
|
|
281
|
-
Keyword arguments for :
|
|
281
|
+
Keyword arguments for :meth:`boto3.session.Session.client`.
|
|
282
282
|
|
|
283
283
|
Returns
|
|
284
284
|
-------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boto3-refresh-session
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.1.3
|
|
4
4
|
Summary: A simple Python package for refreshing the temporary security credentials in a boto3.session.Session object automatically.
|
|
5
5
|
License: MPL-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -109,7 +109,7 @@ Description-Content-Type: text/markdown
|
|
|
109
109
|
|
|
110
110
|
<a href="https://github.com/michaelthomasletts/boto3-refresh-session/blob/main/LICENSE">
|
|
111
111
|
<img
|
|
112
|
-
src="https://img.shields.io/
|
|
112
|
+
src="https://img.shields.io/static/v1?label=License&message=MPL-2.0&color=FF0000&labelColor=555&logo=github&style=flat"
|
|
113
113
|
alt="license"
|
|
114
114
|
/>
|
|
115
115
|
</a>
|
|
@@ -123,7 +123,7 @@ Description-Content-Type: text/markdown
|
|
|
123
123
|
|
|
124
124
|
</div>
|
|
125
125
|
|
|
126
|
-
##
|
|
126
|
+
## Features
|
|
127
127
|
|
|
128
128
|
- Drop-in replacement for `boto3.session.Session`
|
|
129
129
|
- MFA support included for STS
|
|
@@ -136,7 +136,7 @@ Description-Content-Type: text/markdown
|
|
|
136
136
|
- MQTT actions are available!
|
|
137
137
|
- [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/)
|
|
138
138
|
|
|
139
|
-
##
|
|
139
|
+
## Recognition and Testimonials
|
|
140
140
|
|
|
141
141
|
[Featured in TL;DR Sec.](https://tldrsec.com/p/tldr-sec-282)
|
|
142
142
|
|
|
@@ -148,19 +148,85 @@ A testimonial from a Cyber Security Engineer at a FAANG company:
|
|
|
148
148
|
|
|
149
149
|
> _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._
|
|
150
150
|
|
|
151
|
-
##
|
|
151
|
+
## Installation
|
|
152
|
+
|
|
153
|
+
boto3-refresh-session is available on PyPI:
|
|
152
154
|
|
|
153
155
|
```bash
|
|
154
156
|
pip install boto3-refresh-session
|
|
155
157
|
```
|
|
156
158
|
|
|
157
|
-
##
|
|
159
|
+
## Quick Start Guide
|
|
160
|
+
|
|
161
|
+
Basic, bare-bones initialization:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from boto3_refresh_session import AssumeRoleConfig, RefreshableSession
|
|
165
|
+
|
|
166
|
+
session = RefreshableSession(
|
|
167
|
+
AssumeRoleConfig(
|
|
168
|
+
RoleArn="<your role arn>"
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Basic initilization including some additional session parameters:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from boto3_refresh_session import AssumeRoleConfig, RefreshableSession
|
|
177
|
+
|
|
178
|
+
session = RefreshableSession(
|
|
179
|
+
AssumeRoleConfig(
|
|
180
|
+
RoleArn="<your role arn>"
|
|
181
|
+
),
|
|
182
|
+
region_name="<your region name>",
|
|
183
|
+
profile_name="<your aws profile name>",
|
|
184
|
+
)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Slightly advanced initialization using an MFA token provider (Yubikey):
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from boto3_refresh_session import AssumeRoleConfig, RefreshableSession
|
|
191
|
+
import subprocess
|
|
192
|
+
from typing import Sequence
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def mfa_token_provider(cmd: Sequence[str], timeout: float):
|
|
196
|
+
p = subprocess.run(
|
|
197
|
+
list(cmd),
|
|
198
|
+
check=False,
|
|
199
|
+
capture_output=True,
|
|
200
|
+
text=True,
|
|
201
|
+
timeout=timeout,
|
|
202
|
+
)
|
|
203
|
+
return (p.stdout or "").strip()
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
mfa_token_provider_kwargs = {
|
|
207
|
+
"cmd": ["ykman", "oath", "code", "--single", "AWS-prod"], # example token source
|
|
208
|
+
"timeout": 3.0,
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
session = RefreshableSession(
|
|
212
|
+
AssumeRoleConfig(
|
|
213
|
+
RoleArn="<your role arn>",
|
|
214
|
+
SerialNumber="<your MFA device arn>",
|
|
215
|
+
),
|
|
216
|
+
mfa_token_provider=mfa_token_provider,
|
|
217
|
+
mfa_token_provider_kwargs=mfa_token_provider_kwargs,
|
|
218
|
+
)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Usage
|
|
222
|
+
|
|
223
|
+
Refer to the [official usage documentation](https://michaelthomasletts.com/boto3-refresh-session/usage.html) for guidance on general usage.
|
|
158
224
|
|
|
159
|
-
Refer to the [official documentation](https://michaelthomasletts.com/boto3-refresh-session/
|
|
225
|
+
Refer to the [official API documentation](https://michaelthomasletts.com/boto3-refresh-session/modules/index.html) for technical information.
|
|
160
226
|
|
|
161
|
-
##
|
|
227
|
+
## Versions
|
|
162
228
|
|
|
163
|
-
Refer to the [changelog](https://michaelthomasletts.com/boto3-refresh-session/changelog.html).
|
|
229
|
+
Refer to the [changelog](https://michaelthomasletts.com/boto3-refresh-session/changelog.html) for additional information on specific versions and releases.
|
|
164
230
|
|
|
165
231
|
## License
|
|
166
232
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
boto3_refresh_session/__init__.py,sha256=IdfzDufhNbMK1jCkUvwCIsgYB7-OTkNZeEcWPv8FMUk,620
|
|
2
|
+
boto3_refresh_session/exceptions.py,sha256=ypSr7p5Tf0k_E7cf5r-bl336vofNHGRGXsGdkQTyX58,4412
|
|
3
|
+
boto3_refresh_session/methods/__init__.py,sha256=18a2jb5VvY2FdUhHJ4T1lkfotHpbAb8zdMjqxZ3e6tc,394
|
|
4
|
+
boto3_refresh_session/methods/custom.py,sha256=jHRkleg9wvfJ9P0zsWezAr5-93CbXmVaWd5xYjiynBQ,5346
|
|
5
|
+
boto3_refresh_session/methods/iot/__init__.py,sha256=RI9zui9I1hEwkE5N8sAs94IGLCkHF3DxRnKg6MvPESE,348
|
|
6
|
+
boto3_refresh_session/methods/iot/core.py,sha256=6TInwBrNyLwQrcfLC76LRgCB75HFtF_spZ_2pCJKk0g,1532
|
|
7
|
+
boto3_refresh_session/methods/iot/x509.py,sha256=01iN_eSFV2xGPWHl_VgCpf6ojRnikFDC4vNb5v1tApo,22954
|
|
8
|
+
boto3_refresh_session/methods/sts.py,sha256=Z8oix37oK0ClHB_YVcsy5H2UCSJObbDbjNW3NTyNm98,9134
|
|
9
|
+
boto3_refresh_session/session.py,sha256=dqcKcC3mknrolpaBv-en67__Xsn0ocJtMF_PCJaim6E,3997
|
|
10
|
+
boto3_refresh_session/utils/__init__.py,sha256=B-bq0LB9XTlP6VjoGLdsIecWxzauULTRQRyEN1YYLfQ,546
|
|
11
|
+
boto3_refresh_session/utils/cache.py,sha256=3zgms7KZSwPMvTnc39ndPqByB7KqpMeZwuV_bv7S6y8,3126
|
|
12
|
+
boto3_refresh_session/utils/config/__init__.py,sha256=AD-dIem6xwiISXEs-xQA8NOhMKibMkBSt00kLpz8JJg,290
|
|
13
|
+
boto3_refresh_session/utils/config/config.py,sha256=gfVHla7dDgrBAt9Prr_UU6WQmA6Y3lWNk6Mg5PL-tKo,9864
|
|
14
|
+
boto3_refresh_session/utils/constants.py,sha256=iQ6XnSe8p9DH95Ylnhpp6-Pi6amgnBWJSBloHWBK_VA,1132
|
|
15
|
+
boto3_refresh_session/utils/internal.py,sha256=Xvo3D5_MFoldmqNISOmfQf7qydIbQOCVE-0EQY_8pjg,14755
|
|
16
|
+
boto3_refresh_session/utils/typing.py,sha256=pfUP9bGHoh5JlfMBJL-yDBLYykE2gu2A55uLsOS1tVs,3407
|
|
17
|
+
boto3_refresh_session-7.1.3.dist-info/METADATA,sha256=ZJvtmiLo52bygfZHP6HnHVa86ckySU6EbgJcXSmFdCw,8457
|
|
18
|
+
boto3_refresh_session-7.1.3.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
|
|
19
|
+
boto3_refresh_session-7.1.3.dist-info/licenses/LICENSE,sha256=hs-WVkefHtuCJFuYX0oswNUDuUV2br7aQmnGCzB2ma4,16725
|
|
20
|
+
boto3_refresh_session-7.1.3.dist-info/licenses/NOTICE,sha256=4nNFSLvbelWrxMEBMrkcmgi93AaF0NckUgNIf9i6Kbs,863
|
|
21
|
+
boto3_refresh_session-7.1.3.dist-info/RECORD,,
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
boto3_refresh_session/__init__.py,sha256=tUnT4evpnXX_TNcqBXOmtziC02jrsCQ6ryCj33vEOwQ,620
|
|
2
|
-
boto3_refresh_session/exceptions.py,sha256=y4jQ-kjbyprJxSD7HnqzoCZqMnmNqj6TgmTuua7ba2k,4412
|
|
3
|
-
boto3_refresh_session/methods/__init__.py,sha256=18a2jb5VvY2FdUhHJ4T1lkfotHpbAb8zdMjqxZ3e6tc,394
|
|
4
|
-
boto3_refresh_session/methods/custom.py,sha256=jHRkleg9wvfJ9P0zsWezAr5-93CbXmVaWd5xYjiynBQ,5346
|
|
5
|
-
boto3_refresh_session/methods/iot/__init__.py,sha256=RI9zui9I1hEwkE5N8sAs94IGLCkHF3DxRnKg6MvPESE,348
|
|
6
|
-
boto3_refresh_session/methods/iot/core.py,sha256=6TInwBrNyLwQrcfLC76LRgCB75HFtF_spZ_2pCJKk0g,1532
|
|
7
|
-
boto3_refresh_session/methods/iot/x509.py,sha256=01iN_eSFV2xGPWHl_VgCpf6ojRnikFDC4vNb5v1tApo,22954
|
|
8
|
-
boto3_refresh_session/methods/sts.py,sha256=ll6zjAuelUu-rNVKDn4PdUKu4YESafVFVJgWV--GnHw,11114
|
|
9
|
-
boto3_refresh_session/session.py,sha256=5xg6SprpdPvGgAC1cPRZy983EnVh3z9xJ0PBRO5L7VI,3643
|
|
10
|
-
boto3_refresh_session/utils/__init__.py,sha256=WWHRpVzj0HMqWCLhm4vr2aV678gqA5q-FN2-7OZJe-Q,485
|
|
11
|
-
boto3_refresh_session/utils/cache.py,sha256=3zgms7KZSwPMvTnc39ndPqByB7KqpMeZwuV_bv7S6y8,3126
|
|
12
|
-
boto3_refresh_session/utils/constants.py,sha256=3Kp4JVrDdeFCknb87wK0GjGzX8xMkkILxAYArIsP5mo,574
|
|
13
|
-
boto3_refresh_session/utils/internal.py,sha256=HS1drA0F1kzsAG_i_MXN6n1LBmTEU5DLrv3SsSGvZK4,14757
|
|
14
|
-
boto3_refresh_session/utils/typing.py,sha256=GPUADnET8WqNLt6k8sXNimRsCY9dZmxv-fV3g2dYBfY,3372
|
|
15
|
-
boto3_refresh_session-7.0.1.dist-info/METADATA,sha256=nkutVfNQ9MeoyOkXIZ4IsrdNhYea47wu0EgSLagLAyk,6905
|
|
16
|
-
boto3_refresh_session-7.0.1.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
|
|
17
|
-
boto3_refresh_session-7.0.1.dist-info/licenses/LICENSE,sha256=hs-WVkefHtuCJFuYX0oswNUDuUV2br7aQmnGCzB2ma4,16725
|
|
18
|
-
boto3_refresh_session-7.0.1.dist-info/licenses/NOTICE,sha256=4nNFSLvbelWrxMEBMrkcmgi93AaF0NckUgNIf9i6Kbs,863
|
|
19
|
-
boto3_refresh_session-7.0.1.dist-info/RECORD,,
|
|
File without changes
|
{boto3_refresh_session-7.0.1.dist-info → boto3_refresh_session-7.1.3.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{boto3_refresh_session-7.0.1.dist-info → boto3_refresh_session-7.1.3.dist-info}/licenses/NOTICE
RENAMED
|
File without changes
|