AWS Secrets ManagerSecrets ManagementIAMSecurityRotation

AWS Secrets Manager: Securing and Monitoring Your Application Secrets

Vigilare Engineering

Platform Team · January 20, 2026 · 9 min read

The Hardcoded Credentials Problem

Database passwords in application code. API keys in environment variables that end up in logs. Credentials committed to GitHub repositories that developers thought were private. These aren't hypothetical scenarios — they're the most common causes of AWS credential exposure, and they're almost entirely preventable.

AWS Secrets Manager exists to solve exactly this problem. It's a managed service for storing, rotating, and auditing access to application secrets — database credentials, API keys, OAuth tokens, TLS certificates, and anything else your applications shouldn't have hardcoded. This guide covers how to use it correctly and how to monitor for the security issues that still arise even when you're using it.

What Secrets Manager Actually Does

At its core, Secrets Manager provides three things:

  1. Encrypted storage — Secrets are encrypted at rest using KMS (either an AWS managed key or a CMK you specify). See our KMS security guide for implications.
  2. Programmatic retrieval — Applications call the Secrets Manager API to retrieve secrets at runtime, eliminating the need to store credentials in configuration files or environment variables.
  3. Automatic rotation — For supported services (RDS, Redshift, DocumentDB, and others), Secrets Manager can rotate credentials automatically on a schedule, eliminating the operational burden of manual rotation.

Migrating from Environment Variables to Secrets Manager

The first step for most teams is migrating existing hardcoded or environment-variable-based credentials to Secrets Manager. The process:

Creating a Secret

aws secretsmanager create-secret   --name "prod/myapp/database"   --description "Production database credentials"   --secret-string '{"username":"appuser","password":"changeme"}'   --kms-key-id arn:aws:kms:us-east-1:123456789012:key/your-key-id

Retrieving Secrets in Application Code

The AWS SDK provides native Secrets Manager clients for all major languages. In Python:

import boto3
import json

def get_secret(secret_name):
    client = boto3.client('secretsmanager')
    response = client.get_secret_value(SecretId=secret_name)
    return json.loads(response['SecretString'])

A common pattern is to cache the secret in memory after the first retrieval and refresh it periodically or on rotation. The AWS SDK's built-in caching library handles this automatically.

IAM Permissions for Secret Access

Applications need IAM permissions to call secretsmanager:GetSecretValue. The principle of least privilege applies: each application should have access only to its own secrets.

{
  "Effect": "Allow",
  "Action": ["secretsmanager:GetSecretValue"],
  "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/myapp/*"
}

Avoid granting secretsmanager:* or access to * resources. Even in development environments, use secret-specific permissions to build the habit.

Automatic Secret Rotation

Manual credential rotation is error-prone and often deferred indefinitely. Secrets Manager automates this for supported database types using Lambda functions that update the credential in both the database and Secrets Manager.

Enabling Rotation for RDS

aws secretsmanager rotate-secret   --secret-id prod/myapp/database   --rotation-rules AutomaticallyAfterDays=30   --rotate-immediately

For RDS, Secrets Manager creates a Lambda function in your account that performs the rotation. The function handles the two-phase rotation process: creating new credentials, verifying they work, and only then deprecating the old ones. See our guide on RDS security for the full database security context.

Custom Rotation Functions

For services not natively supported (third-party APIs, internal services), you can write a custom Lambda rotation function. The rotation contract requires implementing four steps: createSecret, setSecret, testSecret, finishSecret. AWS provides templates for common patterns.

Monitoring Secrets Manager with CloudTrail

Every Secrets Manager API call is logged to CloudTrail. This gives you a complete audit trail of who accessed which secrets, when, and from where. The events to watch:

High-Priority Events

  • GetSecretValue — The most important event. Every time a secret is retrieved, it's logged. Unexpected access patterns here indicate credential compromise.
  • DeleteSecret — Secret deletion starts a recovery window (7-30 days by default). Alert immediately.
  • PutSecretValue — Secret value was changed outside the rotation process. Could indicate unauthorized modification.
  • UpdateSecret — Secret metadata or KMS key was changed.
  • RemoveRegionsFromReplication / ReplicateSecretToRegions — Cross-region replication changes.

CloudWatch Alarm for Unexpected GetSecretValue

A metric filter that counts unexpected callers:

aws cloudwatch put-metric-alarm   --alarm-name "UnexpectedSecretAccess"   --metric-name "UnauthorizedSecretAccess"   --namespace "SecurityMetrics"   --statistic Sum   --period 300   --threshold 1   --comparison-operator GreaterThanOrEqualToThreshold   --evaluation-periods 1   --alarm-actions arn:aws:sns:us-east-1:123456789012:SecurityAlerts

Combine this with a CloudTrail metric filter that counts GetSecretValue calls from principals outside your expected application roles. Any call from an unexpected principal should be investigated. See our CloudTrail alerting guide for the full setup.

Detecting Access from Unusual Locations

GuardDuty can detect GetSecretValue calls from TOR exit nodes, known malicious IPs, and anomalous locations. Enable GuardDuty and ensure its findings include Secrets Manager events. See the GuardDuty setup guide for configuration details.

Resource-Based Policies for Secrets

In addition to IAM policies, secrets support resource-based policies that control access at the secret level. This is useful for cross-account access or when you want to restrict access to specific conditions:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::111122223333:role/ApplicationRole"
    },
    "Action": "secretsmanager:GetSecretValue",
    "Resource": "*",
    "Condition": {
      "StringEquals": {
        "secretsmanager:VersionStage": "AWSCURRENT"
      }
    }
  }]
}

The condition restricting to AWSCURRENT is important during rotation: it ensures applications always get the current credential rather than a pending rotation version. For cross-account patterns, see our resource-based policies guide.

Common Misconfigurations to Avoid

Overly Permissive Secret Access

The most common Secrets Manager mistake is granting a Lambda function or EC2 role access to secretsmanager:GetSecretValue on resource *. This means the compromised workload can read every secret in the account. Always scope to specific secrets or secret name patterns.

Using Default KMS Keys for Sensitive Secrets

By default, Secrets Manager uses the AWS managed key aws/secretsmanager. For sensitive credentials, consider using a CMK so you have full control over who can decrypt the secret and can audit key usage separately. Review our KMS security guide for guidance on when CMKs are warranted.

Not Enabling Deletion Protection

Secrets can be accidentally deleted. Enable deletion protection by setting a recovery window and considering resource-level policies that prevent deletion:

aws secretsmanager put-resource-policy   --secret-id prod/myapp/database   --resource-policy '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Principal":"*","Action":"secretsmanager:DeleteSecret","Resource":"*","Condition":{"StringNotEquals":{"aws:PrincipalArn":"arn:aws:iam::123456789012:role/SecurityAdmin"}}}]}'

Secrets Manager and Lambda Functions

Lambda functions benefit from a specific pattern: retrieve the secret once during initialization, cache it in the execution environment, and handle rotation by catching decryption errors and re-fetching. The AWS Lambda Powertools library provides a built-in secrets provider with caching and automatic refresh:

from aws_lambda_powertools.utilities.parameters import SecretsProvider

secrets_provider = SecretsProvider()

def handler(event, context):
    db_credentials = secrets_provider.get("prod/myapp/database", transform="json", max_age=300)
    # max_age caches for 5 minutes before re-fetching

See our Lambda security guide for the complete Lambda security context.

Compliance and Secrets Management

Most compliance frameworks (SOC 2, PCI DSS, HIPAA, ISO 27001) require evidence that secrets are not hardcoded in source code, are rotated periodically, and that access is logged and auditable. Secrets Manager provides all three:

  • CloudTrail logs every access — auditable evidence for access reviews
  • Automatic rotation satisfies periodic rotation requirements
  • No hardcoded credentials when your applications retrieve secrets via API

AWS Config provides a managed rule secretsmanager-rotation-enabled-check that verifies rotation is configured for all secrets, and secretsmanager-secret-periodic-rotation that verifies rotation has occurred recently. See our guides on SOC 2 and PCI DSS for compliance-specific guidance.

FAQ

Should I use Secrets Manager or Parameter Store?

Both store secrets, but they serve different use cases. Secrets Manager has automatic rotation, is purpose-built for credentials, and costs $0.40/secret/month. Systems Manager Parameter Store (SecureString tier) is cheaper for high-volume non-rotating configuration values. Use Secrets Manager for anything that rotates or is a credential; use Parameter Store for application configuration.

How do I audit which secrets are unused?

Secrets Manager tracks LastAccessedDate for each secret. Use the CLI to list secrets and check their last access dates: aws secretsmanager list-secrets --query 'SecretList[?LastAccessedDate<`2026-01-01`].[Name,LastAccessedDate]'. Unused secrets should be reviewed and potentially deleted.

Can Secrets Manager access be restricted by VPC?

Yes. You can create a VPC endpoint for Secrets Manager and use endpoint policies to restrict access to calls originating from within your VPC. This prevents secrets from being accessed by compromised credentials operating outside your network perimeter.

Protect your AWS accounts before it's too late

Vigilare monitors your AWS accounts for suspension risks — billing anomalies, IAM issues, GuardDuty findings, and more — and alerts you before AWS takes action.

Written by Vigilare Engineering

Platform Team