Aws
Portable collection of Cursor agent and Claude Code agent skills. Paste the repo URL into agent chat to install on any machine
npx -y skills add timi-ty/agent-forge --skill awsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Perform AWS operations via the CLI. Use when the user asks to manage AWS resources, services, infrastructure, or anything involving EC2, S3, Lambda, IAM, RDS, ECS, CloudFormation, Route53, CloudWatch, Lightsail, or other AWS services.
SKILL.md
14.5 KB, ~3.6k tokens by cl100k_base, as published. Nobody here has run it
AWS CLI Operations — Multi-Account
This skill manages multiple AWS accounts (static IAM keys and SAML SSO) with safe switching. An account registry at ~/.aws/account-registry.json tracks all configured accounts and which one is active.
CRITICAL: Every aws command MUST be prefixed with AWS_PROFILE=<profile> using the active profile from the registry. Shell env vars do not persist between tool calls.
Active Account Check (MANDATORY — run on EVERY invocation)
Before doing anything else, determine the active account and verify credentials:
python -c "
import json, pathlib
reg = json.loads(pathlib.Path.home().joinpath('.aws/account-registry.json').read_text())
acct = reg['accounts'][reg['active']]
print(f\"Active: {reg['active']} | {acct.get('description','')} | Account ID: {acct.get('account_id','unknown')} | Region: {acct.get('region','us-east-1')} | Auth: {acct['auth_method']}\")
print(f\"AWS_PROFILE={acct['aws_profile']}\")
"
Then verify credentials:
AWS_PROFILE=<profile> aws sts get-caller-identity --output json
- If creds work → show the banner to the user and proceed.
- If creds fail → run the Credential Refresh procedure for the account's
auth_method(see the Credential Refresh section).
If ~/.aws/account-registry.json does not exist → run First-Time Setup (the First-Time Setup section).
Account Management
List accounts
python -c "
import json, pathlib
reg = json.loads(pathlib.Path.home().joinpath('.aws/account-registry.json').read_text())
for name, acct in reg['accounts'].items():
marker = ' (active)' if name == reg['active'] else ''
print(f\" {name}{marker} — {acct.get('description','')} [{acct['auth_method']}]\")
"
Register a new account — static keys
- Ask the user for: friendly name, description, AWS profile name, region, access key ID, secret access key.
- Run
aws configure --profile <profile>(or write to~/.aws/credentialsdirectly). - Verify with
AWS_PROFILE=<profile> aws sts get-caller-identity. - Capture the account ID from the response.
- Add to registry:
python -c "
import json, pathlib
p = pathlib.Path.home() / '.aws/account-registry.json'
reg = json.loads(p.read_text())
reg['accounts']['<name>'] = {
'description': '<desc>',
'account_id': '<from_sts>',
'aws_profile': '<profile>',
'region': '<region>',
'auth_method': 'static_keys'
}
p.write_text(json.dumps(reg, indent=2))
print('Added.')
"
Register a new account — SAML SSO (saml2aws)
Prerequisites: saml2aws must be installed. Check with saml2aws --version. If missing, tell the user to install it: choco install saml2aws -y (Windows, elevated PowerShell) or brew install saml2aws (macOS). The agent cannot elevate privileges.
- Ask the user for: friendly name, description, SAML IDP URL, AWS profile name, IAM role ARN, region, session duration (default 3600).
- Create the storage state directory:
mkdir -p ~/.aws/saml2aws
- Configure saml2aws. Always use the Browser provider — programmatic providers (KeyCloak, Okta, etc.) cannot handle MFA flows:
saml2aws configure \
--idp-account=<name> \
--idp-provider=Browser \
--url="<idp_url>" \
--username="<user_email>" \
--profile=<aws_profile> \
--role="<role_arn>" \
--session-duration=<duration> \
--mfa=Auto \
--skip-prompt
- First login — this opens a Chromium browser for the user to complete login + MFA:
saml2aws login --idp-account=<name> --profile=<aws_profile> --download-browser-driver --skip-prompt
The --download-browser-driver flag auto-installs Playwright Chromium on first use. The browser opens for the user to authenticate (enter credentials, complete MFA, select role if needed). After successful auth, saml2aws captures the SAML assertion and writes temporary credentials to ~/.aws/credentials under the named profile.
- Verify:
AWS_PROFILE=<aws_profile> aws sts get-caller-identity. - Capture account ID and add to registry:
python -c "
import json, pathlib
p = pathlib.Path.home() / '.aws/account-registry.json'
reg = json.loads(p.read_text())
reg['accounts']['<name>'] = {
'description': '<desc>',
'account_id': '<from_sts>',
'aws_profile': '<aws_profile>',
'region': '<region>',
'auth_method': 'saml2aws',
'saml2aws_idp_account': '<name>',
'idp_url': '<url>',
'idp_provider': 'Browser',
'role_arn': '<role_arn>',
'session_duration': <duration>
}
p.write_text(json.dumps(reg, indent=2))
print('Added.')
"
Remove an account
Remove from registry only. Do NOT delete AWS profiles or credentials files.
python -c "
import json, pathlib
p = pathlib.Path.home() / '.aws/account-registry.json'
reg = json.loads(p.read_text())
if '<name>' == reg['active']:
print('ERROR: Cannot remove the active account. Switch first.')
else:
del reg['accounts']['<name>']
p.write_text(json.dumps(reg, indent=2))
print('Removed.')
"
Account Switching
When the user asks to switch accounts (e.g., "switch to dnn-dev", "use my personal account"):
- Verify the target account exists in the registry.
- Test credentials:
AWS_PROFILE=<target_profile> aws sts get-caller-identity. - If expired → run the Credential Refresh procedure for the account's
auth_method(see the Credential Refresh section). - Update registry:
python -c "
import json, pathlib
p = pathlib.Path.home() / '.aws/account-registry.json'
reg = json.loads(p.read_text())
reg['active'] = '<target_name>'
p.write_text(json.dumps(reg, indent=2))
print('Switched to <target_name>.')
"
- Confirm by running
AWS_PROFILE=<target_profile> aws sts get-caller-identity.
Safety Rules
Destructive operations require confirmation
Before running any of these, describe what will happen, state which account is affected, and ask the user to confirm:
terminate-instances,delete-*,remove-*,deregister-*drop,destroy,purge- Modifying security groups to open
0.0.0.0/0 - Deleting IAM users, roles, or policies
- Emptying or deleting S3 buckets
Cost-incurring operations require a warning
Before creating resources that cost money, state the expected cost impact and the target account:
- EC2 instances (mention instance type pricing)
- RDS instances, NAT Gateways, ELBs
- Data transfer, EBS volumes
- Example: "This will create a
t3.microinstance (~$8.50/month in us-east-1) on account personal (851725607183). Proceed?"
Cross-account safety
- Always include the active account name and ID in destructive/cost confirmations.
- If the user's request seems to target a different account than the active one (e.g., they mention "dev" resources but the active account is "personal"), warn them and ask if they want to switch first.
Never expose secrets
Do not print access keys, secret keys, passwords, or tokens. Use --query to filter them out, or redact them.
Credential Refresh
Principle: When credentials expire or fail, refresh them using the same method that was originally used to obtain them. This applies at invocation start (the mandatory Active Account Check) AND mid-operation if any aws command returns ExpiredTokenException, ExpiredToken, RequestExpired, or an InvalidIdentityToken error.
Refresh by auth method
Read the account's auth_method from the registry and follow the matching procedure:
saml2aws
Re-run the same login command used during initial registration — this opens the browser for the user to re-authenticate, exactly as they did the first time:
saml2aws login --idp-account=<saml2aws_idp_account> --profile=<aws_profile> --download-browser-driver --skip-prompt
After successful login, retry the command that failed. If saml2aws is not installed, tell the user to install it: choco install saml2aws -y (Windows, elevated PowerShell) or brew install saml2aws (macOS).
static_keys
Static IAM keys do not expire on a timer, but they can be rotated or revoked. When sts get-caller-identity fails for a static-keys account, re-run the same configuration command used during initial setup:
aws configure --profile <aws_profile> # or write to ~/.aws/credentials directly
Prompt the user to enter their new Access Key ID and Secret Access Key, then verify with AWS_PROFILE=<profile> aws sts get-caller-identity.
Mid-operation expiry
If any aws command fails with a credential-expiry error during a multi-step operation:
- Pause the operation.
- Run the refresh procedure for the active account's
auth_method(above). - Verify with
AWS_PROFILE=<profile> aws sts get-caller-identity. - Retry the failed command and continue the operation.
First-Time Setup
Auto-detected when ~/.aws/account-registry.json does not exist:
- Check if
~/.aws/credentialshas a[default]section. - If yes → run
aws sts get-caller-identityto get the account ID. - Create the registry:
python -c "
import json, pathlib
p = pathlib.Path.home() / '.aws/account-registry.json'
p.write_text(json.dumps({
'active': 'personal',
'accounts': {
'personal': {
'description': 'Personal AWS account',
'account_id': '<from_sts>',
'aws_profile': 'default',
'region': '<from aws configure get region>',
'auth_method': 'static_keys'
}
}
}, indent=2))
print('Registry created with personal account.')
"
- Ask if the user wants to add any SSO accounts.
Output and Filtering
Default output is JSON. Use --output table for human-readable display, or --query for JMESPath filtering:
AWS_PROFILE=<profile> aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId,State.Name,InstanceType]' --output table
Use --no-cli-pager when output is long and you want it inline.
Common Workflows
All commands below must be prefixed with AWS_PROFILE=<active_profile> from the registry.
EC2
# List running instances
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,PublicIpAddress,Tags[?Key==`Name`].Value|[0]]' --output table
# Launch instance (confirm cost + account first)
aws ec2 run-instances --image-id ami-xxxxx --instance-type t3.micro --key-name MyKey --security-group-ids sg-xxxxx --subnet-id subnet-xxxxx --count 1
# Stop / start / terminate (confirm destructive ops + account)
aws ec2 stop-instances --instance-ids i-xxxxx
aws ec2 start-instances --instance-ids i-xxxxx
aws ec2 terminate-instances --instance-ids i-xxxxx
S3
# List buckets
aws s3 ls
# Sync local directory to bucket
aws s3 sync ./local-dir s3://bucket-name/prefix
# Copy file
aws s3 cp file.txt s3://bucket-name/
# Presigned URL (1 hour)
aws s3 presign s3://bucket-name/file.txt --expires-in 3600
IAM
# List users
aws iam list-users --output table
# List attached policies for a user
aws iam list-attached-user-policies --user-name <username>
# Create a new role
aws iam create-role --role-name MyRole --assume-role-policy-document file://trust-policy.json
Lambda
# List functions
aws lambda list-functions --query 'Functions[*].[FunctionName,Runtime,LastModified]' --output table
# Invoke function
aws lambda invoke --function-name my-function --payload '{"key":"value"}' response.json
# Update function code
aws lambda update-function-code --function-name my-function --zip-file fileb://function.zip
CloudFormation
# List stacks
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE --output table
# Deploy stack
aws cloudformation deploy --template-file template.yaml --stack-name my-stack --capabilities CAPABILITY_IAM
# Delete stack (confirm first)
aws cloudformation delete-stack --stack-name my-stack
RDS
# List DB instances
aws rds describe-db-instances --query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBInstanceStatus,Endpoint.Address]' --output table
Route53
# List hosted zones
aws route53 list-hosted-zones --output table
# List records in a zone
aws route53 list-resource-record-sets --hosted-zone-id Z1234567890
CloudWatch
# List alarms
aws cloudwatch describe-alarms --state-value ALARM --output table
# Get metrics
aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name CPUUtilization --dimensions Name=InstanceId,Value=i-xxxxx --start-time 2024-01-01T00:00:00Z --end-time 2024-01-02T00:00:00Z --period 3600 --statistics Average
Lightsail
# List instances
aws lightsail get-instances --query 'instances[*].[name,state.name,publicIpAddress,blueprintId]' --output table
# Get instance details
aws lightsail get-instance --instance-name MyInstance
ECS
# List clusters
aws ecs list-clusters
# List services in a cluster
aws ecs list-services --cluster my-cluster
# Describe service
aws ecs describe-services --cluster my-cluster --services my-service
Secrets Manager
# List secrets
aws secretsmanager list-secrets --query 'SecretList[*].[Name,LastChangedDate]' --output table
# Get secret value (be careful with output)
aws secretsmanager get-secret-value --secret-id my-secret --query 'SecretString' --output text
Error Handling
| Error | Cause | Fix |
|---|---|---|
AccessDenied / UnauthorizedAccess | Missing IAM permission | Check policies via aws iam list-attached-user-policies or aws iam list-attached-role-policies |
ExpiredTokenException / ExpiredToken / RequestExpired / InvalidIdentityToken | Credentials expired | Run the Credential Refresh procedure for the account's auth_method (see the Credential Refresh section), then retry the command |
ThrottlingException | API rate limit hit | Wait and retry with exponential backoff |
ResourceNotFoundException | Resource doesn't exist or wrong region | Verify region with --region flag |
InvalidParameterValue | Bad input | Check AWS docs for the correct parameter format |
Multi-Region Operations
Use the region from the active account in the registry. For resources in other regions, pass --region:
AWS_PROFILE=<profile> aws ec2 describe-instances --region eu-west-1
For global services (IAM, Route53, CloudFront, S3 bucket creation), region doesn't matter.
Gives 0 of the 12 instructions most containers cloud skills give in ~3.6k tokens
Counted across 607 of the 657 authors here whose files we hold, read 2026-08-06
- run containers as a non-root userin 69 of 607, across 49 files
- use multi-stage buildsin 52 of 607, across 41 files
- use Promise.all for independent operationsin 47 of 607, across 13 files
- import directly instead of barrel filesin 46 of 607, across 12 files
- use ternary instead of AND for conditionalsin 45 of 607, across 12 files
- use Set or Map for O(1) lookupsin 42 of 607, across 10 files
- create a .dockerignore filein 41 of 607, across 31 files
- Read individual rule files for detailsin 39 of 607, across 9 files
- authenticate server actions like API routesin 35 of 607, across 7 files
- use next/dynamic for heavy componentsin 34 of 607, across 9 files
- use React.cache for per-request deduplicationin 34 of 607, across 10 files
- copy dependency files before source codein 34 of 607, across 21 files
Said here and by no other author read
- prefix every aws command with the active profile
- verify the active account and credentials on every invocation
- use the Browser provider for saml2aws configuration
- state the affected account before destructive operations
- state cost impact before creating billable resources
- warn the user if the request targets a different account
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.