🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

cypress-aws-secrets-manager

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cypress-aws-secrets-manager

Cypress Plugin | Integrate the power of AWS Secrets Manager seamlessly into your Cypress tests with the cypress-aws-secrets-manager plugin. This lightweight yet powerful plugin facilitates the secure loading of secrets stored in AWS Secrets Manager direct

2.1.0
Source
npm
Version published
Weekly downloads
471
19.85%
Maintainers
1
Weekly downloads
 
Created
Source

Handle AWS Secrets easily with Cypress

Managing secrets securely and efficiently is crucial for any application. This plugin integrates AWS Secrets Manager into your Cypress tests, ensuring that sensitive data like API keys, passwords, and tokens remain secure during testing. It allows for secure loading and updating of secrets directly from your tests.

Table of Contents

Upgrading to Version 2

This is version 2 of the library, which includes significant performance improvements and several changes. Please update your configuration according to the new instructions provided below to avoid any issues. See Main Changes for more details.

Installation

$ npm install cypress-aws-secrets-manager --save-dev

or as a global module

$ npm install -g cypress-aws-secrets-manager

Prerequisites

Functions

getSecretFromAWS

The getSecretFromAWS function allows you to update your environment variables by adding secrets stored in AWS Secrets Manager. This function merges existing environment variables with new secrets from AWS Secrets Manager.

getSecretFromAWS Usage

// cypress.config.js
module.exports = defineConfig({
  e2e: {
    async setupNodeEvents(on, config, __dirname) {
      const { getSecretFromAWS, updateSecret } = require('cypress-aws-secrets-manager')
      config.env = await getSecretFromAWS(config.env, __dirname)
      return config
    }
  }
})

updateSecret

The updateSecret function allows you to update secrets stored in AWS Secrets Manager. This function merges existing secrets with new values and updates the secret in AWS Secrets Manager.

updateSecret Usage

// cypress.config.js
module.exports = defineConfig({
  e2e: {
    async setupNodeEvents(on, config, __dirname) {
      const { getSecretFromAWS, updateSecret } = require('cypress-aws-secrets-manager')
      on('task', {
        updateSecret(secretValue) {
          return updateSecret(config.env, secretValue)
        }
      })
      return config
    }
  }
})

//spec.cy.js
describe('testSuite', () => {
  it('testCase 1.1', () => {
    const secretValue = { secretKey: 'secretString' }
    cy.task('updateSecret', secretValue).then((result) => {
      cy.log(JSON.stringify(result))
    })
  })
})

secretValue: An object containing the new secretString for the secretKey to update & to merge with the existing ones.

Returns

A promise that resolves with the AWS Secrets Manager response if the secret is updated successfully, or rejects with an error if the update fails

Global Configuration

Code in cypress.config.js

In your cypress.config.js file:

// cypress.config.js
module.exports = defineConfig({
  e2e: {
    async setupNodeEvents(on, config, __dirname) {
      const { getSecretFromAWS, updateSecret } = require('cypress-aws-secrets-manager')
      config.env = await getSecretFromAWS(config.env, __dirname)
      on('task', {
        updateSecret(secretValue) {
          return updateSecret(config.env, secretValue)
        }
      })
      return config
    }
  }
})

Global Variables

These configurations are external to the AWS_SECRET_MANAGER_CONFIG because they can vary for the same project when executed locally and on CI. The variables within AWS_SECRET_MANAGER_CONFIG are more dependent on the execution environment.

Global variables should be easily modifiable from the command line (see here), whereas the other configurations should not.

ParameterMandatoryNotesDefault
AWS_SSO_STRATEGYTRUEA string that defines the AWS login strategy (see here for more details)\
AWS_SECRET_MANAGER_CONFIGTRUEAn object that contains the essential configuration parameters (see here for more details)\
AWS_SECRETS_LOCAL_DIRFALSEDirectory path where secrets should be saved locally . If not specified, secrets will not be saved (see here for more details)\

AWS login strategies

  • If profile will use the profile name specified inside the AWS_SECRET_MANAGER_CONFIG (If the profile is not specified, the default profile will be used).
  • AWS_SSO_STRATEGY: 'profile'|'default'|'credentials'|'unset'|'multi'
    • If default will use the default sso config.
    • If credentials will log with aws credentials, need access_key, secret_key and session_token specified in a pathToCredential variable.
    • If unset will log with aws credentials, need access_key, secret_key and session_token as environment variable.
    • If multi will try with every strategy, fails only after trying them all.
AWS_SSO_STRATEGYAWS Auth Type
profileAWS SSO
defaultAWS SSO
credentialsAWS IAM
unsetAWS IAM
multiIf not specified the 'multi' strategy will be used.

Define AWS_SECRET_MANAGER_CONFIG object

The AWS_SECRET_MANAGER_CONFIG is an object containing the following parameters:

{
  "AWS_SECRET_MANAGER_CONFIG": {
    "secretName": "AWS_SECRET_NAME",
    "profile": "AWS_PROFILE_NAME",
    "region": "AWS_REGION",
    "pathToCredentials": "PATH_TO_AWS_CREDENTIALS.JSON"
  }
}
ParameterMandatoryNotesDefault
secretNameTRUEAWS secret name\
regionTRUEAWS Secrets Manager region\
profileFALSEAWS SSO profile name'default' profile
pathToCredentialsFALSEpath to credentials file, used with 'credentials' if u want to write them in a fileSame folder as "cypress.config.js"

Credential File example:

This credential file is used with the AWS IAM strategy. It is optional.

//pathToCredentials.json
{
  "accessKeyId": "xxxxxx",
  "secretAccessKey": "xxxxxx",
  "sessionToken": "xxxxxx"
}

Pass your AWS configuration to cypress

After defining your strategy and your AWS_SECRET_MANAGER_CONFIG.

I propose two solutions for you to import this configuration into cypress, it's up to you to decide which one to choose

"Easy" way with cypress-env plugin:

PRO: Zero code solution
CONS: cypress-env needed

Following the plugin's guide, you should end up with a JSON file, which must respect this syntax:

//environment.json
{
  "baseUrl": "https://www.google.com",
  "env": {
    "var1": "value1",
    "var2": "value2",
    "var3": "value3"
  }
}

Simply add "AWS_SSO_STRATEGY" and AWS_SECRET_MANAGER_CONFIG inside the "env" object as follows:

//environment.json
{
  "baseUrl": "https://www.google.com",
  "env": {
    "var1": "value1",
    "var2": "value2",
    "var3": "value3",
    "AWS_SSO_STRATEGY": "strategy_type",
    "AWS_SECRET_MANAGER_CONFIG": {
      "secretName": "AWS_SECRET_NAME",
      "profile": "AWS_PROFILE_NAME",
      "region": "AWS_REGION",
      "pathToCredentials": "PATH_TO_AWS_CREDENTIALS.JSON"
    }
  }
}

No other changes needed

"Complex" way inside cypress.config.js:

PRO: No cypress-env needed
CONS: Solution with some code

//cypress.config.js
module.exports = defineConfig({
  e2e: {
    async setupNodeEvents(on, config, __dirname) {
      const { getSecretFromAWS, updateSecret } = require('cypress-aws-secrets-manager')
      config.env = await getSecretFromAWS(config.env, __dirname)
      return config
    }
  },
  env: {
    AWS_SSO_STRATEGY: 'strategy_type',
    AWS_SECRET_MANAGER_CONFIG: {
      secretName: 'AWS_SECRET_NAME',
      profile: 'AWS_PROFILE_NAME',
      region: 'AWS_REGION',
      pathToCredentials: 'PATH_TO_AWS_CREDENTIALS.JSON'
    }
  }
})

Importing Secrets from a Local File

I understand that allowing users to load secrets from a local file might seem counterintuitive. However, this approach becomes necessary especially when using a cloud provider like AWS, in scenarios involving assume-role chains that are limited to an hour in duration.

When conducting sequential tests, particularly with tools like Cypress that restart and reload environment variables for each new session, obtaining AWS secrets after the initial hour can be cumbersome. This can interrupt testing workflows, especially when secrets are needed across multiple sessions. To mitigate this issue, I’ve added the option for users to specify a AWS_SECRETS_LOCAL_DIR variable.

If AWS_SECRETS_LOCAL_DIR is specified and the temporary file doesn't exist, the plugin will retrieve the secrets during the first session and store them locally. These stored secrets will then be reused in subsequent sessions, eliminating the need to continuously fetch them from AWS after the role chain expires.Every secrets will be saved in a JSON file named by the secret name.

This solution simplifies running multiple test sequences without worrying about refreshing the role or secret access within the limited session time frame.

See here to understand how to use different behavior on CI.

//environment.json
{
  "baseUrl": "https://www.google.com",
  "env": {
    "AWS_SSO_STRATEGY": "strategy_type",
    "AWS_SECRETS_LOCAL_DIR": "aws_secrets_folder",
    "AWS_SECRET_MANAGER_CONFIG": {
      "secretName": "AWS_SECRET_NAME",
      "profile": "AWS_PROFILE_NAME",
      "region": "AWS_REGION",
      "pathToCredentials": "PATH_TO_AWS_CREDENTIALS.JSON"
    }
  }
}

Overwrite Environment Variables when running on a different machine or on CI

Sometimes you'll need to override the AWS_SSO_STRATEGY & AWS_SECRETS_LOCAL_DIR property that was provided inside cypress.config.env.
To do so, you'll need to run cypress with the following command:

npx cypress run -e AWS_SSO_STRATEGY=$OVERWRITING_AWS_SSO_STRATEGY,AWS_SECRETS_LOCAL_DIR=$FOLDER_TO_SAVE_SECRETS_LOCALLY

Where $OVERWRITING_AWS_SSO_STRATEGY is the new strategy value.

Results

Correct configuration

====================================================================================================

Starting plugin: cypress-aws-secrets-manager

AWS SSO strategy: profile

1st attempt: Trying to login into AWS with profile: "AWS_PROFILE_NAME"

AWS SDK credentials are set up correctly!

Extracting secret from: "AWS Secrets Manger"

secret: "{
    "username": "*****",
    "password": "*****"
}"

√ Secret loaded correctly from: "AWS_SECRET_NAME"

====================================================================================================

Missing configuration

Description
Cypress has starter without plugin configurations

====================================================================================================

Starting plugin: cypress-aws-secrets-manager
√ Missing AWS_SECRET_MANAGER_CONFIG, continue without secrets!


====================================================================================================

Wrong configuration

Description
Properties: secretName & region are mandatory

====================================================================================================

Starting plugin: cypress-aws-secrets-manager

"AWS_SECRET_MANAGER_CONFIG" object MUST contains these mandatory properties: secretName,region
ConfigurationError!

Passed: [
 "profile": "AWS_PROFILE_NAME"
]
Missing: [
 "secretName",
 "region"
]

====================================================================================================

Wrong credentials

Description
Your credentials are invalid

====================================================================================================

Starting plugin: cypress-aws-secrets-manager

AWS SSO strategy: "multi"

1st attempt: Trying to login into AWS with profile: "AWS_PROFILE_NAME"

2nd attempt: Trying to login into AWS with profile: "default"

3rd attempt: Trying without specifying credentials

Incorrect plugin configuration!
ERROR: Could not load credentials from any providers

====================================================================================================

Little tip for you

You can create a bash file that verifies if you are already logged into the AWS account:
NB Change AWS_PROFILE & AWS_USER with your data

#awslogin_script.sh
#!/bin/bash
AWS_PROFILE='your_profile'
AWS_USER="your_aws_user_number"

# Check to see if we are already logged in
ACCOUNT_ID_TEMP=$(aws sts get-caller-identity --query "Account" --profile $AWS_PROFILE | tr -d '"')

# If response is "533223568588" we are already logged in
if [ "$ACCOUNT_ID_TEMP" = "$AWS_USER" ]; then
    echo "AWS SSO session still valid, no login needed"

# Else we login with "aws sso login"
else
    echo ""
    echo "AWS SSO session expired, login needed"
    echo ""
    aws sso login --profile onboarding-noprod

fi

Then in your package.json file create a script like this:

//package.json
{
  "scripts": {
    "cy:open": "sh awslogin_script.sh && npx cypress open",
    "cy:run": "sh awslogin_script.sh && npx cypress run"
  }
}

So you'll only have to type this command to open cypress and login into aws:

npm run cy:open

Main Changes from V1

Storing AWS_SECRET_MANAGER_CONFIG

The AWS_SECRET_MANAGER_CONFIG should now be stored as a Cypress environment variable inside config.env instead of directly in config. Additionally, its name has changed from awsSecretManagerConfig to AWS_SECRET_MANAGER_CONFIG (although awsSecretManagerConfig is still valid).

Library Import in setupNodeEvents

The library should now be imported and used as follows:

const { getSecretFromAWS, updateSecret } = require('cypress-aws-secrets-manager')
config.env = await getSecretFromAWS(config.env, __dirname)

Old method:

const getSecretFromAWS = require('cypress-aws-secrets-manager')
await getSecretFromAWS(on, config, __dirname)

THE JOB IS DONE!

Happy testing to everyone!

ALEC-JS

🙌 Donate to support my work & further development! 🙌

Keywords

aws

FAQs

Package last updated on 18 Sep 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts