© Miguel A. Calles 2020
M. A. CallesServerless Securityhttps://doi.org/10.1007/978-1-4842-6100-2_8

8. Secrets Management

Miguel A. Calles1 
(1)
La Habra, CA, USA
 

In this chapter, we will discuss how you might protect our secrets using provider services. We will explore the various ways AWS will enable us to encrypt secrets. Based on this exploration, we will select an approach that has a balance between encryption and convenience, and explore that approach in Azure and Google Cloud.

The provider allows us to encrypt your secrets in multiple ways. We will explore the various ways AWS will enable us to encrypt secrets. Based on this exploration, we will select an approach that has a balance between encryption and convenience, and explore that approach in Azure and Google Cloud.

The Importance of Secrets Management

Serverless functions may need to interface with external services, which may require a username and password, an API key, or a secret key to verify the account and validate the session. For example, your application may need to process credit card transactions, and the payment processor API might require an API key unique to your account to accept API requests. If someone obtains access to this API key, that individual might start processing unauthorized credit card transactions. These illegal transactions could result in financial loss, customer complaints, or other actions degrading the business brand. Therefore, we must take extra measures to protect secrets, like an API key, to reduce risk.

Protecting Secrets

We want to avoid accidentally disclosing secrets to help prevent scenarios like those previously discussed. We should take as many measures as possible, and as practical, to protect our secrets. We should have a business process for protecting secrets and a secure software process in our application.

The business process might be the responsibility of the Information Technology, Information Security, or Cybersecurity departments or the application team if the organization is small. Whoever is responsible, having a process in place, is essential and need not be elaborate. It might be as simple as using a password manager to store all secrets and limiting who has access to it. Some organizations might store a physical sheet of paper containing the passwords in a safe, and the knowledge of the safe’s code is limited. Both situations, in essence, have the same process in different mediums, digital vs. physical. Whatever process our business adopts, we need to use it consistently and periodically reassess it.

The secure software process is likely a shared responsibility between the software development team and the team responsible for the business process. It is a shared responsibility because the software developers need to develop software that securely uses the secrets, and the business process team might be involved in establishing the process and auditing it. We will discuss the general principles for how you might develop your secure software process for protecting secrets and how you might implement them for each provider.

General Principles

As a general rule, the source code should not contain any secrets (i.e., usernames, passwords, or keys). We can consider a few approaches for protecting secrets in the Serverless configuration file:
  • Reference an environment variable.

  • Reference a provider service that contains the value.

  • Use an encrypted value in the Serverless configuration file.

We can use environment variables for any information we do not want to save in the source code. For example, we will obtain an API key from the environment variable to access a payment gateway; see Listing 8-1.
const { API_KEY } = process.env;
console.log('API_KEY:', API_KEY.replace(/w/g, '*'));
Listing 8-1

An Example of Referencing an Environment Variable Containing an API Key

We can store the credit payment vendor’s API key in the environment as a variable named “apiKey” which our Node function can reference. We will need to update our Serverless configuration to define the environment variable and make it accessible for the function; see Listing 8-2.
functions:
  chargeCC:
    handler: src/functions/chargeCC.handler
    events:
      - http:
          method: post
          path: chargeCC
    environment:
      API_KEY: 40d5263a-0952-4fa2-94c6-882b92523e5c
Listing 8-2

An Example of Defining an Environment Variable in the Serverless Configuration

You might notice defining the API key in the Serverless configuration has the actual API key value. The configuration might be captured in a repository1 and no longer kept secret. We have moved the API key from the function source code to the Serverless configuration, which diminishes the security patch or software update. We should have the Serverless configuration file reference the “apiKey” value rather than storing it.

We can define the environment variable containing the API key in the CI/CD pipeline that deploys the Serverless configuration; see Listing 8-3.
functions:
  chargeCC:
    handler: src/functions/chargeCC.handler
    events:
      - http:
          method: post
          path: chargeCC
    environment:
      API_KEY: ${env:API_KEY}
Listing 8-3

An Example of Referencing an Environment Variable in the Serverless Configuration

The CI/CD pipeline should have limited access and have security measures (e.g., up-to-date software, host-based firewalls) in place to reduce the risk of accidentally disclosing the environment variables.

We can reference a provider service that contains the API key, which centralizes where the value is stored. We will see examples in the AWS, Azure, and Google Cloud sections. We want to use IAM permissions to limit who and what functions have access to the value.

We can use encryption in combination with the previous three approaches we have discussed. Using encryption further reduces the risk of disclosing the secret API key by the CI/CD server, the function, or the developer. In the event the environment variables are disclosed, only the encrypted version of the API key is made known. The recipient will need to decrypt the encrypted data to obtain the API key. Remember, using a stronger encryption method will better protect the secrets.2,3

The decryption algorithm should leverage well-known algorithms rather than building a custom decryption algorithm which may introduce unknown vulnerabilities. We should consider using an encryption-decryption capability included in the provider’s libraries.

We will now explore how to protect secrets using provider capabilities.

Amazon Web Services (AWS)

In AWS, we can leverage the Systems Manager (SSM) Parameter Store,4 Secrets Manager,5 Key Management Service,6 or a combination to manage our secrets. SSM Parameter Store enables us to store the values in plaintext (i.e., unencrypted) and ciphertext (i.e., encrypted) when at rest. We can reference them in our Serverless configuration or Lambda function code. Secrets Manager enables us to store values in ciphertext at rest and can reference them in our Serverless configuration or Lambda function code. KMS allows us to encrypt and decrypt data using customer master keys (CMKs), which are unique encryption keys we generate within AWS. SSM Parameter Store and Secrets Manager use KMS to encrypt and decrypt the ciphertext. These are the three services we’ll consider to manage our secrets.

Scenario: Using AWS Systems Manager (SSM) Parameter Store

We will explore how to use SSM Parameter Store to store our secrets in plaintext and ciphertext. We can use the AWS Management Console to create a parameter as a “String” (i.e., plaintext) (see Figure 8-1) or a “SecureString” (i.e., ciphertext) (see Figures 8-2 and 8-3).
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig1_HTML.jpg
Figure 8-1

An Example of Creating an AWS SSM String (Plaintext) Parameter

../images/486121_1_En_8_Chapter/486121_1_En_8_Fig2_HTML.jpg
Figure 8-2

An Example of Creating an AWS SSM SecureString (Ciphertext) Parameter, Part 1

../images/486121_1_En_8_Chapter/486121_1_En_8_Fig3_HTML.jpg
Figure 8-3

An Example of Creating an AWS SSM SecureString (Ciphertext) Parameter, Part 2

The String parameter is stored as plaintext, whether at rest, in motion, or in use. The SecureString parameter is stored as ciphertext when at rest or in motion and is converted to plaintext when in use by the correct KMS key.

We can update our Serverless configuration to reference the String parameter (see Listing 8-4) or the SecureString parameter (see Listing 8-5).
custom:
  ssmPath: /ecommerce/${self:provider.stage}/creditCardApiKey
functions:
  chargeCC:
    handler: src/functions/chargeCC.handler
    events:
      - http:
          method: post
          path: chargeCC
    environment:
      API_KEY: ${ssm:${self:custom.ssmPath} }
Listing 8-4

An Example of Referencing an AWS SSM String Parameter in the Serverless Configuration

custom:
  ssmPath: /ecommerce/${self:provider.stage}/secure/creditCardApiKey
functions:
  chargeCC:
    handler: src/functions/chargeCC.handler
    events:
      - http:
          method: post
          path: chargeCC
    environment:
      API_KEY: ${ssm:${self:custom.ssmSecure}~true}
Listing 8-5

An Example of Referencing an AWS SSM SecureString Parameter in the Serverless Configuration

With either approach, the parameter value is passed in plaintext to the Lambda function environment variables; see Figure 8-4.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig4_HTML.jpg
Figure 8-4

An Example of AWS Lambda Environment Variables Containing Plaintext Secrets

Anyone able to access the Lambda function configuration section or disclose the environment variables during the Lambda function runtime can obtain the API key. To avoid this risk, we can dynamically get the SSM parameter during the Lambda function runtime. Listing 8-6 shows an example Serverless configuration for specifying the SSM parameter name to a Lambda function. (Listing 8-6 has the appropriate IAM permissions to allow the Lambda function to access the SSM parameters and uses the Serverless IAM Roles per Function plugin we discussed in Chapter 6.) Listing 8-7 shows an example of using the SSM parameter name to obtain an SSM SecureSring parameter. Setting the “WithDecryption” value to “true” retrieves an SSM SecureString parameter, whereas setting it to "false" retrieves an SSM String parameter.
custom:
  arnPrefix: arn:aws:ssm:${self:provider.region}:*:parameter
  ssmPath: /ecommerce/${self:provider.stage}/secure/creditCardApiKey
functions:
  chargeCC:
    handler: src/functions/chargeCC.handler
    events:
      - http:
          method: post
          path: chargeCC
    environment:
      PARAMETER_NAME: /ecommerce/${self:provider.stage}/secret/creditCardApiKey
    iamRoleStatements:
      - Effect: Allow
        Action: ssm:GetParameter
        Resource: ${self:custom.arnPrefix}${self:custom.ssmPath}
plugins:
  - serverless-iam-roles-per-function
Listing 8-6

Updating the Serverless Configuration to Use the SSM Parameter Name

const AWS = require('aws-sdk');
const ssm = new AWS.SSM();
const { PARAMETER_NAME } = process.env;
const params = {
    Name: PARAMETER_NAME,
    WithDecryption: true
};
module.exports.handler = (event, context, callback) => {
    return ssm
        .getParameter(params)
        .promise()
        .then((data) => {
            const apiKey = data.Parameter.Value;
            console.log(
                'apiKey:',
                apiKey.replace(/w/g, '*'),
            );
            callback(null, {
                statusCode: 200,
                body: 'Success'
            });
        })
        .catch((err) => {
            console.error(err);
            callback(null, {
                statusCode: 500,
                body: 'Error'
            });
        });
};
Listing 8-7

An Example of Obtaining an SSM SecureString Parameter in a Lambda Function

We no longer have to maintain the Serverless configuration file and deploy it whenever the SSM parameter is updated. The Lambda function will dynamically obtain the latest SSM parameter value every time it executes. We should consider using the SSM SecureString parameter because the data is encrypted using an AWS-managed KMS key.

Scenario: Using AWS Key Management System (KMS)

We will explore how to use Key Management System (KMS) keys to encrypt our secrets.

We will create a CMK using the AWS Management Console and following the on-screen prompts; see Figure 8-5.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig5_HTML.jpg
Figure 8-5

An Example of Creating a Customer Managed Key

We will use the Key ID listed in the KMS CMK section (see Figure 8-6) to encrypt our API key.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig6_HTML.jpg
Figure 8-6

An Example of a Customer Managed Key ID

We will use the AWS CLI to encrypt the API key (see Listing 8-8), which returns a JSON object containing the ciphertext (see Listing 8-9).
aws2 kms encrypt
--key-id dc435c97-f2da-4d59-971b-2694d57f0b63
--plaintext 40d5263a-0952-4fa2-94c6-882b92523e5c
--region us-east-1
Listing 8-8

An Example of Encrypting an API Key Using the AWS CLI

{
    "CiphertextBlob": "AQICAHgC7mTtcEJQ1Y3mcIte25SbVsB/yZnL7UzG0fzWgHVJoAFSxCxpGJ6cyeLQl9J7s7+bAAAAgzCBgAYJKoZIhvcNAQcGoHMwcQIBADBsBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDP78crOWYO1h6P0U8QIBEIA/VIZuslMvhwB9M8KE7ONKaqoYmQUgRwQivT63SZuA2BOifQg7uvbN2QgNEHo3VC0HfJKO+mS+bFXWHC1qJtiB",
    "KeyId": "arn:aws:kms:us-east-1:123456789012:key/dc435c97-f2da-4d59-971b-2694d57f0b63"
}
Listing 8-9

An Example Output of the Encryption

We can update the Serverless configuration file to use the ciphertext; see Listing 8-10. We added the appropriate IAM permissions to allow the Lambda function to access the KMS decryption and used the Serverless IAM Roles per Function plugin we discussed in Chapter 6.
functions:
  chargeCC:
    handler: src/functions/chargeCC.handler
    events:
      - http:
          method: POST
          path: chargeCC
    environment:
      ENCRYPTED_API_KEY: |
AQICAHgC7mTtcEJQ1Y3mcIte25SbVsB/yZnL7UzG0fzWgHVJoAFSxCxpGJ6cyeLQl9J7s7+bAAAAgzCBgAYJKoZIhvcNAQcGoHMwcQIBADBsBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDP78crOWYO1h6P0U8QIBEIA/VIZuslMvhwB9M8KE7ONKaqoYmQUgRwQivT63SZuA2BOifQg7uvbN2QgNEHo3VC0HfJKO+mS+bFXWHC1qJtiB
    iamRoleStatements:
      - Effect: Allow
        Action: kms:Decrypt
        Resource: arn:aws:kms:${self:provider.region}:*:key/*
plugins:
  - serverless-iam-roles-per-function
Listing 8-10

Specifying the Ciphertext in the Serverless Configuration File

We will decrypt the ciphertext using KMS during the Lambda function runtime; see Listing 8-11.
const AWS = require('aws-sdk');
const kms = new AWS.KMS();
const { ENCRYPTED_API_KEY } = process.env;
const params = {
    CiphertextBlob: ENCRYPTED_API_KEY
};
module.exports.handler = (event, context, callback) => {
    return kms
        .decrypt(params)
        .promise()
        .then((data) => {
            const apiKey = data.Plaintext;
            console.log(
                'apiKey:',
                apiKey.replace(/w/g, '*')
            );
            callback(null, {
                statusCode: 200,
                body: 'Success'
            });
        })
        .catch((err) => {
            console.error(err);
            callback(null, {
                statusCode: 500,
                body: 'Error'
            });
        });
};
Listing 8-11

Decrypting the Ciphertext Environment Variable

We can integrate this KMS encryption and decryption approach with SSM by creating a parameter containing the ciphertext or integrate with Secrets Manager by creating a secret containing the ciphertext.

We might consider this approach as the most secure, yet it is arguably the most cumbersome and expensive. We first need to pay to create a CMK. We need to encrypt the API key. We need to store the encrypted API key in the Serverless configuration file and deploy it. The Lambda function needs to decrypt the API key. Whenever the CMK or API key is changed, the previous steps need to account for the change also.

Scenario: Using AWS Secrets Manager

We will explore how to use Secrets Manager to store our secrets as the ciphertext. We can use the AWS Management Console to save a new secret; see Figures 8-7 and 8-8.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig7_HTML.jpg
Figure 8-7

An Example of Creating an AWS Secrets Manager Secret, Part 1

../images/486121_1_En_8_Chapter/486121_1_En_8_Fig8_HTML.jpg
Figure 8-8

An Example of Creating an AWS Secrets Manager Secret, Part 2

The secret is stored in ciphertext when at rest and in motion and is converted to plaintext when in use by the correct KMS key.

We can update our Serverless configuration to reference the secret, but we will forego it because it passes the secret as plaintext in the Lambda function environment variables (as discussed in the SSM example). Therefore, we will focus on getting the secret during the Lambda function runtime; see Listings 8-12 and 8-13. We added the appropriate IAM permissions in Listing 8-12 to allow the Lambda function to access the KMS decryption and used the Serverless IAM Roles per Function plugin we discussed in Chapter 6.
custom:
  arnPrefix: arn:aws:secretsmanager:${self:provider.region}:*:secret
  smPath: ecommerce/${self:provider.stage}/secret/creditCardApiKey
functions:
  chargeCC:
    handler: src/functions/chargeCC.handler
    events:
      - http:
          method: post
          path: chargeCC
    environment:
      SECRET_ID: ${self:custom.smPath}
    iamRoleStatements:
      - Effect: Allow
        Action: secretsmanager:GetSecretValue
        Resource: ${self:custom.arnPrefix}:${self:custom.smPath}*
plugins:
  - serverless-iam-roles-per-function
Listing 8-12

Updating the Serverless Configuration to Use the Secrets Manager Secret Identifier

const AWS = require('aws-sdk');
const secretsmanager = new AWS.SecretsManager();
const { SECRET_ID } = process.env;
const params = { SecretId: SECRET_ID };
module.exports.handler = (event, context, callback) => {
    return secretsmanager
        .getSecretValue(params)
        .promise()
        .then((data) => {
            const secret = JSON.parse(data.SecretString);
            const apiKey = secret.apiKey;
            console.log(
                'apiKey:',
                apiKey.replace(/w/g, '*')
            );
            callback(null, {
                statusCode: 200,
                body: 'Success'
            });
        })
        .catch((err) => {
            console.error(err);
            callback(null, {
                statusCode: 500,
                body: 'Error'
            });
        });
};
Listing 8-13

An Example of Obtaining a Secrets Manager Secret in a Lambda Function

The Lambda function will dynamically obtain the latest secret value every time it executes.

From all the scenarios, this approach has an appropriate balance between security and convenience. We still use an encryption key, but the Secrets Manager performs the encryption for us. We do not store the KMS encrypted value in the Serverless configuration. Instead, we reference the Secrets Manager secret ID. Whenever we update the secret in Secrets Manager, we do not have to update the Serverless configuration nor redeploy it. This approach has the security benefits of using KMS encryption and the convenience of referencing an SSM parameter.

Azure

In the previous section, the AWS Secrets Manager had an appropriate balance between encryption and convenience. Therefore, we will focus on using the Azure Key Vault7 feature that provides a similar capability.

The Azure Key Vault service provides secrets management, key management, certificate management, and hardware security modules. With secrets management, we specify the plaintext value, and the service encrypts the value when at rest and decrypts it when in use. Key management allows us to create encryption keys that we can use to encrypt and decrypt data. Certificate management will enable us to manage the certificates we use for network security. Hardware security modules will allow us to protect secrets using encryption hardware. We will focus on secrets management in this section.

We start by creating a new Key Vault; see Figure 8-9. We specify the subscription and the resource group where the Key Vault will exist. This example creates a new resource group to separate the Key Vault resource from other resources within the subscription.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig9_HTML.jpg
Figure 8-9

An Example of Creating a New Azure Key Vault

We create a new secret for the API key; see Figure 8-10.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig10_HTML.jpg
Figure 8-10

An Example of Creating a New Secret in Azure Key Vault

We now want to obtain the secret in the Azure Function. We define environment variables containing the Key Vault information in the Serverless configuration file; see Listing 8-14. We reference the environment variables when accessing the secret from Azure Key Vault; see Listing 8-15.
provider:
  name: azure
  region: West US 2
  runtime: nodejs10.x
  environment:
    KEY_VAULT: Ch8KeyVault
    SECRET_NAME: apiKey
Listing 8-14

An Example of Defining the Secret Name in the Serverless Configuration

const { DefaultAzureCredential } = require('@azure/identity');
const { SecretClient } = require('@azure/keyvault-secrets');
const { KEY_VAULT, SECRET_NAME } = process.env;
const credential = new DefaultAzureCredential();
const url = `https://${KEY_VAULT}.vault.azure.net`;
const client = new SecretClient(url, credential);
module.exports.handler = async (context, req) => {
    try {
        const secret = await client.getSecret(SECRET_NAME);
        let apiKey = secret.value;
        context.log('apiKey:', apiKey.replace(/w/g, '*'));
        context.res = {
            status: 200,
            body: 'Success'
        };
    } catch (e) {
        context.log(e);
        context.res = {
            status: 500,
            body: 'Error'
        };
    }
};
Listing 8-15

An Example of Accessing the Key Vault Secret in the Azure Function

After deploying the Serverless configuration, you might find the Azure Function throws an error. The Azure Function currently has no permissions to access the secret. We need to add an access policy in the Key Vault to allow the Azure Function’s resource group to get the secret; see Figure 8-11. The Serverless configuration automatically creates the resource group for us.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig11_HTML.jpg
Figure 8-11

An Example of Creating an Access Policy in Azure Key Vault

The Azure Function will dynamically obtain the latest secret value every time it executes.

Google Cloud

Again, the AWS Secrets Manager had an appropriate balance between encryption and convenience. Therefore, we will focus on using the Google Cloud secrets management8 feature that provides a similar capability.

Google Cloud secrets management provides the Secret Manager,9 Berglas,10 and HashiCorp Vault11 services. With Secret Manager, we specify the plaintext value, and the service encrypts the value when at rest and decrypts when in use. With Berglas, we leverage Google Cloud KMS for encryption and decryption and store the encrypted data in Google Cloud Storage or Secret Manager. HashiCorp Vault is similar to Secret Manager and provides additional capabilities (e.g., identity-based access). We will focus on the Secret Manager in this section.

We start by enabling the Secret Manager API; see Figure 8-12.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig12_HTML.jpg
Figure 8-12

An Example of Enabling the Secret Manager API

We can now create a new secret for the API key; see Figure 8-13.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig13_HTML.jpg
Figure 8-13

An Example of Creating a New Secret in Google Cloud Secret Manager

We view the secret details to obtain the secret name; see Figure 8-14. We will use the secret name in the Serverless configuration.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig14_HTML.jpg
Figure 8-14

An Example of a Secret Name in Google Cloud Secret Manager

We now want to obtain the secret in the Cloud Function. We define environment variables containing the Secret Manager information in the Serverless configuration file; see Listing 8-16. We reference the environment variables when accessing the secret from Secret Manager; see Listing 8-17.
functions:
  first:
    handler: chargeCC
    events:
      - http: path
    environment:
      SECRET_NAME: projects/123456789012/secrets/apiKey/versions/latest
Listing 8-16

An Example of Defining the Secret Name in the Serverless Configuration

const { SecretManagerServiceClient } = require( '@google-cloud/secret- manager');
const client = new SecretManagerServiceClient();
const { SECRET_NAME } = process.env;
exports.chargeCC = async (request, response) => {
    try {
        const [version] = await client.accessSecretVersion({
            name: SECRET_NAME
        });
        const apiKey = version.payload.data.toString('utf8');
        console.log('apiKey:', apiKey.replace(/w/g, '*'));
        response.status(200).send('Success');
    } catch (e) {
        console.error(e);
        response.status(500).send('Error');
    }
};
Listing 8-17

An Example of Accessing the Secret Manager Secret in the Cloud Function

After deploying the Serverless configuration, you might find the Cloud Function throws an error. The Cloud Function currently has no permissions to access the secret. We need to add an IAM policy to allow the Cloud Function’s service account to access the secret; Google Cloud automatically creates a default service account that Cloud Functions use.

We can obtain the service account by viewing the Cloud Function; see Figure 8-15.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig15_HTML.jpg
Figure 8-15

An Example of Obtaining the Cloud Function Service Account

We create an IAM permission granting the service account permission to access the Secret Manager secret; see Figure 8-16. We give the service account the “Secret Manager Secret Access” permission.
../images/486121_1_En_8_Chapter/486121_1_En_8_Fig16_HTML.jpg
Figure 8-16

An Example of Defining IAM Permissions for Secret Manager and Service Account

The Cloud Function will dynamically obtain the latest secret value every time it executes.

Key Takeaways

We discussed how protecting secrets is essential because they might contain information that might have a business impact if accidentally disclosed. The first step to safeguarding secrets is removing that information from the function code. The next step is storing that information elsewhere and protecting it.

We found that putting the secrets in the Serverless configuration was insufficient in protecting them. We might save the Serverless configuration in a repository, but then the secret is no longer a secret. Therefore, we needed to find a different method for securely storing the secrets.

We explored three approaches in AWS to protect the secrets: SSM, KMS, and Secrets Manager. Using SSM allowed us to get the secret in multiple ways, but using the SecureString parameter and decrypting its value in the Lambda function code proved the best with this service. Using KMS allowed us to encrypt the secret, store it as an environment variable in the Serverless configuration, and decrypt it in the Lambda function code. Using Secrets Manager allowed us to securely store the secret when at rest using a CMK and decrypt it in the Lambda function. We selected the Secrets Manager approach as having the best balance between security and convenience.

We explored the Azure Key Vault secrets and Google Cloud Secret Manager because they have a comparable approach to that of the AWS Secrets Manager. We found both services allow us to securely store the secret when at rest and decrypt it in the function. We briefly discussed the other approaches Azure and Google Cloud provide.

With whatever approach we decide to use, it should provide the desired balance between security and convenience while meeting the customer and business requirements.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.173.112