diff --git a/tiledb/sm/c_api/tiledb.h b/tiledb/sm/c_api/tiledb.h
index 2587046b89a2..0a320ec19ff3 100644
--- a/tiledb/sm/c_api/tiledb.h
+++ b/tiledb/sm/c_api/tiledb.h
@@ -1000,6 +1000,9 @@ TILEDB_EXPORT void tiledb_config_free(tiledb_config_t** config);
* - `vfs.s3.aws_secret_access_key`
* Set the AWS_SECRET_ACCESS_KEY
* **Default**: ""
+ * - `vfs.s3.aws_access_key_id`
+ * Set the AWS_SESSION_TOKEN
+ * **Default**: ""
* - `vfs.s3.scheme`
* The S3 scheme (`http` or `https`), if S3 is enabled.
* **Default**: https
diff --git a/tiledb/sm/config/config.cc b/tiledb/sm/config/config.cc
index 03f1a786055f..0e6111fb6851 100644
--- a/tiledb/sm/config/config.cc
+++ b/tiledb/sm/config/config.cc
@@ -83,6 +83,7 @@ const std::string Config::VFS_FILE_ENABLE_FILELOCKS = "true";
const std::string Config::VFS_S3_REGION = "us-east-1";
const std::string Config::VFS_S3_AWS_ACCESS_KEY_ID = "";
const std::string Config::VFS_S3_AWS_SECRET_ACCESS_KEY = "";
+const std::string Config::VFS_S3_AWS_SESSION_TOKEN = "";
const std::string Config::VFS_S3_SCHEME = "https";
const std::string Config::VFS_S3_ENDPOINT_OVERRIDE = "";
const std::string Config::VFS_S3_USE_VIRTUAL_ADDRESSING = "true";
@@ -117,6 +118,7 @@ const std::set Config::unserialized_params_ = {
"vfs.s3.proxy_password",
"vfs.s3.aws_access_key_id",
"vfs.s3.aws_secret_access_key",
+ "vfs.s3.aws_session_token",
"rest.username",
"rest.password",
"rest.token",
@@ -162,6 +164,7 @@ Config::Config() {
param_values_["vfs.s3.region"] = VFS_S3_REGION;
param_values_["vfs.s3.aws_access_key_id"] = VFS_S3_AWS_ACCESS_KEY_ID;
param_values_["vfs.s3.aws_secret_access_key"] = VFS_S3_AWS_SECRET_ACCESS_KEY;
+ param_values_["vfs.s3.aws_session_token"] = VFS_S3_AWS_SESSION_TOKEN;
param_values_["vfs.s3.scheme"] = VFS_S3_SCHEME;
param_values_["vfs.s3.endpoint_override"] = VFS_S3_ENDPOINT_OVERRIDE;
param_values_["vfs.s3.use_virtual_addressing"] =
@@ -373,6 +376,8 @@ Status Config::unset(const std::string& param) {
} else if (param == "vfs.s3.aws_secret_access_key") {
param_values_["vfs.s3.aws_secret_access_key"] =
VFS_S3_AWS_SECRET_ACCESS_KEY;
+ } else if (param == "vfs.s3.aws_session_token") {
+ param_values_["vfs.s3.aws_session_token"] = VFS_S3_AWS_SESSION_TOKEN;
} else if (param == "vfs.s3.logging_level") {
param_values_["vfs.s3.logging_level"] = VFS_S3_LOGGING_LEVEL;
} else if (param == "vfs.s3.scheme") {
diff --git a/tiledb/sm/config/config.h b/tiledb/sm/config/config.h
index 700e0980b2f2..c6244a6962dc 100644
--- a/tiledb/sm/config/config.h
+++ b/tiledb/sm/config/config.h
@@ -173,6 +173,9 @@ class Config {
/** S3 aws secret access key. */
static const std::string VFS_S3_AWS_SECRET_ACCESS_KEY;
+ /** S3 aws session token. */
+ static const std::string VFS_S3_AWS_SESSION_TOKEN;
+
/** S3 scheme (http for local minio, https for AWS S3). */
static const std::string VFS_S3_SCHEME;
diff --git a/tiledb/sm/cpp_api/config.h b/tiledb/sm/cpp_api/config.h
index 519c711224aa..b5ce2621b716 100644
--- a/tiledb/sm/cpp_api/config.h
+++ b/tiledb/sm/cpp_api/config.h
@@ -335,6 +335,9 @@ class Config {
* - `vfs.s3.aws_secret_access_key`
* Set the AWS_SECRET_ACCESS_KEY
* **Default**: ""
+ * - `vfs.s3.aws_session_token`
+ * Set the AWS_SESSION_TOKEN
+ * **Default**: ""
* - `vfs.s3.scheme`
* The S3 scheme (`http` or `https`), if S3 is enabled.
* **Default**: https
diff --git a/tiledb/sm/filesystem/s3.cc b/tiledb/sm/filesystem/s3.cc
index ddf362db3a27..b0934002d94c 100644
--- a/tiledb/sm/filesystem/s3.cc
+++ b/tiledb/sm/filesystem/s3.cc
@@ -224,6 +224,8 @@ Status S3::init(const Config& config, ThreadPool* const thread_pool) {
auto aws_secret_access_key =
config.get("vfs.s3.aws_secret_access_key", &found);
assert(found);
+ auto aws_session_token = config.get("vfs.s3.aws_session_token", &found);
+ assert(found);
int64_t connect_max_tries = 0;
RETURN_NOT_OK(config.get(
"vfs.s3.connect_max_tries", &connect_max_tries, &found));
@@ -265,6 +267,17 @@ Status S3::init(const Config& config, ThreadPool* const thread_pool) {
Aws::String secret_access_key(aws_secret_access_key.c_str());
client_creds_ = std::unique_ptr(
new Aws::Auth::AWSCredentials(access_key_id, secret_access_key));
+
+ // If the user has set a session token (for AWS Security Token Service)
+ // then use it:
+ // - https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html
+ // For testing run: `aws sts get-session-token --duration-seconds 900`. See:
+ // -
+ // https://docs.aws.amazon.com/cli/latest/reference/sts/get-session-token.html
+ if (!aws_session_token.empty()) {
+ Aws::String session_token(aws_session_token.c_str());
+ client_creds_->SetSessionToken(session_token);
+ }
}
state_ = State::INITIALIZED;