banner

KuchBhiLearning - A free website to learn and code

This is a good learning site. This contains details of cloud computing, AWS, AWS-CDK, AWS-SDK codes and examples including S3, Redis, lambda, api-gateway, cloudfront, cloudformation.

Getting secrets from Secret Manager using AWS-SDK


What is AWS Secret Manager?

AWS Secret Manager is nothing but a locker where you can keep all secret values like Api keys, secret key or client key or DB Credentials.


Why is Secret Manager important?

Sometimes it's easy to manage environment specific secret values in server side code. Because there is different server. But we can lose those values if we don't keep them in code and another side of the mirror is not recommended to keep those values in code or repository which can lead to multiple code changes if the value changes.
If any non authorized person gets access to repo then these credentials are exposed.

Benefits of Secret Manager?

  • Easily replicate secrets to multiple regions.
  • Secure as this secrets will not be accessed by users with view only permission.
  • Pay as you go.
Here we are using AWS-SDK(Client side SDK) for our implementation.

Create SecretManager.ts file

export class SecretsManager {
  /**
   * This method returns all the values for the specific id.
   * @param secretId Secret id of the secret manager
   * @returns All the key value pair json for the specific secret id.
   */
  static async getSecret(secretId: string): Promise<any> {
    // Visit the AWS docs for more information:
    // https://aws.amazon.com/developers/getting-started/nodejs/
    // https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html

    // Load the AWS SDK
    const AWS = require('aws-sdk');

    let secret: any;
    let decodedBinarySecret: string;

    // Create a Secrets Manager client
    const client = new AWS.SecretsManager({
      region: 'us-east-1',
    });

   
    return new Promise<any>((resolve, reject): void => {
      client.getSecretValue({ SecretId: secretId }, (err: any, data: any): any => {
        if (err) {
          if (err.code === 'DecryptionFailureException') {
            // Secrets Manager can't decrypt the protected secret text using the provided KMS key.
            // Deal with the exception here, and/or rethrow at your discretion.

            reject('error');
          } else if (err.code === 'InternalServiceErrorException') {
            // An error occurred on the server side.
            // Deal with the exception here, and/or rethrow at your discretion.
            reject('error');
          } else if (err.code === 'InvalidParameterException') {
            // You provided an invalid value for a parameter.
            // Deal with the exception here, and/or rethrow at your discretion.
            reject('error');
          } else if (err.code === 'InvalidRequestException') {
            // You provided a parameter value that is not valid for the current state of the resource.
            // Deal with the exception here, and/or rethrow at your discretion.
            reject('error');
          } else if (err.code === 'ResourceNotFoundException') {
            // We can't find the resource that you asked for.
            // Deal with the exception here, and/or rethrow at your discretion.
            reject('error');
          }
          reject('error');
        } else {
          // Decrypts secret using the associated KMS CMK.
          // Depending on whether the secret is a string or binary, one of these fields will be populated.

          if ('SecretString' in data) {
            secret = data.SecretString;
          } else {
            const buff = new Buffer(data.SecretBinary, 'base64');
            decodedBinarySecret = buff.toString('ascii');
          }
        }

        if (!secret) {
          return reject();
        }
        return resolve(JSON.parse(secret));
      });
    });
  }
}


Create new handler which calls this method

import { SecretsManager } from '../../common/helpers/secret-manager';

exports.handler = async function (event: any) {
  try {
    const secrets = await SecretsManager.getSecret('blog/test');
    return {
      statusCode: 200,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ Message: `Fetched secretmanager details!\n` }),
    };
  } catch (error) {
    console.log(`The following error occured in hello handler : ${error} `);
    return error;
  }
};


Creating Secrets Manager values in AWS Console

Navigate to Secret manager


Click on Store New Secret.



Select the Other Type of secrets(Because we are not storing credentials of database)



Provide an example Key Value pair. We can still add new values after this creation.



Other properties are optional so we will skip it for now.

In this example we are storing private Client ID and Secret key provided by the client. So we will not enable the rotation.

So click on Next and review the changes.



Click on Store. 

We should be able to see the newly created secrets in secret manager.

If we select and move inside secret manager



We have an option of edit and we can add new properties or update properties here. 

If you are looking for attaching secret manager role to lambda, check here

1 comment:

If you have any doubts, Please let me know

Copyright 2022, KuchBhiLearning - A free website to learn and code. All rights Reserved.
| Designed by Yaseen Shariff