Giter Site home page Giter Site logo

aws-samples / aws-secrets-manager-rotation-lambdas Goto Github PK

View Code? Open in Web Editor NEW
309.0 22.0 279.0 198 KB

Contains Lambda functions to be used for automatic rotation of secrets stored in AWS Secrets Manager

License: MIT No Attribution

Python 100.00%
aws secretsmanager lambda-functions lambda aws-secrets-manager

aws-secrets-manager-rotation-lambdas's Introduction

aws-secrets-manager-rotation-lambdas's People

Contributors

adithyasolai avatar crus-umich avatar ecraw-amzn avatar huanjeff7 avatar jirkafajfr avatar joejesse avatar jpeddicord avatar kboxeth avatar lasred avatar madsid avatar mdavis-xyz avatar parimaldeshmukh avatar simonmarty avatar timjell avatar whygoyal avatar willtong1234 avatar wlewis4321 avatar yanwum avatar zebehringer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-secrets-manager-rotation-lambdas's Issues

functionName should not be required

Currently the Application requires passing of the functionName.
All Lambda Functions allow you to not provide that value as to avoid issues with character limits exceeding the 64 character limit.

Not passing errors as:

Parameters: [functionName] must have values

Postgres Multi User Rotation does not preserve grants

From: https://forums.aws.amazon.com/thread.jspa?threadID=322708

  1. We create an environment and apply a bunch of grants.
  2. A rotation occurs. This copies the grants over to the new user that's created.
  3. We continue to do dev work on the service, granting additional permissions on new tables.
  4. Another rotation occurs. Since the other user already exists, the lambda doesn't try to copy grants over (e.g. it follows the logic in the else here: https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas/blob/master/SecretsManagerRDSPostgreSQLRotationMultiUser/lambda_function.py#L194)
  5. At this point, the grants applied as part of #3 aren't there, and we get permission denied errors.

Secret manager rotation expects credential key names to be constant

Hey, in the SecretsManagerRDSMySQLRotationSingleUser/lambda_function.py we expect the field names to be:

 {
        'engine': <required: must be set to 'mysql'>,
        'host': <required: instance host name>,
        'username': <required: username>,
        'password': <required: password>,
        'dbname': <optional: database name>,
        'port': <optional: if not specified, default port 3306 will be used>
    }

In our case, we were using key names as 'rds.engine' etc for internal purposes.
I would expect the field names to be configurable/dynamic.
Can we look into this?
Thank you for your consideration!

Password rotation failed to due login issue RDS SQL Server Enterprise Edition when SSL is enforced

Hi folks!

I seem to have come across an issue with the RDS SQL Server rotation lambda. I'm specifically seeing this with "SecretsManagerRDSSQLServerRotationSingleUser".

Steps to reproduce:

  1. Deploy RDS DB Instance running SQL Server enterprise edition.
  2. Associate an RDS Parameter group with this DB instance with the parameter "rds.force_ssl" set to "1".
  3. Create a new secret in secrets manager and configure it to manage the rotation of the master user for the DB instance.

Errors:

  • Check the lambda logs in cloudwatch for the secret rotation lambda. There will be an error stating setSecret: Unable to log into database with previous, current, or pending secret of secret arn <secret arn>
  • I also slightly modified the lambda to log the error from SQL Server, and received this message: (20002, 'DB-Lib error message 20002, severity 9:\nAdaptive Server connection failed.

I've done some research, and it seems that the version of pymssql which this lambda uses (pymssql v2.1.1) is not packaged with a version of FreeTDS which supports SSL connections to SQL Server.

I've confirmed that this is my issue as I've tried disabling the rds.force_ssl paramater (i.e. setting the value to "0") which fixes this issue.

I found a related workaround here for "pymsql" (used in the RDS MySQL rotation lambda): https://aws.amazon.com/premiumsupport/knowledge-center/rotate-secret-db-ssl/ which mentions to update the connection to have an additional parameter ssl={'ca': './rds-combined-ca-bundle.pem'}, however I do not believe that this is a support parameter in pymssql.

The Microsoft SQL documentation mentions that the supported python SQL driver is pyodbc (you can see that here https://docs.microsoft.com/en-us/sql/connect/python/python-driver-for-sql-server?view=sql-server-ver15). I've tested pyodbc connections to RDS SQL Server and it works well with SSL enabled on the parameter group.

Is there any chance of this issue being resolved by either creating this lambda with a newer version of pymssql and packaging it with a version of FreeTDS which supports SSL or possibly refactoring to use pyodbc?

Thanks in advanced and let me know if you have any further questions!

Feature Request: Support MongoDB version 4.0

Hi,

According to the official document, MongoDB supports 3.2 or 3.4 for both Single User and Master User.
I would like to use MongoDB 4.0 to build DocumentDB,
So, it would be nice if the lambda to be rotated could also support version 4.0.

CloudFormation Outputs.ApplicationOutputName is not available

Using the AWS Serverless Application Repository with both the AWS Serverless Application Module and AWS CloudFormation seems to be missing the Outputs.ApplicationOutputName as specified in the Return values documentation.

I've include the AWS CloudFormation which I used.

  rDatabaseCredentialRotationApplication:
    Type: AWS::Serverless::Application
    Properties:
      Location:
        ApplicationId: 'arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSMySQLRotationSingleUser'
        SemanticVersion: 1.0.0
      Parameters:
        endpoint: !Sub 'https://secretsmanager.${AWS::Region}.amazonaws.com'

The generated nested stack is included below.


AWSTemplateFormatVersion: 2010-09-09
Parameters:
  endpoint:
    Type: String
    Description: The Secrets Manager endpoint to hit
Resources:
  SecretsManagerRDSMySQLRotationSingleUser:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        S3Bucket: awsserverlessrepo-changesets-CHANGESET-ID-HERE
        S3Key: KEY-HERE
      Description: >-
        Conducts an AWS SecretsManager secret rotation for RDS MySQL using
        single user rotation scheme
      Tags:
        - Value: SAM
          Key: 'lambda:createdBy'
      Environment:
        Variables:
          SECRETS_MANAGER_ENDPOINT: !Ref endpoint
          AWS_DATA_PATH: models
      Handler: lambda_function.lambda_handler
      Role: !GetAtt 
        - SecretsManagerRDSMySQLRotationSingleUserRole
        - Arn
      Timeout: 30
      Runtime: python2.7
  SecretsManagerRDSMySQLRotationSingleUserRole:
    Type: 'AWS::IAM::Role'
    Properties:
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      Policies:
        - PolicyName: SecretsManagerRDSMySQLRotationSingleUserRolePolicy0
          PolicyDocument:
            Statement:
              - Action:
                  - 'ec2:CreateNetworkInterface'
                  - 'ec2:DeleteNetworkInterface'
                  - 'ec2:DescribeNetworkInterfaces'
                  - 'ec2:DetachNetworkInterface'
                Resource: !Sub >-
                  arn:${AWS::Partition}:ec2:${AWS::Region}:${AWS::AccountId}:network-interface/*
                Effect: Allow
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com

An error occurred (AccessDeniedException) when calling the GetSecretValue operation: Access to KMS is not allowed

Hey, I'm trying to execute the lambda function, but it shows me an error.

ClientError: An error occurred (AccessDeniedException) when calling the GetSecretValue operation: Access to KMS is not allowed

FIle "/../lambda_function.py"
secret = service_client.get_secret_value(SecretId=arn, VersionStage=stage)

https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas/blob/master/SecretsManagerRDSPostgreSQLRotationMultiUser/lambda_function.py#L337

I already applied for these permissions

   "kms:Encrypt",
   "kms:Decrypt",
   "kms:ReEncrypt*",
    "kms:GenerateDataKey"

thanks in advance

SingleUser Rotation with Master Secret

Currently the code (for example SecretsManagerRDSPostgreSQLRotationSingleUser) uses the existing password (in the secret) to authenticate/login and then rotates it (as the documentation explains).
Probably a minor improvement, but does it make sense to use the master secret (if exists in the secret) to rotate the secret? In other words, the function checks the secret and if there's a masterarn, it uses it to authenticate/login (similar to multi-user flow) and rotates the secret in single-user mode.
One benefit is that the current password doesn't need to be correct. This makes the whole flow in using CDK a little smoother; creating the RDS instance and its additional credentials.

ORACLE MultiUser doesn't support if the password originally contains @ symbol

As we have:
conn = cx_Oracle.connect(secret_dict['username'] + '/' + secret_dict['password'] + '@' + secret_dict['host'] + ':' + port + '/' + `secret_dict['dbname'])

The connection string would be like username/password@host:port/SID

If at the beginning the original password contains @ symbol (say if it's pwd@123), it will never connect to database. Because the connection string becomes: username/pwd@123@host:port/SID, and the host is recognized as 123@host instead of host.

A simple change could avoid this behavior, to use below code:
conn = cx_Oracle.connect(secret_dict['username'], secret_dict['password'], secret_dict['host'] + ':' + port + '/' + secret_dict['dbname'])

Reference:
https://cx-oracle.readthedocs.io/en/latest/api_manual/module.html#
https://cx-oracle.readthedocs.io/en/latest/user_guide/connection_handling.html#connstr

Help with this error - Runtime.UserCodeSyntaxError: Syntax error in module 'lambda_function': invalid syntax

So did the following to prepare the depedency package
pip install --target ./package pg
pip install --target ./package pgdb
cd package
zip -r ../deployment.zip .

[ERROR] Runtime.UserCodeSyntaxError: Syntax error in module 'lambda_function': invalid syntax (init.py, line 3)
Traceback (most recent call last):
  File "/var/task/pg/init.py" Line 3
        async,

Tried with python 3.6, 3.7 & 3.8; no luck; googling does not seem to help much either...

SQL Injection Vulnerability

Improper SQL query building is present in the several of the password rotation functions. For example, SecretsManagerRDSPostgreSQLRotationSingleUser:

alter_role = "ALTER USER \"%s\"" % pending_dict['username']
cur.execute(alter_role + " WITH PASSWORD %s", (pending_dict['password'],))

pending_dict['username'] should be escaped as an identifier, unfortunately PyGreSQL does not expose this function easily.

pg module not compatible with the latest version of python (python 3.8)

Compiler
Python3.8

Error from cloudwatch

[ERROR] Runtime.UserCodeSyntaxError: Syntax error in module 'lambda_function': invalid syntax (init.py, line 3)
Traceback (most recent call last):
File "/var/task/pg/init.py" Line 3
async,

Reason for error

Async a reserved word from python 3.7
https://docs.python.org/3/whatsnew/3.7.html

This is a very old package - should be replace with something newer which is compatible latest python version.
https://pypi.org/project/pg/#history

Even winding back to python 3.6 results in additional errors (_imaging module).

Would be nice to be able to change the Runtime for the rotation function

Here is the yaml configuration for deploying the AWS::Serverless::Application

  RDSSecretRotationService:
    Type: "AWS::Serverless::Application"
    Properties:
      Location:
        ApplicationId: arn:aws:serverlessrepo:region:id:applications/SecretsManagerRDSPostgreSQLRotationSingleUser
        SemanticVersion: 1.0.117
      Parameters:
        endpoint: !Sub "https://secretsmanager.${AWS::Region}.${AWS::URLSuffix}"
        functionName:
          Fn::Join:
            - ""
            - - Fn::ImportValue: !Sub ${ClusterImportPrefix}-ClusterResolvingName
              - "-rds-rotation-lambda"
        vpcSubnetIds:
          Fn::ImportValue: !Sub ${VPCImportPrefix}-PrivateSubnets
        vpcSecurityGroupIds: !Ref RDSSecurityGroup

where can the documentation for the parameter list supported by this AWS resource (AWS::serverless::application)

I tried to add both

        Runtime: "python3.7"
        runtime: "python3.7"

failed to do so

ORACLE MultiUser doesn't support if the GET_GRANTED_DDL contains multiple sqls instead of one

As we have https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas/blob/master/SecretsManagerRDSOracleRotationMultiUser/lambda_function.py#L196,

    for grant_type in ['ROLE_GRANT', 'SYSTEM_GRANT', 'OBJECT_GRANT']:
        try:
            cur.execute("SELECT DBMS_METADATA.GET_GRANTED_DDL('%s', '%s') FROM DUAL" % (grant_type, current_dict['username'].upper()))
            results = cur.fetchall()
            for row in results:
                sql = row[0].read().strip(' \n\t').replace("\"%s\"" % current_dict['username'].upper(), "\"%s\"" % pending_dict['username'])
                cur.execute(sql)
        except cx_Oracle.DatabaseError:
            # If we were unable to find any grants skip this type
            pass

Basically this code is to check which privileges the current user has, and then grant them to the pending user. However if the row[0].read returns multiple sqls, it will never commit successfully because cx_Oracle can be used to execute individual statements, one at a time.

In our test situation, DUMMY_USER contains multiple privileges and the sql of SYSTEM_GRANT would become:
GRANT "CONNECT" TO "DUMMY_USER_CLONE"
GRANT "RESOURCE" TO "DUMMY_USER_CLONE"
Then the cur.execute(sql) would raise exception of (We have added a traceback for debugging propose):
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 204, in set_secret
cur.execute(sql)
cx_Oracle.DatabaseError: ORA-00933: SQL command not properly ended

So I suggest to do below modification to make it compatible for above situation.

    for grant_type in ['ROLE_GRANT', 'SYSTEM_GRANT', 'OBJECT_GRANT']:
        try:
            cur.execute("SELECT DBMS_METADATA.GET_GRANTED_DDL('%s', '%s') FROM DUAL" % (grant_type, current_dict['username'].upper()))
            results = cur.fetchall()
            for row in results:
                sqls = row[0].read().strip(' \n\t').replace("\"%s\"" % current_dict['username'].upper(), "\"%s\"" % pending_dict['username'])
                for sql in sqls.split('\n'):
                    cur.execute(sql)
        except cx_Oracle.DatabaseError:
            # If we were unable to find any grants skip this type
            pass

Rotate Secret With Reader Endpoint

Hello.

We are planning to have Postgres roles that have the reader endpoint in the secret host attribute to enforce use of the Aurora reader endpoint without the application having to worry about changing endpoint URL's. Am I right in thinking that rotation will fail due to the reader endpoint being passed to the rotation Lambda?

If so, what is the solution? Customize the Lambda? Change our approach?

Thanks.

Oracle Issue with ORA-28221: REPLACE not specified

I try to use this script but i found the error ORA-28221: REPLACE not specified because i apply oracle user policy and it requires REPLACE syntax
(example: alter user username identified by new password REPLACE old password )

so how to edit the script to support REPLACE in line 216 : "cur.execute("ALTER USER %s IDENTIFIED BY "%s"" % (escaped_username, pending_password))"

i am not the master of programing so please advise

Positional argument - SecretsManagerRDSMySQLRotationSingleUser

Hi, I have had the following error takes 1 positional argument but 2 positional arguments (and 5 keyword-only arguments) were given

I have addressed the issue by adding host as a keyword argument to connection string on line 269.

Function: get_connection
Line: 269
Fix: conn = pymysql.connect(host=secret_dict['host'], user=secret_dict['username'], passwd=secret_dict['password'], port=port, db=dbname, connect_timeout=5)

@PJ64

Parameters: [vpcSecurityGroupIds, functionName, vpcSubnetIds] do not exist in the template when using CloudFormation

When using AWS CloudFormation with the AWS Serverless Application Module and the AWS Serverless Application Repository, the paramter functionname is not recognized. However, it's listed in the docs for To create a Lambda rotation function by using an AWS Serverless Application Repository template

endpoint – The URL of the service endpoint that you want the rotation function to query. Typically, this is https://secretsmanager.region.amazonaws.com.

functionname – The name of the completed Lambda rotation function that's created by this process.

AWS CloudFormation template is included below.

  rDatabaseCredentialRotationApplication:
    Type: AWS::Serverless::Application
    Properties:
      Location:
        #https://docs.aws.amazon.com/secretsmanager/latest/userguide/reference_available-rotation-templates.html
        ApplicationId: 'arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSMySQLRotationSingleUser'
        SemanticVersion: 1.0.0
      Parameters:
        endpoint: !Sub 'https://secretsmanager.${AWS::Region}.amazonaws.com'
        functionname: 'test-function-name'

Mismatching tokens

Hi,

I'm trying to setup secretsmanager rotation and found these lambda function examples here... but can't get these to work.
It seems like the tokens received by Lambda (event) don't match the tokens/VersionStages fetched when calling seceretsmanager API (describe_secret), so the function fails raising an exception.

Please see the Lambda output below:

START RequestId: 869a3608-f930-43dd-9337-b71edc57f134 Version: $LATEST

EVENT_DATA: {'ClientRequestToken': 'AF585B8F-AA06-4EAB-8827-EFF43E6FD896', 'SecretId': 'arn:aws:secretsmanager:eu-west-1:passwd-WqYjGj', 'Step': 'createSecret'}

DESC_SECRET {'ARN': 'arn:aws:secretsmanager:eu-west-1:passwd-WqYjGj', 'Name': 'passwd', 'KmsKeyId': '41b10ffe-b86d-412f-8bb5-d63ba990e585', 'RotationEnabled': True, 'RotationLambdaARN': 'arn:aws:lambda:eu-west-1:XXX:function:rotate-secrets', 'RotationRules': {'AutomaticallyAfterDays': 90}, 'LastChangedDate': datetime.datetime(2019, 8, 5, 16, 18, 40, 344000, tzinfo=tzlocal()), 'Tags': [{'Key': 'Environment', 'Value': 'uat'}, {'Key': 'Owner', 'Value': 'terraformer'}, {'Key': 'Terraform', 'Value': 'true'}], 'VersionIdsToStages': {'AF585B8F-AA06-4EAB-8827-EFF43E6FD896': ['AWSPENDING']}, 'ResponseMetadata': {'RequestId': '75613522-63e9-42c3-999c-ba1d728f08e8', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Mon, 05 Aug 2019 16:18:41 GMT', 'content-type': 'application/x-amz-json-1.1', 'content-length': '583', 'connection': 'keep-alive', 'x-amzn-requestid': '75613522-63e9-42c3-999c-ba1d728f08e8'}, 'RetryAttempts': 0}}

[ERROR] ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the GetSecretValue operation: Secrets Manager can’t find the specified secret value for staging label: AWSCURRENT

Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 61, in lambda_handler
    create_secret(service_client, arn, token)
  File "/var/task/lambda_function.py", line 88, in create_secret
    service_client.get_secret_value(SecretId=arn, VersionStage="AWSCURRENT")
  File "/var/runtime/botocore/client.py", line 320, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 623, in _make_api_call
    raise error_class(parsed_response, operation_name)

END RequestId: 869a3608-f930-43dd-9337-b71edc57f134

REPORT RequestId: 869a3608-f930-43dd-9337-b71edc57f134	Duration: 1039.40 ms	Billed Duration: 1100 ms Memory Size: 128 MB	Max Memory Used: 71 MB	

Can you please advise on how to solve that issue ?

Discussion - MultiUser Rotation lambda to rotate secrets only

MultiUser templates are creating cloned users and replicating grants.

Although this is convenient, we have to maintain the different grant methods in the different db engines templates with fair amount of complexity. When complexity deepens, we introduce risks of points of failures.

Since the <db_user> needs to be pre-created with the necessary grants, why not <db_user>_clone?

kinit_command

I get this error while executing the lambda for SecretsManagerActiveDirectoryRotationSingleUser

Please suggest


2022-08-01T16:19:08.536+05:30Copy[ERROR] ValueError: execute_kinit_command: kinit failedTraceback (most recent call last):  File "/var/task/lambda_function.py", line 136, in lambda_handler    create_secret(secrets_manager_client, arn, token, directory_name, current_dict)  File "/var/task/lambda_function.py", line 202, in create_secret    execute_kinit_command(current_dict, None, directory_name)  File "/var/task/lambda_function.py", line 446, in execute_kinit_command    raise ValueError("execute_kinit_command: kinit failed") from Exception [ERROR] ValueError: execute_kinit_command: kinit failed Traceback (most recent call last):   File "/var/task/lambda_function.py", line 136, in lambda_handler     create_secret(secrets_manager_client, arn, token, directory_name, current_dict)   File "/var/task/lambda_function.py", line 202, in create_secret     execute_kinit_command(current_dict, None, directory_name)   File "/var/task/lambda_function.py", line 446, in execute_kinit_command     raise ValueError("execute_kinit_command: kinit failed") from Exception

RotationMultiUser doesn't set host and engine from masterSecret

I added password rotation to my database using https://github.com/time-loop/cdk-aurora/blob/main/src/aurora.ts#L284

However, it didn't

Also, what is with the master stuff? BLM happened years ago. adminSecret or administratorSecret if you want to do Microsofty things. Or mainSecret if you want to follow GitHub's pattern. Or primarySecret, or controlSecret. It takes almost no effort at all to not be crass.

Syntax error in module 'lambda_function

{
"errorMessage": "Syntax error in module 'lambda_function': invalid syntax (init.py, line 3)",
"errorType": "Runtime.UserCodeSyntaxError",
"stackTrace": [
" File "/var/task/pg/init.py" Line 3\n async,\n"
]
}

Rotation lambda function in JS: facing error- Invalid or unexpected token

Hi all,
I am using the below code in node JS to rotate the secret but i am facing an error. I am mentioning the code and the error below.I am not using client request token assuming it's an optional parameter. Please let me know where i am going wrong.

Code:

// Ensure you have installed these two packages
const AWS = require('aws-sdk');

const ServiceURL = "https://vpce-0ee-s82syo9o.secretsmanager.us-east-1.vpce.amazonaws.com/";
const endpoint = ServiceURL;
const region = "us-east-1";
const secretName = "1033-Rotation-Lambda";
const rotationInterval = 30;
const rotationLambdaARN = "arn:aws:lambda:us-east-36390381:function:1033_PasswordRotation";

const secretsManager = new AWS.SecretsManager({
endpoint: endpoint,
region: region,
});

const params = {
SecretId: secretName,
RotationLamdaARN: rotationLambdaARN,
RotationRules: {
AutomaticallyAfterDays: rotationInterval,
},
};

exports.handler = async (event, context) => {
try {
const response = await secretsManager.rotateSecret(params).promise();
console.log(${secretName} secret rotation complete);
console.log(response);
} catch (error) {
console.error(An error occurred while attempting to rotate ${secretName} secret);
console.log(error);
}
};

// SAMPLE ENVIRONMENT/CONFIG FILES- Use what fits your current app setup

/**

  • Sample config folder
  • this assumes you're using ES5
    */
    // config/default.js
    // REPLACE THE FOLLOWING WITH THE CORRECT VALUES!
    module.exports = {
    AWS: {
    endpoint: 'https://vpce-0ee-s82syo9o.secretsmanager.us-east-1.vpce.amazonaws.com/',
    region: 'us-east-1',
    secretName: '1033-Rotation-Lambda',
    clientToken: 'token',
    rotation: {
    interval: 30,
    lambdaARN: 'arn:aws:lambda:us-east-36390381:function:1033_PasswordRotation'
    }
    },
    };

/**

  • If you're reading values from the .env file
    */
    const {
    AWS_ENDPOINT,
    AWS_REGION,
    AWS_SECRET_NAME,
    AWS_CLIENT_TOKEN,
    AWS_SECRET_ROTATION_INTERVAL,
    } = process.env;

Error:

Response:
{
"errorType": "Runtime.UserCodeSyntaxError",
"errorMessage": "SyntaxError: Invalid or unexpected token",
"trace": [
"Runtime.UserCodeSyntaxError: SyntaxError: Invalid or unexpected token",
" at _loadUserApp (/var/runtime/UserFunction.js:98:13)",
" at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)",
" at Object. (/var/runtime/index.js:45:30)",
" at Module._compile (internal/modules/cjs/loader.js:778:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)",
" at Module.load (internal/modules/cjs/loader.js:653:32)",
" at tryModuleLoad (internal/modules/cjs/loader.js:593:12)",
" at Function.Module._load (internal/modules/cjs/loader.js:585:3)",
" at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)",
" at startup (internal/bootstrap/node.js:283:19)"
]
}

Request ID:
"6705fb8f-b909-4381-b8c3-cfbffa6f7d18"

Function Logs:
START RequestId: 6705fb8f-b909-4381-b8c3-cfbffa6f7d18 Version: $LATEST
2019-11-11T10:17:04.575Z undefined ERROR Uncaught Exception {"errorType":"Runtime.UserCodeSyntaxError","errorMessage":"SyntaxError: Invalid or unexpected token","stack":["Runtime.UserCodeSyntaxError: SyntaxError: Invalid or unexpected token"," at _loadUserApp (/var/runtime/UserFunction.js:98:13)"," at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)"," at Object. (/var/runtime/index.js:45:30)"," at Module._compile (internal/modules/cjs/loader.js:778:30)"," at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)"," at Module.load (internal/modules/cjs/loader.js:653:32)"," at tryModuleLoad (internal/modules/cjs/loader.js:593:12)"," at Function.Module._load (internal/modules/cjs/loader.js:585:3)"," at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)"," at startup (internal/bootstrap/node.js:283:19)"]}
END RequestId: 6705fb8f-b909-4381-b8c3-cfbffa6f7d18
REPORT RequestId: 6705fb8f-b909-4381-b8c3-cfbffa6f7d18 Duration: 1903.34 ms Billed Duration: 2000 ms Memory Size: 128 MB Max Memory Used: 24 MB
Unknown application error occurred
Runtime.UserCodeSyntaxError

Improved support for KMS-CMKs

I ran into a problem deploying this using KMS-CMKs using a single pass because I can't create the IAM Role first so the CMK policy can include its ARN for access. This can, of course, be solved by changing the CMK policy after the fact but that is non-trivial to implement in common tools like CloudFormation or Terraform.

It seems like this could most easily be implemented by allowing an IAM role to be provided as an input so the CMK key policy could be configured first and then all of the same IAM policies could be attached by this stack.

Clarify import of pg database

Hi,

I tried deploying these manually myself and was unable to import "_pg" inside my lambda environment. It appears related to the issue at https://github.com/jkehler/awslambda-psycopg2 where

This is a custom compiled psycopg2 C library for Python. Due to AWS Lambda missing the required PostgreSQL libraries in the AMI image, we needed to compile psycopg2 with the PostgreSQL libpq.so library statically linked libpq library instead of the default dynamic link.

Can the github repository clarify if this is correct and how to build and deploy this code?

Creation of AWS-secret-manager-rotation-lambda in .net

Hi everyone,
Can anyone please point me to a document or link where i can find a generic template or code to build solution to rotate secret from lambda function in .net language. i have seen the available one is in python but i am not sure how to begin in .net.
Please provide me your guidance as i am new to both AWS lambdas and secret manager.

Thank you.

Role Ownership Issues in the RDS PostgreSQL Multi-User Rotation Lambda

Hello,

My team has been working to implement our slightly custom RDS password rotation lambda based on the multi user lambda here:
https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas/blob/master/SecretsManagerRDSPostgreSQLRotationMultiUser/lambda_function.py

We are granting the master user role permissions to our secondary users, and also in between the users (as is done in this repo) and have run into several issues around object ownership (completely breaking) when actually using them with several micro-services.

As I understand this function, it is expecting the multi-user role permissions to look something like this:

master {perms to create objects}
user1 {}
user2 {member of user1}

I think that there is a major flaw in the rotation function as it is setup now. And the issue goes like this:

Assuming user2 is a member of the user1 Role:

  1. The service is connecting with user2
  2. User2 is used to create a new schema, table, or any object.
  3. That new table is now owned by the user2 role
  4. When the secrets rotate and the service connects with user1, it cannot access the object created by user2. It has permission denied errors because that Table/object is owned solely by user2
  5. Service is now in a breaking state because of the password rotation

We've implemented several fixes around this where we reassign ownership during rotation back to the master user so it can be accessed by both user1 and user2 since they are members of the master role. (I can make a PR to this repo if this is indeed an issue), but this case seems so simple that I'm surprised no-one else is running into issues and wanted to confirm here as well.

Can someone confirm that this is an issue? It basically makes the rotation function unusable as is without heavy customization and/or custom SQL event triggers to reassign ownership. Is there an easy way to fix this, or something that we're missing?

hosted functions use insecure python `cryptography` library

When setting up rotations via the hosted function like below:

from aws_cdk import core, aws_ec2 as ec2
from aws_cdk.aws_rds import DatabaseCluster, DatabaseClusterEngine, InstanceProps, AuroraEngineVersion
from aws_cdk.core import Duration


class Tmp2Stack(core.Stack):
    def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        vpc = ec2.Vpc(self, "VPC")

        db = DatabaseCluster(
            self,
            "Database",
            engine=DatabaseClusterEngine.aurora(version=AuroraEngineVersion.VER_1_22_2),
            instance_props=InstanceProps(vpc=vpc),
        )
        db.add_rotation_single_user(automatically_after=Duration.days(7))

Then the python 3.7 lambdas are insecure using 2017 version of python cryptography

image

image

Output function role ARN

It would be great if the Cloudformation templates for these functions would output the ARN of the role that was created for inclusion in resource policies on the secrets.

Right now the best option I've found is to check userid ~= "*:[rotator function name]" as in

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "secretsmanager:UpdateSecretVersionStage",
        "secretsmanager:PutSecretValue",
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotLike": {
          "aws:userid": [
            "AROASECRETADMINROLE:*",
            "*:name-of-rotator-function"
          ]
        }
      }
    }
  ]
}

Which, for all the protection that provides I just might as well not have a secret policy.

Python 2.7 EOL January 1, 2020

It looks like Python 2.7 is going to stop being supported as of January 1, 2020 based on the information found here:
https://devguide.python.org/#status-of-python-branches

I'm assuming that a lambda runtime environment deprecation will follow soon after.

Last I remember trying to run the RDS single user rotation for PostgreSQL in a Python 3 lambda runtime, it was not compatible. Is there a plan to upgrade these to be Python 3 compatible?

set_secret user check logic

I'm running into an error here:

https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas/blob/master/SecretsManagerRDSMySQLRotationMultiUser/lambda_function.py#L165-L168

The conditional doesn't seem to match the error message. Is it supposed to be only validating that the pending username contains the 'clone' suffix?

The message says:

Attempting to modify user %s other than current user or clone %s

But the conditional says:

get_alt_username(current_dict['username']) != pending_dict['username']

I would expect something more like:

if pending_dict['username'] not in [get_alt_username(current_dict['username']), current_dict['username']]

MySql MultiUser RDS credential rotation causes problematic permission grants

Commit edd300a ("Supports MySQL/Maria grants containing percent symbols.") added a replacement of '%' with '%%' because '%' is an escape character for python format strings. I don't know if something changed in the libraries used or if this is only necessary in certain situations, but it causes problems with the permission grants in the simplest case. This is the specific line that appears to be the problem:
new_grant_escaped = new_grant.replace('%','%%') # % is a special character in Python format strings.

We are using this in a lambda with Python 3.7.
We started with a user 'myuser', with a grant:
GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE, SHOW VIEW ON %.* TO 'myuser'@'%'

Each time the key rotation is run, we end up with a grant doubling the wildcard as the grant gets copied back and forth between the base account and the clone account. EG:
GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE, SHOW VIEW ON %%.* TO 'myuser_clone'@'%'

After several automatic rotations, we're up to 64 on the main account and 128 on the clone:
GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE, SHOW VIEW ON %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.* TO 'myuser'@'%'
GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, EXECUTE, SHOW VIEW ON %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.* TO 'myuser_clone'@'%'

I expect at some point we'll run up against a character limit and rotation will fail.

I can change the lambda locally, but if we ever take a further update from the template, that might get lost. Additionally, I expect other customers are likely to run into this problem if they restrict permissions in this way.

As a workaround, I can grant the privileges separately to each schema in the DB, but that's a little bit painful and error prone if we ever add an additional schema.

SecretsManagerRDSMySQLRotationSingleUser application doesn't output role resource in aws serverlessrepo get-application output

I tried using SecretsManagerRDSMySQLRotationSingleUser application to create a lambda function in the AWS console but it looks like this application tries to create a role SecretsManagerRDSMySQLRotationSingleUserRole internally. My company doesn't allow role creation like this. I would like to use this application (to make use of standard rotation code and bundled pymysql etc) but would like to provide my custom role manually.

I did the following command and it only outputs SecretsManagerRDSMySQLRotationSingleUser resource and not the SecretsManagerRDSMySQLRotationSingleUserRole. Also, I don't see any role param for SecretsManagerRDSMySQLRotationSingleUser resource where I can plug-in my custom role.

aws serverlessrepo get-application --application-id arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSMySQLRotationSingleUser

I will really appreciate any input on this.

Feature Request: Add PermissionsBoundary as option for role that gets created

For SAM functions, you are able to specify a Permissions Boundary to use for the role that gets created automatically by Serverless::Function resources. However, there is no way for us as a consumer of these Serverless Applications to specify that to you.

Could you please add an optional parameter to the Serverless Application that allows us to specify a PermissionsBoundary?

If your App is passed PermissionsBoundary as a parameter by a user, simply pass it down to the Serverless::Function it creates. This should only be a few line change to your template.

We (and others likely) cannot take advantage of your Serverless Apps due being required (by a standard/policy within our organizations) to always specify a PermissionsBoundary on any role we create (or is created for us by things like SAM).

Clarification the Python Runtime version these lambdas should use

Could you please clarify the Python Runtime version these lambdas should use. I notice that SecretsManagerRDSPostgreSQLRotationSingleUser — version 1.0.117 is used in the AWS Serverless Application Repository. The template in the repository contains Runtime: python2.7. Can SecretsManagerRDSPostgreSQLRotationSingleUser be safely used with Runtime: python3.7?

Add IAM role in Outputs when using Serverless Application

Hello,

Multi user strategies require access to a master secret.

When deploying the strategy with the AWS Serverless Repository the only way I see to allow this is to add in my CF template a resource policy on the master secret allowing the role created by the Serverless Application to call GetSecretValue. Since this role is not outputed, I cannot find a way to achieve this.

Code for 2-user secret rotation for Redshift does not match Boto3 documentation.

Line 357 of SecretsManagerRedshiftRotationMultiUser/lambda_function.py says:

secret = service_client.get_secret_value(SecretId=arn, VersionId=token, VersionStage=stage)

Note that both VersionId and VersionStage are specified.

Boto3 documentation for get_secret_value() says you don't specify both.

What are the semantics when you do specify both?

Why does the provided code disregard the documentation?

VersionId (string) --
Specifies the unique identifier of the version of the secret that you want to retrieve. If you specify this parameter then don't specify VersionStage . If you don't specify either a VersionStage or VersionId then the default is to perform the operation on the version with the VersionStage value of AWSCURRENT .

This value is typically a UUID-type value with 32 hexadecimal digits.

VersionStage (string) --
Specifies the secret version that you want to retrieve by the staging label attached to the version.

Staging labels are used to keep track of different versions during the rotation process. If you use this parameter then don't specify VersionId . If you don't specify either a VersionStage or VersionId , then the default is to perform the operation on the version with the VersionStage value of AWSCURRENT .

Password length

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.