diff --git a/pom.xml b/pom.xml
index 9cbac99dc1..16353f84d8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2990,6 +2990,11 @@
software.amazon.awssdk
transcribe
+
+
+ software.amazon.awssdk
+ secretsmanager
+
com.amazon.athena
diff --git a/src/prerna/io/connector/secrets/ISecrets.java b/src/prerna/io/connector/secrets/ISecrets.java
index 4a0a1a0cfe..ec9b6852b6 100644
--- a/src/prerna/io/connector/secrets/ISecrets.java
+++ b/src/prerna/io/connector/secrets/ISecrets.java
@@ -46,6 +46,7 @@ public interface ISecrets {
String AZURE_KEYVAULT = "AZURE_KEYVAULT";
String HASHICORP_VAULT = "HASHICORP_VAULT";
+ String AWS_SECRETS_MANAGER = "AWS_SECRETS_MANAGER";
String IV = "iv";
String SECRET = "secret";
String SALT = "salt";
diff --git a/src/prerna/io/connector/secrets/SecretsFactory.java b/src/prerna/io/connector/secrets/SecretsFactory.java
index f4ddf1580b..e24b70c484 100644
--- a/src/prerna/io/connector/secrets/SecretsFactory.java
+++ b/src/prerna/io/connector/secrets/SecretsFactory.java
@@ -30,6 +30,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import prerna.io.connector.secrets.aws.secretsmanager.AWSSecretsManagerUtil;
import prerna.io.connector.secrets.azure.keyvault.AzureKeyVaultUtil;
import prerna.io.connector.secrets.hashicorp.vault.HashiCorpVaultUtil;
import prerna.util.Constants;
@@ -53,6 +54,8 @@ public static ISecrets getSecretConnector() {
return HashiCorpVaultUtil.getInstance();
} else if (storeType.equalsIgnoreCase(ISecrets.AZURE_KEYVAULT)) {
return AzureKeyVaultUtil.getInstance();
+ } else if (storeType.equalsIgnoreCase(ISecrets.AWS_SECRETS_MANAGER)) {
+ return AWSSecretsManagerUtil.getInstance();
} else {
classLogger.warn("Secret store is enabled but could not find type for input = '{}'", storeType);
return null;
diff --git a/src/prerna/io/connector/secrets/aws/secretsmanager/AWSSecretsManagerUtil.java b/src/prerna/io/connector/secrets/aws/secretsmanager/AWSSecretsManagerUtil.java
new file mode 100644
index 0000000000..d5ee01e55b
--- /dev/null
+++ b/src/prerna/io/connector/secrets/aws/secretsmanager/AWSSecretsManagerUtil.java
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * Copyright 2015 Defense Health Agency (DHA)
+ *
+ * If your use of this software does not include any GPLv2 components:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ----------------------------------------------------------------------------
+ * If your use of this software includes any GPLv2 components:
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *******************************************************************************/
+package prerna.io.connector.secrets.aws.secretsmanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.reflect.TypeToken;
+
+import prerna.engine.api.IEngine;
+import prerna.engine.api.IEngine.CATALOG_TYPE;
+import prerna.io.connector.secrets.AbstractSecrets;
+import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
+import software.amazon.awssdk.services.secretsmanager.model.CreateSecretRequest;
+import software.amazon.awssdk.services.secretsmanager.model.DeleteSecretRequest;
+import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
+import software.amazon.awssdk.services.secretsmanager.model.PutSecretValueRequest;
+import software.amazon.awssdk.services.secretsmanager.model.ResourceNotFoundException;
+
+public final class AWSSecretsManagerUtil extends AbstractSecrets {
+
+ /**
+ *
+ * AWS Secrets Manager secret names only allow alphanumeric characters and the
+ * following: /_+=.@- (this is a superset of what Vault/Azure allow, so
+ * engine/insight ids - which are UUIDs - are always safe to use directly)
+ *
+ */
+
+ private static final Logger classLogger = LogManager.getLogger(AWSSecretsManagerUtil.class);
+
+ private static final String AWS_REGION = "AWS_REGION";
+
+ private static volatile AWSSecretsManagerUtil instance;
+
+ private SecretsManagerClient secretsManagerClient;
+
+ private AWSSecretsManagerUtil() {
+ createSecretsManagerClient();
+ }
+
+ private void createSecretsManagerClient() {
+ String region = getInput(AWS_REGION);
+ if (region == null || (region = region.trim()).isEmpty()) {
+ throw new NullPointerException("Must define the AWS region using " + AWS_REGION);
+ }
+
+ // use the standard AWS credential chain (env vars, shared config/profile, or
+ // IAM role) rather than static keys - mirrors Azure's DefaultAzureCredentialBuilder
+ // branch and avoids hardcoding secret-store credentials
+ this.secretsManagerClient = SecretsManagerClient.builder().region(Region.of(region))
+ .credentialsProvider(DefaultCredentialsProvider.create()).build();
+ }
+
+ public static AWSSecretsManagerUtil getInstance() {
+ if (instance != null) {
+ return instance;
+ }
+
+ if (instance == null) {
+ synchronized (AWSSecretsManagerUtil.class) {
+ if (instance == null) {
+ try {
+ instance = new AWSSecretsManagerUtil();
+ } catch (Exception e) {
+ classLogger.error(
+ "Failed to initialize AWSSecretsManagerUtil singleton. Verify configuration for {}.",
+ AWS_REGION, e);
+ }
+ }
+ }
+ }
+
+ return instance;
+ }
+
+ /**
+ *
+ * @param eType
+ * @param enginePath
+ * @return
+ */
+ private String getPathForEngine(IEngine.CATALOG_TYPE eType, String enginePath) {
+ String base = getBaseForEngine(eType);
+ if (base != null && !(base = base.trim()).isEmpty()) {
+ return base + "/" + enginePath;
+ }
+ return enginePath;
+ }
+
+ /**
+ * Get the full path for the insight secrets
+ *
+ * @param projectPath
+ * @param insightId
+ * @return
+ */
+ private String getInsightPath(String projectPath, String insightId) {
+ return getPathForEngine(IEngine.CATALOG_TYPE.PROJECT, projectPath) + "/" + insightId;
+ }
+
+ /**
+ * Read a secret from AWS Secrets Manager and parse its string value as a JSON
+ * object map.
+ *
+ * @param secretPath the Secrets Manager secret name/id to read
+ * @return the parsed name-value pairs, or {@code null} if the stored value is
+ * not valid JSON
+ */
+ private Map readSecretMap(String secretPath) {
+ String value = this.secretsManagerClient
+ .getSecretValue(GetSecretValueRequest.builder().secretId(secretPath).build()).secretString();
+ Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+ return gson.fromJson(value, new TypeToken