Skip to content

Commit cf48065

Browse files
majetideepakfacebook-github-bot
authored andcommitted
feat(S3): Add payload-signing-policy config (#12197)
Summary: Some use-cases require the payload to be signed for additional security. Add hive.s3.payload-signing-policy config to allow this. Move away from deprecated S3Client API. Pull Request resolved: #12197 Reviewed By: Yuhta Differential Revision: D69254094 Pulled By: kgpai fbshipit-source-id: b75c1e827db29520f3fabf4270af897860d68b2f
1 parent 788555c commit cf48065

File tree

6 files changed

+54
-8
lines changed

6 files changed

+54
-8
lines changed

velox/connectors/hive/storage_adapters/s3fs/S3Config.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ S3Config::S3Config(
7373
}
7474
}
7575
}
76+
payloadSigningPolicy_ =
77+
properties->get<std::string>(kS3PayloadSigningPolicy, "Never");
7678
}
7779

7880
std::optional<std::string> S3Config::endpointRegion() const {

velox/connectors/hive/storage_adapters/s3fs/S3Config.h

+9
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class S3Config {
4747
/// Log granularity of AWS C++ SDK.
4848
static constexpr const char* kS3LogLevel = "hive.s3.log-level";
4949

50+
/// Payload signing policy.
51+
static constexpr const char* kS3PayloadSigningPolicy =
52+
"hive.s3.payload-signing-policy";
53+
5054
/// S3FileSystem default identity.
5155
static constexpr const char* kDefaultS3Identity = "s3-default-identity";
5256

@@ -220,8 +224,13 @@ class S3Config {
220224
return folly::to<bool>(value);
221225
}
222226

227+
std::string payloadSigningPolicy() const {
228+
return payloadSigningPolicy_;
229+
}
230+
223231
private:
224232
std::unordered_map<Keys, std::optional<std::string>> config_;
233+
std::string payloadSigningPolicy_;
225234
};
226235

227236
} // namespace facebook::velox::filesystems

velox/connectors/hive/storage_adapters/s3fs/S3FileSystem.cpp

+21-5
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,21 @@ Aws::Utils::Logging::LogLevel inferS3LogLevel(std::string_view logLevel) {
218218
}
219219
return Aws::Utils::Logging::LogLevel::Fatal;
220220
}
221+
222+
// Supported values are "Always", "RequestDependent", "Never"(default).
223+
Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy inferPayloadSign(
224+
std::string sign) {
225+
// Convert to upper case.
226+
std::transform(sign.begin(), sign.end(), sign.begin(), [](unsigned char c) {
227+
return std::toupper(c);
228+
});
229+
if (sign == "ALWAYS") {
230+
return Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Always;
231+
} else if (sign == "REQUESTDEPENDENT") {
232+
return Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::RequestDependent;
233+
}
234+
return Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never;
235+
}
221236
} // namespace
222237

223238
class S3WriteFile::Impl {
@@ -529,7 +544,7 @@ class S3FileSystem::Impl {
529544
public:
530545
Impl(const S3Config& s3Config) {
531546
VELOX_CHECK(getAwsInstance()->isInitialized(), "S3 is not initialized");
532-
Aws::Client::ClientConfiguration clientConfig;
547+
Aws::S3::S3ClientConfiguration clientConfig;
533548
if (s3Config.endpoint().has_value()) {
534549
clientConfig.endpointOverride = s3Config.endpoint().value();
535550
}
@@ -586,13 +601,14 @@ class S3FileSystem::Impl {
586601
clientConfig.retryStrategy = retryStrategy.value();
587602
}
588603

604+
clientConfig.useVirtualAddressing = s3Config.useVirtualAddressing();
605+
clientConfig.payloadSigningPolicy =
606+
inferPayloadSign(s3Config.payloadSigningPolicy());
607+
589608
auto credentialsProvider = getCredentialsProvider(s3Config);
590609

591610
client_ = std::make_shared<Aws::S3::S3Client>(
592-
credentialsProvider,
593-
clientConfig,
594-
Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never,
595-
s3Config.useVirtualAddressing());
611+
credentialsProvider, nullptr /* endpointProvider */, clientConfig);
596612
++fileSystemCount;
597613
}
598614

velox/connectors/hive/storage_adapters/s3fs/tests/CMakeLists.txt

+10-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
add_executable(velox_s3file_test S3FileSystemTest.cpp S3UtilTest.cpp
16-
S3ConfigTest.cpp)
15+
add_executable(velox_s3config_test S3ConfigTest.cpp)
16+
add_test(velox_s3config_test velox_s3config_test)
17+
target_link_libraries(
18+
velox_s3config_test
19+
velox_common_config
20+
velox_s3fs
21+
GTest::gtest
22+
GTest::gtest_main)
23+
24+
add_executable(velox_s3file_test S3FileSystemTest.cpp S3UtilTest.cpp)
1725
add_test(velox_s3file_test velox_s3file_test)
1826
target_link_libraries(
1927
velox_s3file_test

velox/connectors/hive/storage_adapters/s3fs/tests/S3ConfigTest.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ TEST(S3ConfigTest, defaultConfig) {
3434
ASSERT_EQ(s3Config.secretKey(), std::nullopt);
3535
ASSERT_EQ(s3Config.iamRole(), std::nullopt);
3636
ASSERT_EQ(s3Config.iamRoleSessionName(), "velox-session");
37+
ASSERT_EQ(s3Config.payloadSigningPolicy(), "Never");
3738
}
3839

3940
TEST(S3ConfigTest, overrideConfig) {
@@ -42,6 +43,7 @@ TEST(S3ConfigTest, overrideConfig) {
4243
{S3Config::baseConfigKey(S3Config::Keys::kSSLEnabled), "false"},
4344
{S3Config::baseConfigKey(S3Config::Keys::kUseInstanceCredentials),
4445
"true"},
46+
{"hive.s3.payload-signing-policy", "RequestDependent"},
4547
{S3Config::baseConfigKey(S3Config::Keys::kEndpoint), "endpoint"},
4648
{S3Config::baseConfigKey(S3Config::Keys::kEndpointRegion), "region"},
4749
{S3Config::baseConfigKey(S3Config::Keys::kAccessKey), "access"},
@@ -59,6 +61,7 @@ TEST(S3ConfigTest, overrideConfig) {
5961
ASSERT_EQ(s3Config.secretKey(), std::optional("secret"));
6062
ASSERT_EQ(s3Config.iamRole(), std::optional("iam"));
6163
ASSERT_EQ(s3Config.iamRoleSessionName(), "velox");
64+
ASSERT_EQ(s3Config.payloadSigningPolicy(), "RequestDependent");
6265
}
6366

6467
TEST(S3ConfigTest, overrideBucketConfig) {
@@ -74,6 +77,7 @@ TEST(S3ConfigTest, overrideBucketConfig) {
7477
{S3Config::baseConfigKey(S3Config::Keys::kAccessKey), "access"},
7578
{S3Config::bucketConfigKey(S3Config::Keys::kAccessKey, bucket),
7679
"bucket-access"},
80+
{"hive.s3.payload-signing-policy", "Always"},
7781
{S3Config::baseConfigKey(S3Config::Keys::kSecretKey), "secret"},
7882
{S3Config::bucketConfigKey(S3Config::Keys::kSecretKey, bucket),
7983
"bucket-secret"},
@@ -92,6 +96,7 @@ TEST(S3ConfigTest, overrideBucketConfig) {
9296
ASSERT_EQ(s3Config.secretKey(), std::optional("bucket-secret"));
9397
ASSERT_EQ(s3Config.iamRole(), std::optional("iam"));
9498
ASSERT_EQ(s3Config.iamRoleSessionName(), "velox");
99+
ASSERT_EQ(s3Config.payloadSigningPolicy(), "Always");
95100
}
96101

97102
} // namespace

velox/docs/configs.rst

+7-1
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,14 @@ Each query can override the config by setting corresponding query session proper
696696
* - hive.s3.log-level
697697
- string
698698
- FATAL
699-
- **Allowed values:** "OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"
699+
- **Allowed values:** "OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE".
700700
Granularity of logging generated by the AWS C++ SDK library.
701+
* - hive.s3.payload-signing-policy
702+
- string
703+
- Never
704+
- **Allowed values:** "Always", "RequestDependent", "Never".
705+
When set to "Always", the payload checksum is included in the signature calculation.
706+
When set to "RequestDependent", the payload checksum is included based on the value returned by "AmazonWebServiceRequest::SignBody()".
701707
* - hive.s3.iam-role
702708
- string
703709
-

0 commit comments

Comments
 (0)