1
#pragma once
2
#include "envoy/extensions/common/aws/v3/credential_provider.pb.h"
3
#include "envoy/server/factory_context.h"
4

            
5
#include "source/extensions/common/aws/aws_cluster_manager.h"
6
#include "source/extensions/common/aws/credential_providers/credentials_file_credentials_provider.h"
7
#include "source/extensions/common/aws/credential_providers/environment_credentials_provider.h"
8
#include "source/extensions/common/aws/credential_providers/webidentity_credentials_provider.h"
9
#include "source/extensions/common/aws/credentials_provider.h"
10
#include "source/extensions/common/aws/metadata_credentials_provider_base.h"
11
#include "source/extensions/common/aws/metadata_fetcher.h"
12

            
13
namespace Envoy {
14
namespace Extensions {
15
namespace Common {
16
namespace Aws {
17

            
18
using AwsCredentialProviderOptRef =
19
    OptRef<const envoy::extensions::common::aws::v3::AwsCredentialProvider>;
20

            
21
class CredentialsProviderChainFactories {
22
public:
23
139
  virtual ~CredentialsProviderChainFactories() = default;
24

            
25
  virtual CredentialsProviderSharedPtr createEnvironmentCredentialsProvider() const PURE;
26

            
27
  virtual CredentialsProviderSharedPtr createCredentialsFileCredentialsProvider(
28
      Server::Configuration::ServerFactoryContext& context,
29
      const envoy::extensions::common::aws::v3::CredentialsFileCredentialProvider&
30
          credential_file_config = {}) const PURE;
31

            
32
  virtual CredentialsProviderSharedPtr createWebIdentityCredentialsProvider(
33
      Server::Configuration::ServerFactoryContext& context,
34
      AwsClusterManagerPtr aws_cluster_manager, absl::string_view region,
35
      const envoy::extensions::common::aws::v3::AssumeRoleWithWebIdentityCredentialProvider&
36
          web_identity_config) PURE;
37

            
38
  virtual CredentialsProviderSharedPtr createContainerCredentialsProvider(
39
      Server::Configuration::ServerFactoryContext& context,
40
      AwsClusterManagerPtr aws_cluster_manager, CreateMetadataFetcherCb create_metadata_fetcher_cb,
41
      absl::string_view cluster_name, absl::string_view credential_uri,
42
      MetadataFetcher::MetadataReceiver::RefreshState refresh_state,
43
      std::chrono::seconds initialization_timer, absl::string_view authorization_token = {}) PURE;
44

            
45
  virtual CredentialsProviderSharedPtr createInstanceProfileCredentialsProvider(
46
      Server::Configuration::ServerFactoryContext& context,
47
      AwsClusterManagerPtr aws_cluster_manager, CreateMetadataFetcherCb create_metadata_fetcher_cb,
48
      MetadataFetcher::MetadataReceiver::RefreshState refresh_state,
49
      std::chrono::seconds initialization_timer, absl::string_view cluster_name) PURE;
50

            
51
  virtual CredentialsProviderSharedPtr createAssumeRoleCredentialsProvider(
52
      Server::Configuration::ServerFactoryContext& context,
53
      AwsClusterManagerPtr aws_cluster_manager, absl::string_view region,
54
      const envoy::extensions::common::aws::v3::AssumeRoleCredentialProvider& assume_role_config)
55
      PURE;
56

            
57
  virtual CredentialsProviderSharedPtr createIAMRolesAnywhereCredentialsProvider(
58
      Server::Configuration::ServerFactoryContext& context,
59
      AwsClusterManagerPtr aws_cluster_manager, absl::string_view region,
60
      const envoy::extensions::common::aws::v3::IAMRolesAnywhereCredentialProvider&
61
          iam_roles_anywhere_config) const PURE;
62

            
63
protected:
64
68
  std::string stsClusterName(absl::string_view region) {
65
68
    return absl::StrCat(STS_TOKEN_CLUSTER, "-", region);
66
68
  }
67

            
68
104
  std::string sessionName(Api::Api& api) {
69
104
    const auto role_session_name = absl::NullSafeStringView(std::getenv(AWS_ROLE_SESSION_NAME));
70
104
    std::string actual_session_name;
71
104
    if (!role_session_name.empty()) {
72
29
      actual_session_name = std::string(role_session_name);
73
98
    } else {
74
      // In practice, this value will be provided by the environment, so the placeholder value is
75
      // not important. Some AWS SDKs use time in nanoseconds, so we'll just use that.
76
75
      const auto now_nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(
77
75
                                 api.timeSource().systemTime().time_since_epoch())
78
75
                                 .count();
79
75
      actual_session_name = fmt::format("{}", now_nanos);
80
75
    }
81
104
    return actual_session_name;
82
104
  }
83
};
84

            
85
/**
86
 * AWS credentials provider chain.
87
 *
88
 * Reference implementation:
89
 * https://github.com/aws/aws-sdk-cpp/blob/master/aws-cpp-sdk-core/source/auth/AWSCredentialsProviderChain.cpp#L44
90
 */
91

            
92
class CommonCredentialsProviderChain : public CredentialsProviderChain,
93
                                       public CredentialsProviderChainFactories {
94
public:
95
  CommonCredentialsProviderChain(Server::Configuration::ServerFactoryContext& context,
96
                                 absl::string_view region,
97
                                 AwsCredentialProviderOptRef credential_provider_config)
98
95
      : CommonCredentialsProviderChain(context, region, credential_provider_config, *this) {}
99

            
100
  CommonCredentialsProviderChain(Server::Configuration::ServerFactoryContext& context,
101
                                 absl::string_view region,
102
                                 AwsCredentialProviderOptRef credential_provider_config,
103
                                 CredentialsProviderChainFactories& factories);
104

            
105
  /*
106
   * Create a custom credential provider chain using config provided in credential_provider_config
107
   */
108

            
109
  static absl::StatusOr<CredentialsProviderChainSharedPtr> customCredentialsProviderChain(
110
      Server::Configuration::ServerFactoryContext& context, absl::string_view region,
111
      const envoy::extensions::common::aws::v3::AwsCredentialProvider& credential_provider_config);
112

            
113
  /*
114
   * Create the default credential provider chain
115
   */
116

            
117
  static CredentialsProviderChainSharedPtr
118
  defaultCredentialsProviderChain(Server::Configuration::ServerFactoryContext& context,
119
                                  absl::string_view region);
120

            
121
  // Where credential providers use async functionality, subscribe to credential notifications for
122
  // these providers
123
  void setupSubscriptions();
124

            
125
private:
126
88
  CredentialsProviderSharedPtr createEnvironmentCredentialsProvider() const override {
127
88
    return std::make_shared<EnvironmentCredentialsProvider>();
128
88
  }
129

            
130
  CredentialsProviderSharedPtr createCredentialsFileCredentialsProvider(
131
      Server::Configuration::ServerFactoryContext& context,
132
      const envoy::extensions::common::aws::v3::CredentialsFileCredentialProvider&
133
          credential_file_config
134

            
135
87
  ) const override {
136
87
    return std::make_shared<CredentialsFileCredentialsProvider>(context, credential_file_config);
137
87
  };
138

            
139
  CredentialsProviderSharedPtr createContainerCredentialsProvider(
140
      Server::Configuration::ServerFactoryContext& context,
141
      AwsClusterManagerPtr aws_cluster_manager, CreateMetadataFetcherCb create_metadata_fetcher_cb,
142
      absl::string_view cluster_name, absl::string_view credential_uri,
143
      MetadataFetcher::MetadataReceiver::RefreshState refresh_state,
144
      std::chrono::seconds initialization_timer, absl::string_view authorization_token) override;
145

            
146
  CredentialsProviderSharedPtr createInstanceProfileCredentialsProvider(
147
      Server::Configuration::ServerFactoryContext& context,
148
      AwsClusterManagerPtr aws_cluster_manager, CreateMetadataFetcherCb create_metadata_fetcher_cb,
149
      MetadataFetcher::MetadataReceiver::RefreshState refresh_state,
150
      std::chrono::seconds initialization_timer, absl::string_view cluster_name) override;
151

            
152
  CredentialsProviderSharedPtr createWebIdentityCredentialsProvider(
153
      Server::Configuration::ServerFactoryContext& context,
154
      AwsClusterManagerPtr aws_cluster_manager, absl::string_view region,
155
      const envoy::extensions::common::aws::v3::AssumeRoleWithWebIdentityCredentialProvider&
156
          web_identity_config) override;
157

            
158
  CredentialsProviderSharedPtr createAssumeRoleCredentialsProvider(
159
      Server::Configuration::ServerFactoryContext& context,
160
      AwsClusterManagerPtr aws_cluster_manager, absl::string_view region,
161
      const envoy::extensions::common::aws::v3::AssumeRoleCredentialProvider& assume_role_config)
162
      override;
163

            
164
  CredentialsProviderSharedPtr createIAMRolesAnywhereCredentialsProvider(
165
      Server::Configuration::ServerFactoryContext& context,
166
      AwsClusterManagerPtr aws_cluster_manager, absl::string_view region,
167
      const envoy::extensions::common::aws::v3::IAMRolesAnywhereCredentialProvider&
168
          iam_roles_anywhere_config) const override;
169

            
170
  AwsClusterManagerPtr aws_cluster_manager_;
171
};
172

            
173
} // namespace Aws
174
} // namespace Common
175
} // namespace Extensions
176
} // namespace Envoy