Managing AWS Credentials for Backend Development
Learn how AWS credentials work, configure profiles, use SDK credential providers, deploy with IAM roles, rotate keys, and troubleshoot authentication and authorization failures.
AWS credentials are values or tokens used to authenticate requests to AWS. After AWS identifies the caller, IAM policies determine whether that identity is authorized to perform a requested action. Backend services use AWS identities to access services such as S3, DynamoDB, SQS, Secrets Manager, and CloudWatch.
Authentication and authorization
Authentication answers “Who is making this request?” AWS commonly answers this question by validating an access key, a session token, a federated sign-in, or credentials supplied by an IAM role.
Authorization answers “What is that identity allowed to do?” IAM policies grant or deny actions on resources. Finding valid credentials proves authentication, but it does not guarantee authorization.
AWS credential types
| Credential type | Contents | Expiration | Typical use | Recommended status |
|---|---|---|---|---|
| IAM user access keys | Access key ID and secret access key | Does not expire automatically | Legacy integrations or situations where a role is unavailable | Minimize; prefer temporary credentials |
| Temporary credentials | Access key ID, secret access key, session token, and expiration | Yes | STS role assumption, federation, and workforce sign-in | Preferred |
| IAM role credentials | Temporary credentials issued when a role is used | Yes | EC2, ECS, EKS, Lambda, and other AWS workloads | Preferred for workloads |
| AWS Identity Center or federated credentials | Developer sign-in session and temporary role credentials | Usually session-based | Human access across accounts | Preferred for developers |
| MFA-protected role sessions | Temporary role credentials obtained after MFA or an approved authentication flow | Yes | Sensitive administration and role assumption | Use for elevated access |
An access key ID is a public identifier paired with a secret access key. The secret access key signs requests and must remain confidential. Temporary credentials additionally require a session token; omitting that token commonly causes an invalid security token error. AWS STS, or Security Token Service, issues temporary credentials and supports role assumption.
An IAM user is a long-lived AWS identity. An IAM role is an assumable identity that normally provides temporary credentials. For human developers, use AWS Identity Center or federation where possible. For applications, use an IAM role rather than placing an IAM user's long-lived keys in source code or deployment settings.
The AWS shared credentials file
The default shared credentials file is ~/.aws/credentials, where ~ means the current operating-system user's home directory. It uses INI-style sections and key-value pairs. The default section is used when no named profile is selected.
[default]
aws_access_key_id = EXAMPLE_ACCESS_KEY_ID
aws_secret_access_key = EXAMPLE_SECRET_ACCESS_KEY
[development]
aws_access_key_id = EXAMPLE_DEVELOPMENT_KEY_ID
aws_secret_access_key = EXAMPLE_DEVELOPMENT_SECRET
These are placeholders only. Never replace them with real credentials in documentation, source control, or chat messages.
The shared config file is normally ~/.aws/config. It stores non-secret settings such as regions and output formats, and it can describe role assumption. In the credentials file, a named section is written as [development]. In the config file, the same profile is generally written as [profile development].
| File | Default location | Typical contents | Sensitive values allowed | Example settings |
|---|---|---|---|---|
| Shared credentials file | ~/.aws/credentials | Access keys, session tokens, and credential-related profile values | Yes, but protect the file | aws_access_key_id, aws_secret_access_key, aws_session_token |
| Shared config file | ~/.aws/config | Region, output format, SSO settings, and role configuration | Usually no secret values, but treat the file as sensitive if it contains session or account details | region = us-east-1, output = json, role_arn |
Check that the files are owned by the intended operating-system user. On Unix-like systems, restrict access to the owner:
chmod 700 ~/.aws
chmod 600 ~/.aws/credentials ~/.aws/config
On Windows, protect the corresponding files through the account's file permissions and ensure that the application runs as the expected user. A service started by another user, container, or system account may have a different home directory and therefore cannot see your personal ~/.aws/credentials.
Credential provider precedence
AWS SDKs and tools use a credential provider chain: an ordered set of sources checked to find credentials. Exact ordering can vary by SDK and version, but common sources include explicitly supplied credentials, environment variables, shared files and profiles, web identity credentials, container credentials, and EC2 instance or task roles.
| Credential source | Typical environment | How it is selected | Common conflict or risk |
|---|---|---|---|
| Explicit credentials in application configuration | Custom code or SDK client setup | The program directly receives credential values | Keys may be embedded in source, logs, or configuration; often overrides safer providers |
| Environment variables | Local shells, CI, and development containers | Variables such as AWS_ACCESS_KEY_ID are present | Stale variables can override the profile you expected |
| Shared credentials and config files | Developer workstations | Default or selected profile is loaded | Wrong profile, wrong home directory, or stale local credentials |
| Web identity federation | EKS and OIDC-enabled CI/CD | A web identity token and role ARN are supplied | Incorrect trust policy, token, or role ARN |
| Container credentials | ECS tasks and compatible container runtimes | The SDK queries the container credential endpoint | Missing task-role configuration or unintended endpoint access |
| Instance or workload role | EC2 and other AWS compute services | The SDK obtains credentials from the runtime role mechanism | No attached role, incorrect role, or overly broad permissions |
Do not assume which provider won. Verify the effective identity with STS and inspect the selected source with the CLI. A leftover AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY can cause a command to use different credentials even when AWS_PROFILE points to the expected profile.
Profiles and multi-account workflows
A profile is a named set of credential and configuration settings. Use separate profiles for development, staging, production-readonly, and other clearly defined access levels. Separating identities reduces the chance of running a destructive command against the wrong account.
aws configure --profile development
aws configure --profile production-readonly
aws configure list-profiles
Select a profile for one command:
aws sts get-caller-identity --profile development
Or select it for the current Unix-like shell session:
export AWS_PROFILE=development
aws sts get-caller-identity
Use the equivalent environment-variable syntax for your shell on other operating systems. For automation, prefer an explicit profile or a workload identity rather than relying on an inherited shell state.
Role assumption with a source profile
A source profile contains the initial approved identity. A role profile tells the AWS CLI or SDK to use that identity to obtain temporary credentials for a role in another account. This avoids maintaining separate long-lived keys for every account.
# ~/.aws/credentials
[development]
aws_access_key_id = EXAMPLE_SOURCE_ACCESS_KEY_ID
aws_secret_access_key = EXAMPLE_SOURCE_SECRET_ACCESS_KEY
# ~/.aws/config
[profile production-readonly]
role_arn = arn:aws:iam::123456789012:role/ReadOnlyRole
source_profile = development
region = us-east-1
output = json
aws sts get-caller-identity --profile production-readonly
The result should show the assumed role and the target account. In a mature setup, the source profile is often supplied by AWS Identity Center rather than a long-lived access key.
Using credentials with the AWS CLI
Interactive configuration prompts for an access key, secret access key, default region, and output format:
aws configure --profile development
Non-interactive setup can use environment variables, a supported federation tool, or a carefully protected credentials-file operation. Do not print secrets in shell history or CI logs. Region and output format are related configuration, not credentials or secrets.
aws configure list --profile development
aws sts get-caller-identity --profile development
aws s3 ls --profile development --region us-east-1
aws configure list helps reveal whether a value came from an environment variable, a profile, or another source. aws sts get-caller-identity shows the effective AWS account and caller identity without requiring access to an application resource.
Using credentials in backend applications
The safest general pattern is to let the AWS SDK use its default credential provider chain. For local development, select a profile without embedding keys in source code. For CI, use temporary environment-based or federated credentials. In AWS, use the role attached to the workload.
Local SDK profile selection
For example, an AWS SDK for JavaScript application can select a local profile during development. The profile name is configuration; the credential values remain outside the source tree.
import { S3Client } from "@aws-sdk/client-s3";
const s3 = new S3Client({
region: process.env.AWS_REGION || "us-east-1",
profile: process.env.AWS_PROFILE || "development"
});
SDK behavior and profile options differ by language and version. Consult the SDK's supported configuration for your language. In production, omit the local profile setting when the runtime role should be selected automatically.
Environment-based development and CI
export AWS_ACCESS_KEY_ID=EXAMPLE_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=EXAMPLE_SECRET_ACCESS_KEY
export AWS_SESSION_TOKEN=EXAMPLE_SESSION_TOKEN
export AWS_REGION=us-east-1
The session token is required when these are temporary credentials. Treat the shell environment, process listings, CI variables, build output, and debug logs as sensitive. CI/CD systems should preferably exchange an OIDC token for a temporary role through web identity federation instead of storing static keys.
Workload credentials
A backend may need access to an object bucket, queue, database API, secret, or logging service. Grant those actions to the workload role and allow the SDK to discover the role automatically. Do not copy a developer's credentials file into the application image.
- EC2 uses an attached IAM instance role.
- ECS uses an IAM task role, distinct from the task execution role used for platform operations.
- EKS can use IAM roles for service accounts, commonly through web identity federation.
- Lambda uses its execution role.
- CI/CD systems can use OIDC or workload identity federation to assume a deployment role.
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { SQSClient } from "@aws-sdk/client-sqs";
import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
const region = process.env.AWS_REGION || "us-east-1";
const dynamodb = new DynamoDBClient({ region });
const sqs = new SQSClient({ region });
const secrets = new SecretsManagerClient({ region });
// No access keys or credential file are included.
// The SDK resolves the attached workload role.
Credential security practices
- Never commit access key IDs, secret access keys, session tokens, or
~/.aws/credentialsto version control. - Treat local files, environment variables, CI variables, application configuration, logs, crash reports, and shell history as sensitive.
- Grant least privilege: only the actions and resources required by the identity should be allowed.
- Prefer short-lived credentials, IAM roles, AWS Identity Center, and federation over long-lived IAM user keys.
- Restrict ownership and permissions on local credential files.
- Use secret scanning in repositories and CI, and add local patterns to
.gitignore.
.aws/credentials
.env
.env.*
*.pem
A .gitignore rule prevents many accidental commits, but it is not a secret-management system. Review commits, logs, artifacts, and caches as part of an incident response process. Removing a key from the latest file does not make an already exposed key safe.
Rotation, revocation, and exposed keys
Access-key lifecycle management includes identifying owners, auditing age and last use, rotating active keys, and removing unused keys. A safe planned rotation sequence is:
- Create a replacement key or, preferably, migrate the consumer to an IAM role or federation.
- Update the consumer securely without exposing the new secret in logs.
- Verify the consumer's AWS identity and required operations.
- Deactivate the old key while monitoring for failures.
- Delete the old key after the transition is confirmed.
If a key is accidentally exposed, deactivate it immediately. Audit its usage and permissions, inspect affected resources and logs, remove it from repositories, logs, and configuration history where possible, and investigate related activity. If a role-based replacement is unavailable, create and deploy a replacement through an approved process, then continue the migration away from static keys.
Deployment credential patterns
| Runtime | Preferred AWS identity mechanism | Static key needed | Key implementation note |
|---|---|---|---|
| EC2 | IAM instance role | No | Attach a role with only the instance's required permissions. |
| ECS | IAM task role | No | Assign the application permissions to the task role, not to a copied credentials file. |
| EKS | IAM role for service account | No | Use web identity federation and a trust policy scoped to the service account. |
| Lambda | Lambda execution role | No | Grant only the functions' required service actions and resources. |
| CI/CD | OIDC or workload identity federation | No | Exchange the CI identity for temporary credentials and restrict the trust relationship. |
| Local development | AWS Identity Center, role assumption, or an approved named profile | Prefer no long-lived key | Use a profile setting outside source code and verify the account before changes. |
Troubleshooting credential failures
| Symptom | Likely cause | Verification step | Resolution |
|---|---|---|---|
| Unable to locate credentials | No profile or environment variables; a different OS user or home directory; no workload role | Run aws configure list and aws sts get-caller-identity; check the active home directory and runtime role | Configure an approved profile, select it explicitly, or attach the correct workload role |
| Wrong AWS account | Unexpected AWS_PROFILE, environment variables overriding a profile, or an incorrect default profile | Run aws sts get-caller-identity; inspect AWS_PROFILE, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY | Unset conflicts, select the required profile, and verify identity before destructive operations |
| Invalid security token | Typo, deactivated key, expired temporary credentials, or missing session token | Inspect the credential source and expiration; confirm AWS_SESSION_TOKEN exists for temporary credentials | Renew the session, re-assume the role, or rotate invalid credentials through the approved process |
| AccessDenied | The identity lacks permission, or a resource policy, boundary, service control policy, or explicit deny blocks it | Identify the caller with STS and review the action, resource ARN, account, region, and applicable policies | Grant narrowly scoped permission or correct the target; do not broadly expand access |
| CLI works but application fails | Different process, user, container, profile, SDK behavior, or explicit credentials overriding the chain | Log the non-secret provider type and region; compare application and shell environments | Use the SDK default chain, pass a profile only locally, and use workload roles in production |
A repeatable diagnostic sequence
- Run
aws sts get-caller-identityin the same shell and profile context as the failing command. - Run
aws configure listto inspect the selected source and region without displaying secret values. - Check for stale environment variables and cached federation or SSO sessions.
- Confirm the process user, home directory, selected profile, and AWS region.
- For a deployed service, confirm that the intended instance, task, service-account, or execution role is attached and trusted.
- Enable SDK logging only as needed, and ensure that secret values, authorization headers, and session tokens are not emitted.
- Separate authentication failures from authorization failures: first identify the caller, then investigate permissions and resource targeting.
Practical checklist
- Can you identify the effective caller with STS?
- Is the intended account and region selected?
- Is a stale environment variable overriding the intended profile?
- Does the identity have only the required permissions?
- Are temporary credentials and role-based access used wherever possible?
- Are credential files, environment variables, logs, and CI settings protected?
- Is there a documented rotation and exposed-key response procedure?
- Does the deployed backend use a workload role rather than static keys?
For a focused reference to the local file used by the AWS CLI and SDKs, see AWS shared credentials file.