内容
# awsmux
**在整个舰队中并行运行一个 AWS CLI 命令:数百个账户,几秒钟,安全。**
[](LICENSE)



一次命令可扩展到每个账户和区域(默认100个并行工作线程,`--concurrency`可提高),身份验证后执行,结果合并到一个流中。不需要再使用shell循环,耗时数分钟才能遍历整个舰队。而且任何修改操作都会被审批边界阻止,即使具有管理员权限的AI代理也无法逾越。上面的demo是针对一个包含100个账户的沙盒环境进行的真实终端演示;您可以使用`make fleet-up`命令自行重现。
**而且它对代理的成本和速度有显著提升。在一个150会话、三臂基准测试(相同的Claude Opus 4.8代理,相同的提示,相同的100账户舰队)中,awsmux臂在每个单元格中都优于原始shell aws CLI臂:1.3倍至2.9倍的成本降低,2.3倍至5.4倍的加速,四个舰队规模的持平表现,以及高达7.4倍的输出令牌减少(成本和令牌差异均经过Holm调整,p < 0.05)。**
| 任务 | 舰队 | 每次运行的成本(cli vs awsmux) | 墙上时间 |
| --- | --- | --- | --- |
| 枚举所有VPC | 10个账户 | $0.090 vs $0.068(1.3倍) | 34秒 vs 13秒 |
| 枚举所有VPC | 50个账户 | $0.239 vs $0.120(2.0倍) | 84秒 vs 23秒 |
| 枚举所有VPC | 100个账户 | $0.274 vs $0.193(1.4倍) | 94秒 vs 41秒 |
| 查找开放的世界组 | 50个账户 | $0.229 vs $0.079(2.9倍) | 75秒 vs 14秒 |
| 查找开放的世界组 | 100个账户 | $0.152 vs $0.098(1.5倍) | 90秒 vs 17秒 |
完整设计、统计数据和注意事项:
[docs/BENCHMARK.md](docs/BENCHMARK.md)。
## 在100个账户上试用(无真实账户)
前提条件:Docker和aws CLI。
```sh
make fleet-up && source .tmp/fleet/env.sh
```
一个make目标启动一个固定的LocalStack容器,并提供一个虚构的100账户舰队(10个团队,生产和阶段,5个分片,3个区域),用于娱乐。真实的aws CLI与本地的真实模拟AWS对话,每个配置文件都是一个账户(另外还有一个植入的`admin-legacy`重复项,用于`--dedupe`捕获),您所做的更改确实持久。零凭证,零真实AWS,零风险。
```sh
./bin/awsmux targets --profiles 'payments-*' # 验证身份,每个账户
./bin/awsmux run --dedupe --format jsonl -- ec2 describe-vpcs --query 'Vpcs[].VpcId'
# 所有100个账户,几秒钟
./bin/awsmux run --profiles '*-prod-*' -- ec2 describe-security-groups \
--filters Name=ip-permission.cidr,Values=0.0.0.0/0 # 查找开放的世界组
./bin/awsmux plan --profiles payments-prod-1 -- ec2 revoke-security-group-ingress \
--group-name legacy-bastion --protocol tcp --port 22 --cidr 0.0.0.0/0
```
最后一个是破坏性的,因此它不会直接运行:您会获得一个不可变的计划,待批准。首先使用令牌批准,然后重新运行搜索;发现确实会消失,因为沙盒是一个真实的(模拟)AWS。尝试在批准和应用之间编辑计划文件,并观察哈希检查拒绝它。
`make e2e`烟雾测试相同的节拍端到端(发现和STS验证所有101个配置文件,重复数据删除,整个舰队的扫描,开放世界搜索,审批门槛和完整的计划/批准/应用往返);`make fleet-down`删除容器。
## 真实舰队
相同的命令,指向您自己的AWS设置,而不是沙盒环境。零配置;awsmux从您现有的共享配置文件(`~/.aws/config`)和共享凭证文件(`~/.aws/credentials`)中发现配置文件,遵循`AWS_CONFIG_FILE`和`AWS_SHARED_CREDENTIALS_FILE`。SSO,静态密钥和`credential_process`配置文件全部正常工作,因为awsmux始终通过aws CLI执行,并在运行任何操作之前使用STS验证每个身份:
```sh
awsmux doctor # 首次运行?验证aws CLI,文件,配置文件
awsmux targets --regions us-east-1,us-west-2
awsmux run --profiles 'prod-*' --exclude '*-sandbox' --format jsonl \
-- ec2 describe-instances --query 'Reservations[].Instances[].InstanceId'
awsmux plan -- ssm put-parameter --name /app/flag --value on --type String
awsmux approve plan-01k... # 打印一次性令牌,永不存储
awsmux apply plan-01k... --approval-token <token>
```
看不到您的配置文件?`awsmux doctor`显示了检查了哪些文件,每个文件贡献了多少配置文件,以及aws CLI和状态目录是否可用。`awsmux targets`报告了每个配置文件的来源(表模式中的`SOURCE`列,jsonl中的`source`字段:`config`,`credentials`或`both`)。
有用标志:`--concurrency`(默认100:舰队范围的扩展是重点;每个正在飞行的目标是一个aws CLI子进程),`--timeout 30s`,`--max-errors N`,
`--stop-on-access-denied`,`--dedupe`(折叠解析为相同账户,主体和区域的目标),`--output-dir`(每个目标一个结果文件),
`--interactive`(复选框目标选择器)。每次运行都会进入`awsmux history`,可以使用`awsmux replay`重新运行。
## 交给您的AI代理
两个命令,零配置:
```sh
go install github.com/0hardik1/awsmux@latest
claude mcp add --scope user awsmux -- awsmux mcp
```
无需配置。`awsmux mcp`通过stdio为代理提供接口,遵循模型上下文协议:无端口,无守护进程,无配置文件,无凭证。它发现与您的终端相同的配置文件(共享配置文件和凭证文件;SSO,静态密钥和`credential_process`全部直通),并在运行任何操作之前使用STS验证每个身份。它甚至在MCP客户端通过带有裸GUI PATH的终端启动时,定位aws CLI在已知安装位置。检查与`/mcp`在Claude Code内部的连接,然后询问代理“哪些AWS账户您可以看到?”(删除`--scope user`以仅为当前项目注册。无Go工具链?`git clone` + `make build`为您提供`./bin/awsmux`。)
**Claude Desktop**:设置 > 开发者 > 编辑配置,然后添加到
`claude_desktop_config.json`(GUI应用程序不读取您的shell PATH,
因此使用`which awsmux`的绝对路径):
```json
{
"mcpServers": {
"awsmux": { "command": "/absolute/path/to/awsmux", "args": ["mcp"] }
}
}
```
**其他MCP客户端**(Cursor,Windsurf,Zed,...):相同的形状
在所有地方,一个stdio服务器,命令`awsmux`和参数`["mcp"]`。
代理获得五个结构化工具(`list_aws_targets`,
`plan_aws_operation`,`execute_aws_plan`,`get_aws_execution`,
`cancel_aws_execution`)而不是原始shell,并且它自己使用它们:
一旦注册,就什么也不需要调用,您只需要询问
(“在prod中找到每个开放的安全组”),模型就会自动调用工具。
只读操作自由执行。其他操作返回一个计划:代理为您提供计划
ID,您在自己的终端中运行`awsmux approve <plan-id>`,然后
将一次性令牌粘贴回聊天中以供代理应用。
令牌绑定到计划的sha256哈希,因此代理无法修改
已批准的计划或执行它两次。
想观看代理以零爆炸半径击中边界吗?
注册沙盒舰队:启动`make fleet-up`后,将服务器指向
舰队的配置,通过环境变量(`.tmp/fleet/env.sh`中打印的值):
```sh
claude mcp add awsmux-fleet \
--env AWS_CONFIG_FILE=$PWD/.tmp/fleet/aws-config \
--env AWS_SHARED_CREDENTIALS_FILE=$PWD/.tmp/fleet/aws-credentials \
--env AWSMUX_HOME=$PWD/.tmp/fleet/home \
-- $PWD/bin/awsmux mcp
```
代理通过MCP获得100个账户的LocalStack舰队;让它破坏
它喜欢的任何东西。
表格顶部的成本和速度数字来自完全
这个设置。一个来自同一个基准测试的额外结果:当一个代理被给予
一个shell和MCP工具,它自己选择awsmux并保持几乎所有的余量。
## 安全模型
| 类别 | 示例 | 策略 |
| --- | --- | --- |
| `read_only` | describe-*,list-*,get-*,s3 ls | 自由运行 |
| `mutating` | create-*,put-*,update-*,s3 cp | `--yes`,交互式确认,或批准的计划 |
| `destructive` | delete-*,terminate-*,revoke-*,s3 rm | 永不 `--yes`;键入确认或计划/批准/应用 |
| `unknown` | 任何未识别的操作 | 被视为修改 |
动词约定存在时,awsmux会覆盖它:sts调用的铸造
凭证(assume-role*,assume-root,get-session-token,
get-federation-token)和
s3api操作,写入本地输出文件(get-object,
get-object-torrent,select-object-content)被归类为`mutating`
尽管它们的名称类似于读取。
CI和代理的稳定退出代码:0全部成功,1部分失败,
2选择/配置错误,3需要批准或拒绝,4被阈值停止。
## 03:00故事
扫描器页面:SSH在舰队的某个地方对世界开放。您的
代理在一项只读调用中扫描14个已验证的账户,找到
`sg-0a1b2c3d`在payments-prod中,并提出撤销。撤销是
具有破坏性的,因此引擎返回一个计划而不是运行它。您
在手机上查看计划:确切的命令,确切的账户,验证
主体,哈希。您批准,粘贴一个令牌,然后去睡觉
而修复程序在历史记录中附带哈希值。
您现在可以对一组假冒的账户重现这个确切的故事:
`make fleet-up`.
## 比较
| | awsmux | awsrun | aws-vault / granted / awsume |
| --- | --- | --- | --- |
| 跨账户执行舰队 | 是 | 是 | 否(凭证工具) |
| 每个目标的STS身份预检 | 是 | 否 | 不适用 |
| 风险分类 + 批准边界 | 是 | 仅提示 | 不适用 |
| 代理接口(MCP) | 是 | 否 | 否 |
| 100账户LocalStack测试舰队(`make fleet-up`) | 是 | 否 | 否 |
| 历史记录 + 重放 | 是 | 否 | 否 |
| 运行时 | 单个Go二进制文件 | Python + 插件 | Go / 变化 |
凭证工具是互补的;awsmux愉快地通过
他们管理的配置文件执行。
## 文档
- [架构](docs/ARCHITECTURE.md):引擎,计划边界,
执行器,测试舰队内部。
- [基准](docs/BENCHMARK.md):代理成本A/B方法和
表格上方的结果。
## 开发
```sh
make setup # git钩子 + 预热固定的linter
make build test lint # 或:go build ./... && go vet ./... && go test ./...
make fleet-up e2e # LocalStack舰队 + 端到端烟雾测试
make fleet-down clean
```
CI运行`go test`和`make build`在ubuntu和macos上,gofmt + go vet,
golangci-lint整个存储库,LocalStack端到端烟雾测试在ubuntu上,以及
PR标题的Conventional Commits检查(commit-msg钩子强制执行
相同的约定本地)。
顶部的demo GIF是针对LocalStack舰队的真实Ghostty会话,
使用[Kap](https://getkap.co)记录。
依赖项:stdlib plus cobra。路线图:组织感知发现
(`--ou` + 角色假设),策略包,Homebrew tap和发布
二进制文件。
在[Apache-2.0](LICENSE)下许可。