AWS IAM attack path analysis — find privilege escalation chains before attackers do
Project description
sxaiam
Security eXplainable AI for IAM Attack Mapping
Detects privilege escalation paths in AWS IAM using graph analysis and explainable techniques.
The problem
AWS tells you what permissions exist. It doesn't tell you what an attacker can do with them in combination.
AWS Security Hub might flag that a user has iam:CreatePolicyVersion. What it won't tell you is that this user, chaining three permissions that look harmless in isolation, can reach AdministratorAccess in two steps. That gap is what sxaiam closes.
What makes sxaiam different
Most tools answer: Is this permission dangerous?
sxaiam answers:
- Can this principal become admin?
- Through which path?
- Why? Which permissions justify each step?
- Which techniques were used?
Every finding is backed by explicit IAM permission evidence — no black box, no guessing.
Demo
$ sxaiam scan --profile staging
sxaiam — IAM Attack Path Analysis
profile : staging
output : findings.json (json)
cutoff : 5 hops
1/4 Collecting IAM data from AWS...
✓ 12 users, 10 roles, 4 groups — account 123456789012
2/4 Resolving effective permissions...
✓ 22 identities resolved
3/4 Building attack graph and finding paths...
✓ 27 nodes, 10 edges — 9 escalation path(s) found
4/4 Exporting results (json)...
✓ Saved to findings.json
Escalation Paths Found:
[CRITICAL] low-priv-user → create-policy-version
[CRITICAL] readonly-user → attach-policy
[HIGH] developer-user → passrole-lambda
[HIGH] contractor-user → add-user-to-group
How it works
AWS account
│
▼ boto3 — read-only, agentless
│
Ingestion → get_account_authorization_details
│
Policy resolver → effective permissions per identity
│
Graph engine → networkx DiGraph (nodes: identities, edges: permissions)
│
Path finder → BFS from any identity to admin nodes
│
▼
JSON · Markdown · GraphML
Install
pip install sxaiam
Requires Python 3.10+ and AWS credentials with read-only IAM access.
Usage
Scan a full account:
sxaiam scan --profile my-aws-profile --output findings.json
Export as Markdown for pentest reports:
sxaiam scan --profile my-profile --format markdown --output report.md
Export the attack graph:
sxaiam scan --profile my-profile --format graphml --output graph.graphml
Compare against AWS Security Hub:
sxaiam compare findings.json --region us-east-1
Use as a Python library:
import boto3
from sxaiam.ingestion.client import IngestionClient
from sxaiam.resolver.engine import PolicyResolver
from sxaiam.graph.builder import AttackGraph
from sxaiam.graph.pathfinder import PathFinder
session = boto3.Session(profile_name="my-profile")
client = IngestionClient(session=session)
snapshot = client.collect()
resolver = PolicyResolver(snapshot)
resolved = resolver.resolve_all()
graph = AttackGraph()
G = graph.build(snapshot, list(resolved.values()))
finder = PathFinder(G)
paths = finder.find_all_paths()
for path in paths:
print(path.summary())
Escalation techniques covered
| Technique | Severity | Key permissions |
|---|---|---|
| CreatePolicyVersion swap | CRITICAL | iam:CreatePolicyVersion |
| AttachUserPolicy / AttachRolePolicy | CRITICAL | iam:AttachUserPolicy, iam:AttachRolePolicy |
| PassRole + Lambda execution | HIGH | iam:PassRole, lambda:CreateFunction |
| AssumeRole chaining | HIGH | sts:AssumeRole |
| CreateAccessKey credential takeover | HIGH | iam:CreateAccessKey |
| CreateLoginProfile console takeover | HIGH | iam:CreateLoginProfile |
| UpdateLoginProfile password reset | HIGH | iam:UpdateLoginProfile |
| SetDefaultPolicyVersion privilege swap | HIGH | iam:SetDefaultPolicyVersion |
| AddUserToGroup self-escalation | HIGH | iam:AddUserToGroup |
Why sxaiam vs existing tools
| Feature | sxaiam | PMapper | Cloudsplaining | Ermetic |
|---|---|---|---|---|
| Attack path chaining | ✅ | ✅ (basic) | ❌ | ✅ |
| Full evidence per finding | ✅ | ❌ | ❌ | ❌ |
| Offensive perspective | ✅ | partial | ❌ | ❌ |
| Security Hub comparison | ✅ | ❌ | ❌ | ❌ |
| Open source | ✅ | ✅ | ✅ | ❌ |
| Free | ✅ | ✅ | ✅ | ❌ |
| Active maintenance | ✅ | ❌ | partial | N/A |
IAM permissions required
sxaiam is read-only — it never modifies your account.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GetAccountAuthorizationDetails",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"organizations:ListPolicies",
"organizations:GetPolicy",
"sts:GetCallerIdentity",
"access-analyzer:ListFindings"
],
"Resource": "*"
}
]
}
Project structure
sxaiam/
sxaiam/
cli.py # CLI entry point (Typer)
ingestion/ # boto3 data collection
resolver/ # effective permissions calculator
graph/ # networkx graph builder + path finder
findings/ # escalation technique definitions
output/ # JSON / Markdown / GraphML exporters
tests/
unit/ # moto-based unit tests
integration/ # against the Terraform test environment
terraform/ # deliberately vulnerable IAM sandbox
docs/ # MkDocs documentation
Development setup
git clone https://github.com/sxaAspri/sxaIAM
cd sxaIAM
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
# Run tests (no AWS credentials needed)
pytest
# Lint + type check
ruff check sxaiam/
mypy sxaiam/
Documentation
Full documentation available at sxaAspri.github.io/sxaIAM.
Contributing
Contributions are welcome — especially new escalation techniques. See CONTRIBUTING.md for architecture principles and the PR process.
License
MIT — see LICENSE.
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sxaiam-0.1.0.tar.gz.
File metadata
- Download URL: sxaiam-0.1.0.tar.gz
- Upload date:
- Size: 695.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9d6e1b906a04f02db6fe5315614c52266baab39b6c6c4ebf1126052fd1e728a
|
|
| MD5 |
46aef7a3efddab0f14865f49254c2957
|
|
| BLAKE2b-256 |
34f4d00373529959dfeca8db5262192b61edcf16f58f3876d63845712fe2ad09
|
File details
Details for the file sxaiam-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sxaiam-0.1.0-py3-none-any.whl
- Upload date:
- Size: 52.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa265c40d1cd8aa849e1358a7f6b9321ebdf154df81ed8d23f2e018162c8369e
|
|
| MD5 |
a33caa68a70dab51d694cc3791904872
|
|
| BLAKE2b-256 |
62857298a87d51d2693648bc61c47af5e6774e8f98af36a6704c772113f72e49
|