Description
Ensure that the stage variables of Amazon API Gateway REST API stages do not contain hardcoded secrets such as passwords, API keys, access keys or tokens. Credentials should be stored in AWS Secrets Manager or AWS Systems Manager Parameter Store and retrieved at runtime instead.
Rationale
Stage variables are stored in plain text in the API configuration and are visible to anyone with read access to API Gateway. A secret stored there can be read by users or tools that should not have it, leading to credential theft, unauthorized access to backend systems and movement to other resources. Removing secrets from stage variables and retrieving them from Secrets Manager or Parameter Store, for example in a Lambda authorizer or Lambda integration, keeps credentials protected and auditable.
Impact
Prevents credentials from being exposed through the API Gateway configuration
Allows secrets to be rotated and their use audited centrally
Integrations or mapping templates that use the removed variables must be changed to obtain the secret another way before the variable is removed, otherwise API calls may fail
Default Value
A new stage has no stage variables. Stage variables exist only if they were added explicitly.
Pre-Requisites
IAM permissions: apigateway:GET and apigateway:PATCH on the REST API stages
Permissions to create secrets in AWS Secrets Manager (secretsmanager:CreateSecret) or parameters in Parameter Store (ssm:PutParameter)
An updated integration (for example a Lambda function) that reads the secret at runtime instead of from the stage variable
Remediation
Test Plan
Console:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the API Gateway console and select a REST API.
Select Stages, select a stage and open its Stage variables tab.
Review the name and value of each variable for passwords, API keys, access keys, tokens, private keys or connection strings with credentials.
Repeat for each stage of each REST API in each region in use.
If any variable contains a secret, follow the implementation steps.
CLI:
List the REST APIs:
aws apigateway get-rest-apis --region <REGION> --query "items[].[id,name]" --output table
Show the stage variables of each stage of an API:
aws apigateway get-stages --region <REGION> --rest-api-id <REST_API_ID> --query "item[].{Stage:stageName,Variables:variables}" --output json
A stage fails if any of its variable values looks like a secret, such as a password, API key, access key, token or private key. Stages without variables pass.
Implementation Steps
Console:
Store each secret found in AWS Secrets Manager or as a SecureString parameter in Parameter Store.
Update the integration that used the variable (for example a Lambda function or Lambda authorizer) to read the secret from Secrets Manager or Parameter Store at runtime.
Open the API Gateway console, select the REST API and select Stages.
Select the stage, open the Stage variables tab and choose Manage variables (or Edit).
Remove each variable that contains a secret and save the changes.
Rotate each exposed secret in the system it belongs to, because it may already have been read.
Repeat for each affected stage in each region in use.
CLI:
Remove a stage variable that contains a secret:
aws apigateway update-stage --region <REGION> --rest-api-id <REST_API_ID> --stage-name <STAGE_NAME> --patch-operations op=remove,path=/variables/<VARIABLE_NAME>
Backout Plan
Before making changes, save the current stage settings:
aws apigateway get-stage --region <REGION> --rest-api-id <REST_API_ID> --stage-name <STAGE_NAME> > <STAGE_NAME>-stage-backup.json
To roll back:
Sign in to the AWS Management Console at https://console.aws.amazon.com.
Open the API Gateway console, select the REST API and select Stages.
Select the stage and open its Stage variables tab.
Add the removed variable back with its previous name and value from the saved backup, and save the changes.
CLI:
aws apigateway update-stage --region <REGION> --rest-api-id <REST_API_ID> --stage-name <STAGE_NAME> --patch-operations op=replace,path=/variables/<VARIABLE_NAME>,value=<VARIABLE_VALUE>
Note: rolling back exposes the secret in the API configuration again. Store the backup file securely and delete it when no longer needed, as it contains the secret.
Reference