1
#pragma once
2

            
3
#include "envoy/extensions/common/aws/v3/credential_provider.pb.h"
4

            
5
#include "source/extensions/common/aws/aws_cluster_manager.h"
6
#include "source/extensions/common/aws/metadata_credentials_provider_base.h"
7
#include "source/extensions/common/aws/metadata_fetcher.h"
8
#include "source/extensions/common/aws/signers/iam_roles_anywhere_sigv4_signer_impl.h"
9

            
10
namespace Envoy {
11
namespace Extensions {
12
namespace Common {
13
namespace Aws {
14

            
15
constexpr char ROLESANYWHERE_SERVICE[] = "rolesanywhere";
16

            
17
/**
18
 *
19
 * IAMRolesAnywhereCredentialsProvider purpose is to exchange X509 Credentials for Temporary AWS
20
 * Credentials
21
 *
22
 * When instantiated via config, it will create an IAMRolesAnywhereX509CredentialsProvider, which
23
 * manages the X509 Credentials. IAMRolesAnywhereCredentialsProvider works in the same way as
24
 * WebIdentityCredentialsProvider, by using the async HTTP client to send requests to the AWS IAM
25
 * Roles Anywhere service and retrieve temporary AWS Credentials. It is therefore a subclass of
26
 * MetadataCredentialsProviderBase, which handles the async credential fetch and cluster creation
27
 * for the IAM Roles Anywhere endpoint.
28
 *
29
 * The X509 SigV4 signing process is performed via IAMRolesAnywhereSigV4Signer, which is a
30
 * modification of standard SigV4 signing to use X509 credentials as the signing input.
31
 * IAMRolesAnywhereCredentialsProvider is the only consumer of IAMRolesAnywhereSigV4Signer.
32
 *
33
 * The logic is as follows:
34
 *   1. IAMRolesAnywhereX509CredentialsProvider retrieves X509 credentials and converts them to
35
 * required format
36
 *
37
 *   2. IAMRolesAnywhereCredentialsProvider uses credentials from
38
 * IAMRolesAnywhereX509CredentialsProvider, and uses them as input to
39
 * IAMRolesAnywhereSigV4Signer
40
 *
41
 *   3. Once signing has completed, IAMRolesAnywhereCredentialsProvider requests temporary
42
 * credentials from IAM Roles Anywhere endpoint using the signed payload
43
 *
44
 *   4. Temporary credentials are returned, which then can be used in normal AWS SigV4/SigV4A
45
 * signing
46
 *
47
 */
48

            
49
class IAMRolesAnywhereCredentialsProvider : public MetadataCredentialsProviderBase,
50
                                            public MetadataFetcher::MetadataReceiver {
51
public:
52
  IAMRolesAnywhereCredentialsProvider(
53
      Server::Configuration::ServerFactoryContext& context,
54
      AwsClusterManagerPtr aws_cluster_manager, absl::string_view cluster_name,
55
      CreateMetadataFetcherCb create_metadata_fetcher_cb, absl::string_view region,
56
      MetadataFetcher::MetadataReceiver::RefreshState refresh_state,
57
      std::chrono::seconds initialization_timer,
58
      std::unique_ptr<Extensions::Common::Aws::IAMRolesAnywhereSigV4Signer> roles_anywhere_signer,
59
      const envoy::extensions::common::aws::v3::IAMRolesAnywhereCredentialProvider
60
          iam_roles_anywhere_config);
61

            
62
  // Following functions are for MetadataFetcher::MetadataReceiver interface
63
  void onMetadataSuccess(const std::string&& body) override;
64
  void onMetadataError(Failure reason) override;
65
16
  std::string providerName() override { return "IAMRolesAnywhereCredentialsProvider"; };
66

            
67
private:
68
  void refresh() override;
69
  void extractCredentials(const std::string&& credential_document_value);
70

            
71
  const std::string role_arn_;
72
  const std::string role_session_name_;
73
  const std::string profile_arn_;
74
  const std::string trust_anchor_arn_;
75
  const std::string region_;
76
  absl::optional<uint16_t> session_duration_;
77
  std::unique_ptr<Extensions::Common::Aws::IAMRolesAnywhereSigV4Signer> roles_anywhere_signer_;
78
};
79

            
80
using IAMRolesAnywhereCredentialsProviderPtr = std::shared_ptr<IAMRolesAnywhereCredentialsProvider>;
81

            
82
} // namespace Aws
83
} // namespace Common
84
} // namespace Extensions
85
} // namespace Envoy