Most applications depend on external services. A payment application may connect to a payment gateway, an e-commerce platform may use a shipping API, and a customer management system may communicate with third-party services.
These integrations usually require API keys, access tokens, client secrets, or other credentials.
The problem starts when developers store these credentials directly in source code, configuration files, or deployment scripts. A developer might add an API key to a configuration file during development and later commit that file to Git. Even if the repository is private, credentials can become accessible to people or automated systems that should not have access to them.
Keeping secrets in environment variables is better than hardcoding them, but it does not solve every secret management problem. Teams still need a reliable way to store credentials, control access, rotate them, and retrieve updated values without changing application code.
AWS Secrets Manager provides a centralized solution for managing external application credentials. It allows applications to retrieve secrets at runtime using AWS SDKs, while IAM policies control which services and users can access them.
In this article, we will explore how to manage external API credentials using AWS Secrets Manager, retrieve secrets from a Python application, configure IAM permissions, implement credential rotation, and handle common problems in production environments.
Why External API Secrets Need Centralized Management
Consider an application that communicates with three external services:
- A payment gateway.
- An email delivery service.
- A third-party customer management platform.
Each service provides credentials that the application needs to authenticate API requests.
A simple implementation might store these credentials directly in the application configuration.
PAYMENT_API_KEY = "payment-secret-key"
EMAIL_API_KEY = "email-secret-key"
CRM_API_KEY = "crm-secret-key"
This approach creates several problems.
Credentials Can Be Exposed Through Source Code
Developers may accidentally commit credentials to Git repositories.
Even if the credentials are removed in a later commit, they may remain available in the repository's history.
Credential Rotation Becomes Difficult
When an external service changes an API key, developers may need to update configuration files, deployment variables, and multiple application environments.
If several applications share the same credential, coordinating the change becomes even more difficult.
Access Control Is Limited
A shared configuration file does not provide the same level of access management as a dedicated secrets management service.
It becomes harder to determine which application or AWS identity should be allowed to retrieve a particular credential.
Multiple Environments Need Different Credentials
Development, testing, staging, and production environments should not necessarily use the same external API credentials.
Without centralized management, maintaining separate configurations can become difficult.
AWS Secrets Manager addresses these problems by providing a dedicated service for storing, retrieving, managing, and rotating sensitive information.
Understanding AWS Secrets Manager
AWS Secrets Manager is a managed service for storing and retrieving sensitive information such as:
- External API keys.
- OAuth client secrets.
- Database credentials.
- Third-party service passwords.
- Application access tokens.
- Other confidential configuration values.
Secrets are encrypted at rest using AWS Key Management Service (AWS KMS) and transmitted securely over TLS when retrieved.
Applications can access secrets through AWS SDKs or supported AWS integrations.
For example, a Python application running on Amazon EC2 can use its attached IAM role to retrieve an API key without storing AWS access keys inside the application.
The basic architecture looks like this:
External API Provider
|
v
API Credentials
|
v
AWS Secrets Manager
|
| IAM Authorization
|
v
Application Running on AWS
|
v
Retrieve Secret
|
v
External API Request
The application does not need to contain the actual external API key in its source code.
Instead, it retrieves the required value when it needs to authenticate with the external service.
Creating a Secret in AWS Secrets Manager
Let's use a practical example.
Assume that a Python application needs to communicate with an external payment service.
The payment provider gives the development team an API key that must be used when sending payment requests.
Instead of storing the key in the application, we will create a secret in AWS Secrets Manager.
Step 1: Open AWS Secrets Manager
Sign in to the AWS Management Console.
Navigate to AWS Secrets Manager and select the option to store a new secret.
Choose the appropriate secret type for your use case. For a general external API credential, use the option for other types of secrets.
Step 2: Enter the API Credential
Secrets Manager supports storing secret values as plain text or key-value JSON.
For an application that needs multiple credentials, JSON is a convenient option.
For example:
{
"api_key": "your-payment-api-key",
"api_url": "https://api.example.com",
"environment": "production"
}
This structure keeps related configuration values together.
The actual API key should be obtained from the external provider. Do not use example credentials in a real application.
Step 3: Configure the Secret Name
Give the secret a descriptive name.
For example:
production/payment-service
For applications with multiple environments, use a consistent naming structure:
development/payment-service
staging/payment-service
production/payment-service
This makes it easier to identify which application environment should retrieve each credential.
Step 4: Configure Encryption
AWS Secrets Manager encrypts secrets using AWS KMS.
For many applications, the AWS managed key named aws/secretsmanager is sufficient.
If your organization needs custom key policies, cross-account access, or additional control over encryption, consider using a customer-managed KMS key.
When using a customer-managed key, make sure the relevant IAM permissions and key policy allow the application to retrieve the secret.
Step 5: Review and Store
Review the secret name, secret value, encryption configuration, and access requirements.
Save the secret.
After creation, it will be available through the Secrets Manager console and API.
Configuring IAM Permissions for Secret Access
Creating a secret does not automatically give every application permission to retrieve it.
AWS Identity and Access Management controls access to Secrets Manager.
A production application should receive permission to retrieve only the secrets it actually needs.
For example, an EC2 application that uses the payment API should not automatically receive access to the email service credentials.
Creating a Least-Privilege IAM Policy
The following policy allows an application role to retrieve one specific secret.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:ap-south-1:123456789012:secret:production/payment-service-*"
}
]
}
Replace the AWS account ID, Region, and secret identifier with your actual values.
The policy grants only the GetSecretValue action for the specified secret.
If you use a customer-managed KMS key, the application role may also need the appropriate kms:Decrypt permission, and the KMS key policy must allow the operation.
Use IAM Roles Instead of Access Keys
When an application runs on an AWS service such as EC2, Lambda, or ECS, use the appropriate IAM role or task execution identity for AWS API access.
For example:
- EC2 applications can use instance profiles.
- Lambda functions can use execution roles.
- ECS applications can use task roles.
This avoids placing long-term AWS access keys inside application configuration.
The AWS SDK can obtain temporary credentials through the configured AWS identity automatically.
Retrieving API Secrets From a Python Application
After creating the secret and configuring IAM permissions, the application can retrieve its value using the AWS SDK for Python, also known as Boto3.
Step 1: Install Boto3
Install the required package:
pip install boto3
Boto3 provides the client used to communicate with AWS Secrets Manager.
Step 2: Create a Secret Retrieval Function
Create a Python file named secrets_manager.py.
import boto3
import json
from botocore.exceptions import (
ClientError,
BotoCoreError
)
def get_secret(secret_name, region_name):
client = boto3.client(
"secretsmanager",
region_name=region_name
)
try:
response = client.get_secret_value(
SecretId=secret_name
)
secret_string = response.get("SecretString")
if not secret_string:
raise ValueError(
"Secret does not contain a SecretString value"
)
return json.loads(secret_string)
except (ClientError, BotoCoreError) as error:
raise RuntimeError(
"Unable to retrieve application secret"
) from error
The function performs several operations.
First, it creates a Secrets Manager client for the selected AWS Region.
Next, it calls get_secret_value() to retrieve the secret.
The returned SecretString contains the JSON configuration stored earlier.
Finally, json.loads() converts the JSON string into a Python dictionary.
The example assumes the secret is stored as JSON text. If the secret uses a binary value, handle SecretBinary separately.
Step 3: Use the Retrieved Credential
Create an application file named payment_service.py.
import requests
from secrets_manager import get_secret
secret = get_secret(
"production/payment-service",
"ap-south-1"
)
api_key = secret["api_key"]
api_url = secret["api_url"]
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
response = requests.get(
f"{api_url}/payments",
headers=headers,
timeout=10
)
response.raise_for_status()
print("Payment service request completed.")
The application retrieves the credential from Secrets Manager and uses it to authenticate the external API request.
The API key is not written directly into the Python source code.
For production applications, avoid printing secret values or including authentication headers in HTTP logs.
Also verify the authentication format required by the external provider. Some APIs expect bearer tokens, while others require custom headers or signed requests.
Reducing Repeated Secrets Manager API Calls
One important consideration is how frequently an application retrieves secrets.
Calling Secrets Manager every time an API request is processed is usually unnecessary.
For example, an application receiving thousands of requests may repeatedly retrieve the same API key.
This increases network calls, adds latency, and can increase Secrets Manager costs.
A better approach is to cache the retrieved secret for a controlled period.
Using a Simple Application-Level Cache
The following example keeps a secret in application memory for five minutes.
import time
from secrets_manager import get_secret
_cached_secret = None
_cache_expiry = 0
def get_cached_payment_secret():
global _cached_secret, _cache_expiry
current_time = time.time()
if (
_cached_secret is None
or current_time >= _cache_expiry
):
_cached_secret = get_secret(
"production/payment-service",
"ap-south-1"
)
_cache_expiry = current_time + 300
return _cached_secret
The application retrieves the secret when the cache is empty or expired.
Subsequent calls reuse the cached value until the five-minute period ends.
This is a simple implementation. In applications with multiple threads, use appropriate synchronization. For larger Python applications, the AWS Secrets Manager caching component is another option.
AWS provides a Python caching library called aws-secretsmanager-caching.
Install it using:
pip install aws-secretsmanager-caching
The library supports client-side caching and refreshes cached secrets periodically. Its default refresh interval is one hour.
Caching introduces an important trade-off: an application may continue using an older credential until its cache refreshes. Choose a refresh interval based on the rotation schedule and the external service's credential requirements.
Rotating External API Credentials
Storing credentials securely is only part of secret management. Teams must also replace credentials periodically and respond quickly when a credential is compromised.
For example, suppose a payment provider requires the application to replace its API key every 90 days.
Without a centralized secret management process, developers might need to update multiple configuration files and redeploy several applications.
AWS Secrets Manager supports secret rotation through scheduled rotation and Lambda-based rotation functions.
However, rotating an external API key requires cooperation from the external provider. Secrets Manager cannot automatically generate a new valid credential inside an unrelated third-party service unless that service provides an appropriate API or rotation mechanism.
Understanding the Rotation Process
A typical rotation workflow looks like this:
Rotation Schedule
|
v
Secrets Manager
|
v
Rotation Lambda Function
|
v
External API Provider
|
v
Generate New Credential
|
v
Validate New Credential
|
v
Update Secret Version
|
v
Application Retrieves New Secret
The rotation Lambda function communicates with the external service, creates or retrieves a replacement credential, and validates it before completing the rotation.
For supported rotation workflows, Secrets Manager uses staging labels such as AWSPENDING and AWSCURRENT to manage secret versions.
Implementing External API Key Rotation
The exact implementation depends on the external provider.
For example, a provider might offer an API endpoint that creates a new API token.
The rotation function would generally perform these operations:
- Authenticate with the provider using the existing credential or another approved administrative identity.
- Request a new API credential.
- Store the new value as a pending secret version.
- Test the new credential against the provider.
- Promote the new version to the current version.
- Revoke the old credential when it is safe to do so.
The order is important.
If the old credential is revoked before the new credential is validated, the application may lose access to the external service.
Some providers allow two active API keys during a transition. This makes it easier to update applications without interrupting requests.
If the provider supports only one active key, plan the rotation carefully and account for application cache expiration.
Handling Credential Rotation in the Application
An application should not assume that its cached credential remains valid indefinitely.
After rotation, the application should retrieve the current secret version when its cache expires.
For applications that need faster recovery, consider handling authentication failures by refreshing the secret and retrying a request when the provider's error response clearly indicates an expired or revoked credential.
Do not retry every failed request automatically. Network failures, invalid payloads, rate limits, and authorization errors require different handling.
Handling Secret Retrieval Errors in Production
Applications should be prepared for situations where Secrets Manager cannot return a credential.
Possible causes include:
- Missing IAM permissions.
- An incorrect secret name.
- An invalid AWS Region.
- Network connectivity problems.
- KMS decryption permission failures.
- A deleted or unavailable secret.
A production application should handle these situations without exposing secret values or internal AWS error details to users.
For example, improve the retrieval function with explicit error handling:
import boto3
import json
from botocore.exceptions import ClientError
def get_secret(secret_name, region_name):
client = boto3.client(
"secretsmanager",
region_name=region_name
)
try:
response = client.get_secret_value(
SecretId=secret_name
)
value = response.get("SecretString")
if value is None:
raise RuntimeError(
"Secret value is not available as text"
)
return json.loads(value)
except client.exceptions.ResourceNotFoundException:
raise RuntimeError(
"Required application secret was not found"
)
except client.exceptions.AccessDeniedException:
raise RuntimeError(
"Application is not authorized to retrieve the secret"
)
except ClientError as error:
raise RuntimeError(
"AWS Secrets Manager request failed"
) from error
This example handles common retrieval failures separately.
In a real application, log the error category and relevant request information without logging the actual credential.
For temporary service failures, use bounded retries with exponential backoff and jitter where appropriate. Avoid retrying authorization failures or missing-secret errors indefinitely.
Monitoring and Auditing Secret Access
Knowing where credentials are stored is not enough. Teams should also understand which identities are retrieving them.
AWS provides CloudTrail integration for auditing Secrets Manager API activity.
Administrators can review events such as:
- Secret retrieval requests.
- Secret creation.
- Secret updates.
- Secret deletion.
- Rotation operations.
- Changes to secret resource policies.
For example, a security team may investigate why an application role retrieved a payment credential from an unexpected environment.
CloudTrail records help identify the AWS identity and API operation involved.
CloudTrail auditing does not record the secret value itself in the event details, which helps prevent credential exposure through the audit trail.
For production systems, configure appropriate monitoring and alerts for unusual access patterns, unexpected permission changes, and failed rotation operations.
Best Practices for Managing External API Secrets
Use Separate Secrets for Different Environments
Development and production applications should not share the same external API credentials.
Use separate secret names and IAM permissions for each environment.
Follow the Principle of Least Privilege
Give an application permission to retrieve only the secrets it requires.
Avoid granting broad access to every secret in an AWS account.
Prefer IAM Roles Over Static AWS Credentials
Use EC2 instance profiles, Lambda execution roles, or ECS task roles instead of storing long-term AWS access keys in application configuration.
Implement Client-Side Caching
Avoid retrieving the same credential for every application request.
Use an appropriate cache duration and make sure the application can obtain the updated credential after rotation.
Rotate Credentials Carefully
Use a rotation process supported by the external provider.
Validate new credentials before revoking old ones, and plan for the effect of application caching.
Avoid Logging Sensitive Information
Never log API keys, passwords, authorization headers, or complete secret values.
Review application logs, exception handlers, and monitoring integrations to ensure credentials are not accidentally exposed.
Monitor Access Through CloudTrail
Review secret access events and investigate unexpected retrieval activity.
This helps security teams understand how sensitive credentials are being used.
Plan for Secret Recovery
Document how to replace a compromised credential, restore access, and update dependent applications.
A secret management process should cover both routine rotation and emergency credential replacement.
Common Mistakes When Using AWS Secrets Manager
Mistake | Why it creates problems | Recommended approach |
|---|
Hardcoding AWS access keys | Creates another credential exposure risk | Use IAM roles |
Granting access to all secrets | Increases the impact of a compromised application | Apply resource-level permissions |
Retrieving secrets on every request | Adds latency and unnecessary API calls | Use client-side caching |
Logging secret values | Exposes credentials to log readers | Log error categories without sensitive values |
Assuming rotation is automatic | External API providers may require custom integration | Implement a provider-specific rotation function |
Ignoring cache expiration | Applications may continue using old credentials | Coordinate cache refresh with rotation |
Sharing credentials across environments | Makes access control and incident response difficult | Maintain separate environment-specific secrets |
Ignoring KMS permissions | Secret retrieval may fail during decryption | Review IAM and KMS key policies |
Advantages and Disadvantages of AWS Secrets Manager
Advantages
- Centralized storage for application credentials.
- Encryption at rest and secure retrieval.
- IAM-based access control.
- Integration with AWS services and SDKs.
- Support for secret versioning and rotation workflows.
- CloudTrail auditing of secret management operations.
- Client-side caching options for reducing repeated retrieval calls.
Disadvantages
- Secret retrieval and storage incur AWS charges.
- Applications require additional AWS permissions and configuration.
- External API rotation may require custom Lambda functions.
- Cached credentials can remain outdated until refreshed.
- Applications become dependent on Secrets Manager availability when retrieving credentials.
- Poorly configured IAM or KMS policies can prevent applications from accessing secrets.
Summary
Managing external API credentials is an important part of application security. Storing API keys directly in source code or sharing configuration files across environments creates unnecessary security and maintenance risks.
AWS Secrets Manager provides a centralized way to store, retrieve, encrypt, and manage these credentials. With Boto3, a Python application can retrieve its required API keys at runtime without placing the actual values inside the source code.
For production applications, secret retrieval should be combined with IAM least-privilege policies, client-side caching, credential rotation, and CloudTrail monitoring.
Remember that external API key rotation depends on the capabilities of the external provider. A complete rotation process must create and validate the replacement credential before the old one is revoked.
When these practices are implemented together, teams can manage external service credentials more consistently, reduce accidental exposure, and simplify application maintenance across development, staging, and production environments.
Join the conversation! Your thoughts help the community grow.