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.

Python
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:

Code
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:

JSON
{
  "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:

Code
production/payment-service

For applications with multiple environments, use a consistent naming structure:

Code
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.

JSON
{
  "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:

Bash
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.

Python
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.

Python
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.

Python
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:

Bash
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:

SQL
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:

  1. Authenticate with the provider using the existing credential or another approved administrative identity.
  2. Request a new API credential.
  3. Store the new value as a pending secret version.
  4. Test the new credential against the provider.
  5. Promote the new version to the current version.
  6. 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:

Python
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.