Skip to content

Commit 3addba0

Browse files
authored
Prioritize assume role credentials and deprecate built-in network providers (smithy-lang#773)
* Move PROFILE_ASSUME_ROLE before PROFILE_SESSION_KEYS and PROFILE_STATIC_KEYS in StandardProvider * Update profile session and static key providers to defer when assume role configuration exists in profile * Update env credentials provider to defer when profile_name is configured in IdentityChain.create() * Add deprecation notices to IMDSCredentialsResolver and ContainerCredentialsResolver
1 parent f246160 commit 3addba0

16 files changed

Lines changed: 143 additions & 10 deletions
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "breaking",
3+
"description": "Updated the credential chain precedence so assume role credentials are resolved before session and static profile keys."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "enhancement",
3+
"description": "Updated profile session and static key providers to defer when the selected profile declares an assume-role configuration."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "enhancement",
3+
"description": "Deprecated the built-in IMDS and container credentials resolvers in favor of the resolvers provided by the `aws-credentials-imds` and `aws-credentials-http` packages."
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "enhancement",
3+
"description": "Updated environment credentials provider to defer when `profile_name` is passed to `IdentityChain.create()`."
4+
}

packages/smithy-aws-core/src/smithy_aws_core/identity/chain/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,9 @@ async def create[ChainIdentity: Identity](
185185
:param identity_type: The identity type to resolve.
186186
:param config_file: Parsed config/credentials file. Loaded from disk
187187
when not set.
188-
:param profile_name: Profile name to use. If omitted, the shared config
189-
provider uses ``AWS_PROFILE`` when set, otherwise ``default``.
188+
:param profile_name: Explicit profile name to use. When set, top-level
189+
environment credential resolution is suppressed. If omitted, the shared
190+
config provider uses ``AWS_PROFILE`` when set, otherwise ``default``.
190191
:param region_override: Region to use for providers whose resolvers
191192
fetch credentials through a service call.
192193
:param http_client: HTTP client to use for providers whose resolvers make

packages/smithy-aws-core/src/smithy_aws_core/identity/chain/ordering.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ class StandardProvider(Enum):
1313
ENVIRONMENT = "Environment", None
1414
WEB_IDENTITY_TOKEN_ENV = "WebIdentityTokenEnv", "aws-credentials-sts"
1515
SHARED_CONFIG = "SharedConfig", None
16+
PROFILE_ASSUME_ROLE = "ProfileAssumeRole", "aws-credentials-sts"
1617
PROFILE_SESSION_KEYS = "ProfileSessionKeys", None
1718
PROFILE_STATIC_KEYS = "ProfileStaticKeys", None
18-
PROFILE_ASSUME_ROLE = "ProfileAssumeRole", "aws-credentials-sts"
1919
PROFILE_WEB_IDENTITY = "ProfileWebIdentity", "aws-credentials-sts"
2020
PROFILE_SSO_SESSION = "ProfileSsoSession", "aws-credentials-sso"
2121
PROFILE_LOGIN = "Login", "aws-credentials-login"

packages/smithy-aws-core/src/smithy_aws_core/identity/chain/providers/environment.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
class EnvironmentCredentialsProvider:
17-
"""Adds an environment resolver when credentials are configured in the environment."""
17+
"""Adds an environment resolver unless an explicit profile is selected."""
1818

1919
@property
2020
def name(self) -> str:
@@ -35,6 +35,9 @@ async def setup(
3535
if identity_type is not AWSCredentialsIdentity:
3636
return
3737

38+
if setup.profile_name is not None:
39+
return
40+
3841
if not os.getenv(_ACCESS_KEY_ID) or not os.getenv(_SECRET_ACCESS_KEY):
3942
return
4043

packages/smithy-aws-core/src/smithy_aws_core/identity/chain/providers/profile.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
_SECRET_ACCESS_KEY = "aws_secret_access_key" # noqa: S105
1212
_SESSION_TOKEN = "aws_session_token" # noqa: S105
1313
_ACCOUNT_ID = "aws_account_id"
14+
_ROLE_ARN = "role_arn"
1415

1516

1617
class ProfileSessionCredentialsProvider:
@@ -36,6 +37,9 @@ async def setup(self, identity_type: type[Identity], setup: ChainSetup) -> None:
3637
if config_file is None or profile_name is None:
3738
return
3839

40+
if config_file.get(profile_name, _ROLE_ARN) is not None:
41+
return
42+
3943
access_key_id = config_file.get(profile_name, _ACCESS_KEY_ID)
4044
secret_access_key = config_file.get(profile_name, _SECRET_ACCESS_KEY)
4145
session_token = config_file.get(profile_name, _SESSION_TOKEN)
@@ -74,6 +78,9 @@ async def setup(self, identity_type: type[Identity], setup: ChainSetup) -> None:
7478
if config_file is None or profile_name is None:
7579
return
7680

81+
if config_file.get(profile_name, _ROLE_ARN) is not None:
82+
return
83+
7784
access_key_id = config_file.get(profile_name, _ACCESS_KEY_ID)
7885
secret_access_key = config_file.get(profile_name, _SECRET_ACCESS_KEY)
7986
if access_key_id is None or secret_access_key is None:

packages/smithy-aws-core/src/smithy_aws_core/identity/container.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import ipaddress
55
import json
66
import os
7+
import warnings
78
from dataclasses import dataclass
89
from datetime import UTC, datetime
910
from urllib.parse import urlparse
@@ -106,7 +107,12 @@ def _is_allowed_container_metadata_host(self, hostname: str) -> bool:
106107
class ContainerCredentialsResolver(
107108
IdentityResolver[AWSCredentialsIdentity, AWSIdentityProperties]
108109
):
109-
"""Resolves AWS Credentials from container credential sources."""
110+
"""Resolves AWS Credentials from container credential sources.
111+
112+
.. warning::
113+
This resolver is deprecated. Use the resolver provided by the
114+
``aws-credentials-http`` package instead.
115+
"""
110116

111117
ENV_VAR = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
112118
ENV_VAR_FULL = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
@@ -118,6 +124,12 @@ def __init__(
118124
http_client: HTTPClient,
119125
config: ContainerCredentialsConfig | None = None,
120126
):
127+
warnings.warn(
128+
"`ContainerCredentialsResolver` is deprecated; install "
129+
"`aws-credentials-http` and use its resolver instead.",
130+
DeprecationWarning,
131+
stacklevel=2,
132+
)
121133
self._http_client = http_client
122134
self._config = config or ContainerCredentialsConfig()
123135
self._client = ContainerMetadataClient(http_client, self._config)

packages/smithy-aws-core/src/smithy_aws_core/identity/imds.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33
import asyncio
44
import json
5+
import warnings
56
from dataclasses import dataclass
67
from datetime import UTC, datetime, timedelta
78
from types import MappingProxyType
@@ -182,11 +183,22 @@ async def get(self, *, path: str) -> str:
182183
class IMDSCredentialsResolver(
183184
IdentityResolver[AWSCredentialsIdentity, AWSIdentityProperties]
184185
):
185-
"""Resolves AWS Credentials from an EC2 Instance Metadata Service (IMDS) client."""
186+
"""Resolves AWS Credentials from an EC2 Instance Metadata Service (IMDS) client.
187+
188+
.. warning::
189+
This resolver is deprecated. Use the resolver provided by the
190+
``aws-credentials-imds`` package instead.
191+
"""
186192

187193
_METADATA_PATH_BASE = "/latest/meta-data/iam/security-credentials"
188194

189195
def __init__(self, http_client: HTTPClient, config: Config | None = None):
196+
warnings.warn(
197+
"`IMDSCredentialsResolver` is deprecated; install "
198+
"`aws-credentials-imds` and use its resolver instead.",
199+
DeprecationWarning,
200+
stacklevel=2,
201+
)
190202
# TODO: Respect IMDS specific config values from aws shared config file and environment.
191203
self._http_client = http_client
192204
self._ec2_metadata_client = EC2Metadata(http_client=http_client, config=config)

0 commit comments

Comments
 (0)