API Key Management on AWS: A Practical Guide
API key management on AWS usually means one of two things: storing and rotating secrets your applications use to call external services, or issuing and controlling keys for an API you expose yourself (via API Gateway). Both matter, and AWS gives you different native tools for each. This guide walks through the actual services involved, how to wire them together, and where AWS's built-in tooling stops being enough.
If you just need to answer "where do I put my API keys on AWS," the short answer is: AWS Secrets Manager for anything that needs automatic rotation, and AWS Systems Manager Parameter Store (SecureString) for simpler, lower-cost secret storage. If you're building your own API and need to hand out keys to callers, that's API Gateway API keys paired with usage plans. Below is how each fits together in practice.
Storing secrets: Secrets Manager vs Parameter Store
Both services encrypt values with KMS, but they solve slightly different problems.
AWS Secrets Manager
- Built-in rotation with Lambda rotation functions (native support for RDS, Redshift, DocumentDB; custom rotation for anything else)
- Fine-grained resource policies per secret
- Costs per secret per month plus API calls
Parameter Store (SecureString)
- Free for standard parameters, cheap for advanced ones
- No native rotation — you build it yourself with EventBridge + Lambda
- Simpler IAM model, good for config values that happen to be sensitive
A common pattern: use Secrets Manager for anything with credentials that expire or need rotation (database passwords, third-party API keys with revocation risk), and Parameter Store for static config and low-risk values.
# store a third-party API key
aws secretsmanager create-secret \
--name "prod/my-service/api-key" \
--secret-string '{"api_key":"sk_live_xxx"}'
# retrieve it at runtime (Node.js)
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
const client = new SecretsManagerClient({ region: "eu-west-1" });
const result = await client.send(
new GetSecretValueCommand({ SecretId: "prod/my-service/api-key" })
);
const { api_key } = JSON.parse(result.SecretString);
Never bake keys into environment variables committed to source control, container images, or CloudFormation templates. Reference the secret ARN and fetch it at boot or on-demand instead.
Least privilege with IAM
Whichever storage service you use, the key management problem is really an IAM problem: who can read, write, and rotate each secret. A tight policy looks like this:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": "arn:aws:secretsmanager:eu-west-1:123456789012:secret:prod/my-service/*"
}]
}
Scope by name prefix and environment, not a wildcard secretsmanager: on . Attach the policy to the specific execution role (Lambda, ECS task role, EC2 instance profile) that needs it — never to a broad user or a shared role used by multiple services.
Rotating keys without downtime
For AWS-managed rotation targets, Secrets Manager handles the create-new/test/promote/delete cycle automatically. For third-party API keys (Stripe, a data provider, an LLM vendor), write a custom rotation Lambda that:
- Calls the vendor's API to generate a new key
- Stores it as the pending version in Secrets Manager
- Updates the consuming service to test the new key
- Marks it current and schedules deletion of the old one
Set RotationRules with an interval that matches your risk tolerance — 30 or 90 days is typical for external API keys.
Issuing keys for your own API
If the goal is the reverse — you're exposing an API and need to hand out keys to callers — that's API Gateway API keys combined with usage plans:
aws apigateway create-api-key --name "customer-acme" --enabled
aws apigateway create-usage-plan \
--name "standard-tier" \
--throttle burstLimit=50,rateLimit=20 \
--quota limit=100000,period=MONTH
Usage plans let you throttle and meter per key without writing your own rate-limiter, and CloudWatch metrics give you request counts per key out of the box. This is the right tool when you control the API and need coarse-grained access control plus billing-adjacent metering.
Where AWS-native tooling stops helping
AWS gives you excellent primitives for storing secrets and for gating your own API, but it doesn't help with a specific case that comes up often for teams building on hosted AI models: you have a subscription (a Claude Pro/Max login, for example) rather than a pay-as-you-go vendor API key, and you want to call it from code with proper key issuance, streaming, and per-app usage tracking. Secrets Manager can store a raw token fine, but it won't turn a subscription into a scoped, revocable application key with usage metadata — that's a product problem, not a storage problem.
That's the gap SubToAPI fills: it converts your existing Claude access into a normal HTTPS API, with sub_live_... keys you generate per application, streaming and tool-use support, and usage stats per key in one dashboard. You'd still store the resulting sub_live_ key in Secrets Manager exactly like any other credential — SubToAPI handles issuing and scoping it, AWS handles storing and injecting it into your runtime. Getting a key takes a couple of minutes; see the quickstart or check pricing if you're evaluating it for a team.
Monitoring and auditing
Whatever storage layer you pick, wire up:
- CloudTrail for every
GetSecretValue,PutSecretValue, andCreateApiKeycall, shipped to a log group with retention set intentionally - CloudWatch alarms on unusual read volume for a given secret (a sign of a leaked credential being used)
- AWS Config rules to flag secrets without rotation enabled or IAM policies with overly broad
Resourcefields - Regular access reviews — quarterly is reasonable — to remove roles that no longer need a given secret
None of this is exotic, but skipping it is how a leaked key sits unused for months before anyone notices.
questions
Should I use Secrets Manager or Parameter Store for API keys? Use Secrets Manager if you need automatic rotation or fine-grained per-secret resource policies. Use Parameter Store SecureString for lower-cost, static secrets where you're comfortable rotating manually or via your own scheduled job.
How often should third-party API keys be rotated on AWS? 30–90 days is a reasonable default for external vendor keys, tightened to weekly or automated-on-every-use for anything highly sensitive. Automate it with a custom Lambda rotation function rather than relying on manual reminders.
Can API Gateway usage plans replace a full API key management system? For APIs you host yourself, usage plans cover throttling, quotas, and per-key metrics well. They don't help with keys for external services you consume — for that you still need Secrets Manager plus your own IAM policies.