diff --git a/changelogs/current.yaml b/changelogs/current.yaml index c0e1c53809ad..cb4c0defc775 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -66,6 +66,10 @@ minor_behavior_changes: When computing SNI and SAN value for the auto-sni and auto-san verification feature, route host manipulations are now taken into account. This behavior can be reverted by setting the runtime guard ``envoy_reloadable_features_use_route_host_mutation_for_auto_sni_san`` to false. +- area: aws + change: | + Aws request signing common code uses http async client by default, moving curl to deprecation path. This behavior change can be + reverted by setting the ``envoy_reloadable_features_use_http_client_to_fetch_aws_credentials`` runtime flag to ``false``. bug_fixes: # *Changes expected to improve the state of the world and are unlikely to have negative effects* diff --git a/docs/root/configuration/http/http_filters/_include/aws_credentials.rst b/docs/root/configuration/http/http_filters/_include/aws_credentials.rst index 99dfc80efb4a..eac00b89262f 100644 --- a/docs/root/configuration/http/http_filters/_include/aws_credentials.rst +++ b/docs/root/configuration/http/http_filters/_include/aws_credentials.rst @@ -15,11 +15,11 @@ secret access key (the session token is optional). towards AWS Security Token Service using ``WebIdentityToken`` read from a file pointed by ``AWS_WEB_IDENTITY_TOKEN_FILE`` environment variable and role arn read from ``AWS_ROLE_ARN`` environment variable. The credentials are extracted from the fields ``AccessKeyId``, ``SecretAccessKey``, and ``SessionToken`` are used, and credentials are cached for 1 hour or until they expire (according to the field - ``Expiration``). To enable this credentials provider set ``envoy.reloadable_features.use_http_client_to_fetch_aws_credentials`` to ``true`` - so that it can use http async client to fetch the credentials. This provider is not compatible with :ref:`Grpc Credentials AWS AwsIamConfig - ` plugin which can only support deprecated libcurl credentials - fetcher (see `issue #30626 `_). To fetch the credentials a static cluster is created with the name - ``sts_token_service_internal-`` pointing towards regional AWS Security Token Service. + ``Expiration``). + This provider is not compatible with :ref:`Grpc Credentials AWS AwsIamConfig ` + plugin which can only support deprecated libcurl credentials fetcher (see `issue #30626 `_). + To fetch the credentials a static cluster is created with the name ``sts_token_service_internal-`` pointing towards regional + AWS Security Token Service. Note: If ``signing_algorithm: AWS_SIGV4A`` is set, the logic for STS cluster host generation is as follows: - If the ``region`` is configured (either through profile, environment or inline) as a SigV4A region set @@ -38,19 +38,18 @@ secret access key (the session token is optional). containing the string required in the Authorization header sent to the EKS Pod Identity Agent. The fields ``AccessKeyId``, ``SecretAccessKey``, and ``Token`` are used, and credentials are cached for 1 hour or until they expire (according to the field ``Expiration``). Note that the latest update on AWS credentials provider utility provides an option to use http async client functionality instead of libcurl - to fetch the credentials. This behavior can be changed by setting ``envoy.reloadable_features.use_http_client_to_fetch_aws_credentials`` to ``true``. - The usage of libcurl is on the deprecation path and will be removed soon. To fetch the credentials from either EC2 instance - metadata or ECS task metadata a static cluster is required pointing towards the credentials provider. The static cluster name has to be - ``ec2_instance_metadata_server_internal`` for fetching from EC2 instance metadata or ``ecs_task_metadata_server_internal`` for fetching - from ECS task metadata. If these clusters are not provided in the bootstrap configuration then either of these will be added by default. + to fetch the credentials. To fetch the credentials from either EC2 instance metadata or ECS task metadata a static cluster pointing + towards the credentials provider is required. The static cluster name has to be ``ec2_instance_metadata_server_internal`` for fetching from EC2 instance + metadata or ``ecs_task_metadata_server_internal`` for fetching from ECS task metadata. + + If these clusters are not provided in the bootstrap configuration then either of these will be added by default. The static internal cluster will still be added even if initially ``envoy.reloadable_features.use_http_client_to_fetch_aws_credentials`` is not set so that subsequently if the reloadable feature is set to ``true`` the cluster config is available to fetch the credentials. Statistics ---------- -When using the ``envoy.reloadable_features.use_http_client_to_fetch_aws_credentials`` reloadable feature, the following -statistics are output under the ``aws.metadata_credentials_provider`` namespace: +The following statistics are output under the ``aws.metadata_credentials_provider`` namespace: .. csv-table:: :header: Name, Type, Description diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index 7089ef8daa47..1acdd3d55a31 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -93,6 +93,7 @@ RUNTIME_GUARD(envoy_reloadable_features_uhv_allow_malformed_url_encoding); RUNTIME_GUARD(envoy_reloadable_features_upstream_remote_address_use_connection); RUNTIME_GUARD(envoy_reloadable_features_use_config_in_happy_eyeballs); RUNTIME_GUARD(envoy_reloadable_features_use_http3_header_normalisation); +RUNTIME_GUARD(envoy_reloadable_features_use_http_client_to_fetch_aws_credentials); RUNTIME_GUARD(envoy_reloadable_features_use_route_host_mutation_for_auto_sni_san); RUNTIME_GUARD(envoy_reloadable_features_use_typed_metadata_in_proxy_protocol_listener); RUNTIME_GUARD(envoy_reloadable_features_validate_connect); @@ -127,11 +128,6 @@ FALSE_RUNTIME_GUARD(envoy_reloadable_features_always_use_v6); FALSE_RUNTIME_GUARD(envoy_restart_features_upstream_http_filters_with_tcp_proxy); // TODO(danzh) false deprecate it once QUICHE has its own enable/disable flag. FALSE_RUNTIME_GUARD(envoy_reloadable_features_quic_reject_all); -// TODO(suniltheta): Once the newly added http async technique is stabilized move it under -// RUNTIME_GUARD so that this option becomes default enabled. Once this option proves effective -// remove the feature flag and remove code path that relies on old technique to fetch credentials -// via libcurl and remove the bazel steps to pull and test the curl dependency. -FALSE_RUNTIME_GUARD(envoy_reloadable_features_use_http_client_to_fetch_aws_credentials); // TODO(#10646) change to true when UHV is sufficiently tested // For more information about Universal Header Validation, please see // https://github.com/envoyproxy/envoy/issues/10646 diff --git a/test/extensions/common/aws/credentials_provider_impl_test.cc b/test/extensions/common/aws/credentials_provider_impl_test.cc index 4db7d769046b..76a8472547b7 100644 --- a/test/extensions/common/aws/credentials_provider_impl_test.cc +++ b/test/extensions/common/aws/credentials_provider_impl_test.cc @@ -377,8 +377,6 @@ class InstanceProfileCredentialsProviderTest : public testing::Test { void setupProvider(MetadataFetcher::MetadataReceiver::RefreshState refresh_state = MetadataFetcher::MetadataReceiver::RefreshState::Ready, std::chrono::seconds initialization_timer = std::chrono::seconds(2)) { - scoped_runtime_.mergeValues( - {{"envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"}}); ON_CALL(context_, clusterManager()).WillByDefault(ReturnRef(cluster_manager_)); provider_ = std::make_shared( @@ -1080,6 +1078,10 @@ class InstanceProfileCredentialsProviderUsingLibcurlTest : public testing::Test : api_(Api::createApiForTest(time_system_)) {} void setupProvider() { + + scoped_runtime_.mergeValues( + {{"envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "false"}}); + provider_ = std::make_shared( *api_, absl::nullopt, [this](Http::RequestMessage& message) -> absl::optional { @@ -1134,6 +1136,7 @@ class InstanceProfileCredentialsProviderUsingLibcurlTest : public testing::Test EXPECT_CALL(fetch_metadata_, fetch(messageMatches(headers))).WillOnce(Return(document)); } + TestScopedRuntime scoped_runtime_; Event::SimulatedTimeSystem time_system_; Api::ApiPtr api_; NiceMock fetch_metadata_; @@ -1400,8 +1403,6 @@ class ContainerCredentialsProviderTest : public testing::Test { void setupProvider(MetadataFetcher::MetadataReceiver::RefreshState refresh_state = MetadataFetcher::MetadataReceiver::RefreshState::Ready, std::chrono::seconds initialization_timer = std::chrono::seconds(2)) { - scoped_runtime_.mergeValues( - {{"envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"}}); ON_CALL(context_, clusterManager()).WillByDefault(ReturnRef(cluster_manager_)); provider_ = std::make_shared( *api_, context_, @@ -1664,6 +1665,9 @@ class ContainerCredentialsProviderUsingLibcurlTest : public testing::Test { void setupProvider(MetadataFetcher::MetadataReceiver::RefreshState refresh_state = MetadataFetcher::MetadataReceiver::RefreshState::Ready, std::chrono::seconds initialization_timer = std::chrono::seconds(2)) { + scoped_runtime_.mergeValues( + {{"envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "false"}}); + provider_ = std::make_shared( *api_, absl::nullopt, [this](Http::RequestMessage& message) -> absl::optional { @@ -1682,6 +1686,7 @@ class ContainerCredentialsProviderUsingLibcurlTest : public testing::Test { EXPECT_CALL(fetch_metadata_, fetch(messageMatches(headers))).WillOnce(Return(document)); } + TestScopedRuntime scoped_runtime_; Event::SimulatedTimeSystem time_system_; Api::ApiPtr api_; NiceMock fetch_metadata_; @@ -1826,8 +1831,6 @@ class ContainerEKSPodIdentityCredentialsProviderTest : public testing::Test { void setupProvider(MetadataFetcher::MetadataReceiver::RefreshState refresh_state = MetadataFetcher::MetadataReceiver::RefreshState::Ready, std::chrono::seconds initialization_timer = std::chrono::seconds(2)) { - scoped_runtime_.mergeValues( - {{"envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"}}); ON_CALL(context_, clusterManager()).WillByDefault(ReturnRef(cluster_manager_)); provider_ = std::make_shared( *api_, context_, @@ -1950,8 +1953,6 @@ class WebIdentityCredentialsProviderTest : public testing::Test { void setupProvider(MetadataFetcher::MetadataReceiver::RefreshState refresh_state = MetadataFetcher::MetadataReceiver::RefreshState::Ready, std::chrono::seconds initialization_timer = std::chrono::seconds(2)) { - scoped_runtime_.mergeValues( - {{"envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"}}); ON_CALL(context_, clusterManager()).WillByDefault(ReturnRef(cluster_manager_)); provider_ = std::make_shared( *api_, context_, diff --git a/test/extensions/filters/http/aws_request_signing/aws_request_signing_integration_test.cc b/test/extensions/filters/http/aws_request_signing/aws_request_signing_integration_test.cc index ba0da9513745..6ddd2e81ffe1 100644 --- a/test/extensions/filters/http/aws_request_signing/aws_request_signing_integration_test.cc +++ b/test/extensions/filters/http/aws_request_signing/aws_request_signing_integration_test.cc @@ -74,8 +74,8 @@ class AwsRequestSigningIntegrationTest : public testing::TestWithParamwaitForCounterGe("aws.metadata_credentials_provider.sts_token_" @@ -370,8 +364,6 @@ TEST_F(InitializeFilterTest, TestWithOneClusterRouteLevelAndStandard) { TestEnvironment::setEnvVar("AWS_WEB_IDENTITY_TOKEN_FILE", "/path/to/web_token", 1); TestEnvironment::setEnvVar("AWS_ROLE_ARN", "aws:iam::123456789012:role/arn", 1); TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); addStandardFilter(); addPerRouteFilter(AWS_REQUEST_SIGNING_CONFIG_SIGV4_ROUTE_LEVEL); initialize(); @@ -389,8 +381,6 @@ TEST_F(InitializeFilterTest, TestWithTwoClustersStandard) { TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); TestEnvironment::setEnvVar("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/path/to/creds", 1); TestEnvironment::setEnvVar("AWS_CONTAINER_AUTHORIZATION_TOKEN", "auth_token", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); addStandardFilter(); initialize(); std::vector gauges = test_server_->gauges(); @@ -411,8 +401,6 @@ TEST_F(InitializeFilterTest, TestWithTwoClustersRouteLevel) { TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); TestEnvironment::setEnvVar("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/path/to/creds", 1); TestEnvironment::setEnvVar("AWS_CONTAINER_AUTHORIZATION_TOKEN", "auth_token", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); addPerRouteFilter(AWS_REQUEST_SIGNING_CONFIG_SIGV4_ROUTE_LEVEL); initialize(); test_server_->waitForCounterGe("aws.metadata_credentials_provider.ecs_task_" @@ -432,8 +420,6 @@ TEST_F(InitializeFilterTest, TestWithTwoClustersRouteLevelAndStandard) { TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); TestEnvironment::setEnvVar("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/path/to/creds", 1); TestEnvironment::setEnvVar("AWS_CONTAINER_AUTHORIZATION_TOKEN", "auth_token", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); addStandardFilter(); addPerRouteFilter(AWS_REQUEST_SIGNING_CONFIG_SIGV4_ROUTE_LEVEL); initialize(); @@ -451,8 +437,6 @@ TEST_F(InitializeFilterTest, TestWithTwoClustersStandardInstanceProfile) { TestEnvironment::setEnvVar("AWS_WEB_IDENTITY_TOKEN_FILE", "/path/to/web_token", 1); TestEnvironment::setEnvVar("AWS_ROLE_ARN", "aws:iam::123456789012:role/arn", 1); TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); addStandardFilter(); initialize(); test_server_->waitForCounterGe("aws.metadata_credentials_provider.ec2_instance_" @@ -469,8 +453,6 @@ TEST_F(InitializeFilterTest, TestWithTwoClustersRouteLevelInstanceProfile) { TestEnvironment::setEnvVar("AWS_WEB_IDENTITY_TOKEN_FILE", "/path/to/web_token", 1); TestEnvironment::setEnvVar("AWS_ROLE_ARN", "aws:iam::123456789012:role/arn", 1); TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); addPerRouteFilter(AWS_REQUEST_SIGNING_CONFIG_SIGV4_ROUTE_LEVEL); initialize(); test_server_->waitForCounterGe("aws.metadata_credentials_provider.ec2_instance_" @@ -487,8 +469,6 @@ TEST_F(InitializeFilterTest, TestWithTwoClustersRouteLevelAndStandardInstancePro TestEnvironment::setEnvVar("AWS_WEB_IDENTITY_TOKEN_FILE", "/path/to/web_token", 1); TestEnvironment::setEnvVar("AWS_ROLE_ARN", "aws:iam::123456789012:role/arn", 1); TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); addStandardFilter(); addPerRouteFilter(AWS_REQUEST_SIGNING_CONFIG_SIGV4_ROUTE_LEVEL); initialize(); @@ -560,8 +540,6 @@ TEST_F(CdsInteractionTest, ClusterRemovalRecreatesSTSCluster) { TestEnvironment::setEnvVar("AWS_WEB_IDENTITY_TOKEN_FILE", "/path/to/web_token", 1); TestEnvironment::setEnvVar("AWS_ROLE_ARN", "aws:iam::123456789012:role/arn", 1); TestEnvironment::setEnvVar("AWS_ROLE_SESSION_NAME", "role-session-name", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); CdsHelper cds_helper_; @@ -611,8 +589,6 @@ TEST_F(CdsInteractionTest, ClusterRemovalRecreatesSTSCluster) { TEST_F(CdsInteractionTest, ClusterRemovalRecreatesIMDSCluster) { // Instance Metadata Service only TestEnvironment::setEnvVar("AWS_EC2_METADATA_DISABLED", "false", 1); - config_helper_.addRuntimeOverride( - "envoy.reloadable_features.use_http_client_to_fetch_aws_credentials", "true"); CdsHelper cds_helper_;