aws-secrets-manager-rotation-lambdas icon indicating copy to clipboard operation
aws-secrets-manager-rotation-lambdas copied to clipboard

Password length

Open dmfilipenko opened this issue 4 years ago • 7 comments

Almost all of their lambdas dont take into account the password length parameter. Only four of lambdas use password length as argument, but it's hardcoded. Can we pass password length as env variable, as it's done with excluded character?

dmfilipenko avatar Dec 22 '20 02:12 dmfilipenko

@jpeddicord @hyandell @zebehringer @zebehringer @parimaldeshmukh anyone can help with this?

dmfilipenko avatar Jan 08 '21 16:01 dmfilipenko

maybe it should handle all parameters https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-secretsmanager-secret-generatesecretstring.html and not only the password length

florentcuret avatar Feb 12 '21 08:02 florentcuret

Thank you for your feedback. We have noted this as a feature request.

whygoyal avatar Mar 02 '22 20:03 whygoyal

This seems like a bug - if a GenerateSecretString config is provided for the Secret, it seems a rotation mechanism should honor this config.

Also, the current workaround of providing an environment variable 'EXCLUDE_CHARACTERS' doesn't even seem to help if you're deploying the secret with Cloudformation, since there doesn't seem to be any way to define environment variables for a HostedRotationLambda.

JensRoland avatar Apr 05 '22 09:04 JensRoland

Do you have any update on this please? We have a hard requirement on 30 characters for password length and are not able to specify this as an input parameter to this application.

ben-eb avatar Oct 19 '23 11:10 ben-eb

Suggested patch:

From 41b89b9a0c60fc97e7988200d2c5ddb3b905c17c Mon Sep 17 00:00:00 2001
From: Ben Briggs <[email protected]>
Date: Thu, 19 Oct 2023 12:34:49 +0100
Subject: [PATCH] add support for password length environment variable

---
 .../lambda_function.py                                       | 5 ++++-
 SecretsManagerMongoDBRotationMultiUser/lambda_function.py    | 4 +++-
 SecretsManagerMongoDBRotationSingleUser/lambda_function.py   | 4 +++-
 SecretsManagerRDSMariaDBRotationMultiUser/lambda_function.py | 4 +++-
 .../lambda_function.py                                       | 4 +++-
 SecretsManagerRDSMySQLRotationMultiUser/lambda_function.py   | 4 +++-
 SecretsManagerRDSMySQLRotationSingleUser/lambda_function.py  | 4 +++-
 SecretsManagerRDSOracleRotationMultiUser/lambda_function.py  | 4 +++-
 SecretsManagerRDSOracleRotationSingleUser/lambda_function.py | 4 +++-
 .../lambda_function.py                                       | 4 +++-
 .../lambda_function.py                                       | 4 +++-
 .../lambda_function.py                                       | 4 +++-
 .../lambda_function.py                                       | 4 +++-
 SecretsManagerRedshiftRotationMultiUser/lambda_function.py   | 4 +++-
 SecretsManagerRedshiftRotationSingleUser/lambda_function.py  | 4 +++-
 SecretsManagerRotationTemplate/lambda_function.py            | 4 +++-
 16 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/SecretsManagerActiveDirectoryRotationSingleUser/lambda_function.py b/SecretsManagerActiveDirectoryRotationSingleUser/lambda_function.py
index 5c2a54f..a7cec51 100644
--- a/SecretsManagerActiveDirectoryRotationSingleUser/lambda_function.py
+++ b/SecretsManagerActiveDirectoryRotationSingleUser/lambda_function.py
@@ -210,9 +210,12 @@ def create_secret(secrets_manager_client, arn, token, directory_name, current_di
         logger.info("createSecret: Successfully retrieved secret for %s." % arn)
     except secrets_manager_client.exceptions.ResourceNotFoundException:
         exclude_characters = os.environ.get("EXCLUDE_CHARACTERS", EXCLUDE_CHARACTERS)
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
         passwd = secrets_manager_client.get_random_password(
-            ExcludeCharacters=exclude_characters
+            ExcludeCharacters=exclude_characters,
+            PasswordLength=password_length
         )
         current_dict[DICT_KEY_PASSWORD] = passwd["RandomPassword"]
 
diff --git a/SecretsManagerMongoDBRotationMultiUser/lambda_function.py b/SecretsManagerMongoDBRotationMultiUser/lambda_function.py
index af83bb7..e2d537d 100644
--- a/SecretsManagerMongoDBRotationMultiUser/lambda_function.py
+++ b/SecretsManagerMongoDBRotationMultiUser/lambda_function.py
@@ -122,8 +122,10 @@ def create_secret(service_client, arn, token):
 
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerMongoDBRotationSingleUser/lambda_function.py b/SecretsManagerMongoDBRotationSingleUser/lambda_function.py
index d2c7d29..93a929b 100644
--- a/SecretsManagerMongoDBRotationSingleUser/lambda_function.py
+++ b/SecretsManagerMongoDBRotationSingleUser/lambda_function.py
@@ -116,8 +116,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSMariaDBRotationMultiUser/lambda_function.py b/SecretsManagerRDSMariaDBRotationMultiUser/lambda_function.py
index 5ba63cc..9c5325a 100644
--- a/SecretsManagerRDSMariaDBRotationMultiUser/lambda_function.py
+++ b/SecretsManagerRDSMariaDBRotationMultiUser/lambda_function.py
@@ -122,8 +122,10 @@ def create_secret(service_client, arn, token):
 
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSMariaDBRotationSingleUser/lambda_function.py b/SecretsManagerRDSMariaDBRotationSingleUser/lambda_function.py
index 53b4622..910976d 100644
--- a/SecretsManagerRDSMariaDBRotationSingleUser/lambda_function.py
+++ b/SecretsManagerRDSMariaDBRotationSingleUser/lambda_function.py
@@ -114,8 +114,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSMySQLRotationMultiUser/lambda_function.py b/SecretsManagerRDSMySQLRotationMultiUser/lambda_function.py
index 986e382..4cbbe33 100644
--- a/SecretsManagerRDSMySQLRotationMultiUser/lambda_function.py
+++ b/SecretsManagerRDSMySQLRotationMultiUser/lambda_function.py
@@ -122,8 +122,10 @@ def create_secret(service_client, arn, token):
 
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSMySQLRotationSingleUser/lambda_function.py b/SecretsManagerRDSMySQLRotationSingleUser/lambda_function.py
index 892f743..496c06c 100644
--- a/SecretsManagerRDSMySQLRotationSingleUser/lambda_function.py
+++ b/SecretsManagerRDSMySQLRotationSingleUser/lambda_function.py
@@ -114,8 +114,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSOracleRotationMultiUser/lambda_function.py b/SecretsManagerRDSOracleRotationMultiUser/lambda_function.py
index 90d3169..1b45f29 100644
--- a/SecretsManagerRDSOracleRotationMultiUser/lambda_function.py
+++ b/SecretsManagerRDSOracleRotationMultiUser/lambda_function.py
@@ -122,8 +122,10 @@ def create_secret(service_client, arn, token):
 
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 30
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=30)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSOracleRotationSingleUser/lambda_function.py b/SecretsManagerRDSOracleRotationSingleUser/lambda_function.py
index 42563df..ce4456d 100644
--- a/SecretsManagerRDSOracleRotationSingleUser/lambda_function.py
+++ b/SecretsManagerRDSOracleRotationSingleUser/lambda_function.py
@@ -114,8 +114,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 30
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=30)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSPostgreSQLRotationMultiUser/lambda_function.py b/SecretsManagerRDSPostgreSQLRotationMultiUser/lambda_function.py
index c40e25e..bb630b2 100644
--- a/SecretsManagerRDSPostgreSQLRotationMultiUser/lambda_function.py
+++ b/SecretsManagerRDSPostgreSQLRotationMultiUser/lambda_function.py
@@ -124,8 +124,10 @@ def create_secret(service_client, arn, token):
 
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else ':/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters,PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSPostgreSQLRotationSingleUser/lambda_function.py b/SecretsManagerRDSPostgreSQLRotationSingleUser/lambda_function.py
index 7451bac..9ecc330 100644
--- a/SecretsManagerRDSPostgreSQLRotationSingleUser/lambda_function.py
+++ b/SecretsManagerRDSPostgreSQLRotationSingleUser/lambda_function.py
@@ -116,8 +116,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else ':/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSSQLServerRotationMultiUser/lambda_function.py b/SecretsManagerRDSSQLServerRotationMultiUser/lambda_function.py
index d857198..47ba849 100644
--- a/SecretsManagerRDSSQLServerRotationMultiUser/lambda_function.py
+++ b/SecretsManagerRDSSQLServerRotationMultiUser/lambda_function.py
@@ -122,8 +122,10 @@ def create_secret(service_client, arn, token):
 
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRDSSQLServerRotationSingleUser/lambda_function.py b/SecretsManagerRDSSQLServerRotationSingleUser/lambda_function.py
index 2f827bc..39c4579 100644
--- a/SecretsManagerRDSSQLServerRotationSingleUser/lambda_function.py
+++ b/SecretsManagerRDSSQLServerRotationSingleUser/lambda_function.py
@@ -114,8 +114,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRedshiftRotationMultiUser/lambda_function.py b/SecretsManagerRedshiftRotationMultiUser/lambda_function.py
index 01ae0ef..0d61c92 100644
--- a/SecretsManagerRedshiftRotationMultiUser/lambda_function.py
+++ b/SecretsManagerRedshiftRotationMultiUser/lambda_function.py
@@ -121,8 +121,10 @@ def create_secret(service_client, arn, token):
 
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\:'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRedshiftRotationSingleUser/lambda_function.py b/SecretsManagerRedshiftRotationSingleUser/lambda_function.py
index 78ed403..5f7b6f3 100644
--- a/SecretsManagerRedshiftRotationSingleUser/lambda_function.py
+++ b/SecretsManagerRedshiftRotationSingleUser/lambda_function.py
@@ -115,8 +115,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\:'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
         current_dict['password'] = passwd['RandomPassword']
 
         # Put the secret
diff --git a/SecretsManagerRotationTemplate/lambda_function.py b/SecretsManagerRotationTemplate/lambda_function.py
index 82140a8..9d93964 100644
--- a/SecretsManagerRotationTemplate/lambda_function.py
+++ b/SecretsManagerRotationTemplate/lambda_function.py
@@ -96,8 +96,10 @@ def create_secret(service_client, arn, token):
     except service_client.exceptions.ResourceNotFoundException:
         # Get exclude characters from environment variable
         exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
+        # Get password length from environment variable
+        password_length = int(os.environ['PASSWORD_LENGTH']) if 'PASSWORD_LENGTH' in os.environ else 32
         # Generate a random password
-        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)
+        passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters, PasswordLength=password_length)
 
         # Put the secret
         service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=passwd['RandomPassword'], VersionStages=['AWSPENDING'])
-- 
2.41.0

ben-eb avatar Oct 19 '23 11:10 ben-eb

I investigated this from the CDK side. One blocker is see is that PasswordLength is not found here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-secretsmanager-rotationschedule-hostedrotationlambda.html.

msambol avatar Oct 19 '23 19:10 msambol