内容
# 代理凭证
**为LLM代理提供的临时凭证代理,暴露在MCP上。**
[](https://deepwiki.com/ImAnonFR/ProxyCreds)
> 对代码库有疑问?在DeepWiki上提问,获取AI生成的文档和答案。
将长期有效的API密钥交给LLM代理是一个坏主意:密钥最终会出现在转录记录、日志和模型上下文中,一旦泄露就会一直有效,直到有人注意到并手动轮换它们。ProxyCreds将真实凭证存储在加密保险箱中,代理只获得**不透明、临时令牌**(`pcx_...`,默认10分钟TTL)。真正的秘密在服务器端最后可能的时刻被注入:
- **API密钥** — 代理调用注入网关(`/gw/<service>/...`),验证令牌,强制执行每个授权的方法/路径策略,注入真实密钥并将请求转发到上游。
- **代理凭证**(住宅/数据中心代理) — 代理将普通的HTTP代理客户端指向ProxyCreds中继;中继验证临时令牌并穿过真实的上游代理。
- **SSH访问** — 代理使用其令牌作为SSH密码连接到ProxyCreds堡垒;堡垒使用真实密钥/密码打开到目标主机的真实会话,并透明地桥接它。
如果令牌泄露,通常已经过期,可以一键撤销,并且除了通过ProxyCreds本身之外,在其他地方都无效。
```
LLM代理 ──MCP──> ProxyCreds ──> 加密保险箱(真实凭证从不离开)
│ │
│ pcx_token ├── 策略(代理 × 服务 × 范围 × TTL)
└──网络──> 网关/中继/堡垒 ──真实凭证注入──> 真实API/代理/主机
└── 审计日志(每个令牌事件和请求)
```
## 代码库布局
| 路径 | 描述 |
|---|---|
| `backend/` | FastAPI控制平面、注入网关、代理中继、SSH堡垒、MCP服务器(Python 3.12) |
| `dashboard/` | Next.js管理员仪表盘(服务、代理、策略、令牌、审计) |
| `docker-compose.yml` | 全栈:Postgres + 后端 + 仪表盘 |
## 快速开始(开发)
### 后端
```bash
cd backend
python -m venv .venv
.venv/Scripts/activate # Windows — 在Unix上使用bin/activate
pip install -r requirements.txt
uvicorn proxycreds.main:app --reload --port 8000
```
在开发过程中,您需要的一切都在第一次运行时创建:
- SQLite数据库(`backend/proxycreds.db`)
- 主密钥(`backend/.master_key`)用于封套加密
- SSH堡垒主机密钥(`backend/.bastion_host_key`)
代理中继(端口8080)和SSH堡垒(端口2222)在API启动时自动启动。所有三个生成的文件都被git忽略;对于生产环境,您需要提供自己的主密钥(参见下文)。
### 仪表盘
```bash
cd dashboard
npm install
npm run dev
```
打开http://localhost:3000,创建您的组织,然后:
1. **服务** — 添加凭证(例如GitHub PAT,带有上游基准URL `https://api.github.com` 和格式 `Bearer {secret}`)、上游代理或SSH目标。
2. **代理** — 创建代理密钥(`pca_...`,显示一次)。
3. **策略** — 授予代理对服务的访问权限,带有方法/路径范围和TTL。
4. **设置MCP** — 将生成的MCP配置复制到您的代理(`.cursor/mcp.json`,Claude Desktop配置等)。
### MCP服务器
```json
{
"mcpServers": {
"proxycreds": {
"command": "python",
"args": ["-m", "proxycreds.mcp_server"],
"env": {
"PYTHONPATH": "/path/to/ProxyCreds/backend",
"PROXYCREDS_API_URL": "http://localhost:8000",
"PROXYCREDS_AGENT_KEY": "pca_<your-agent-key>"
}
}
}
}
```
`PYTHONPATH`必须指向`backend`目录,以便模块解析。在Windows上,或任何带有虚拟环境的设置中,将`command`设置为虚拟环境Python(例如`C:\...\backend\.venv\Scripts\python.exe`),以便找到依赖项。在编辑配置后重启您的代理。
暴露给代理的工具:
| 工具 | 描述 |
|---|---|
| `list_services()` | 代理可以访问的服务(仅名称和策略,无密钥) |
| `request_access(service, reason)` | 获取临时`pcx_`令牌和用法说明 |
| `renew_token(token_id)` | 在令牌过期之前延长其有效期 |
| `release_token(token_id)` | 在使用完毕后撤销令牌 |
然后,代理调用例如`GET http://localhost:8000/gw/github/user`,带有`Authorization: Bearer pcx_...`,并在服务器端注入真实PAT。
### 不使用MCP(直接API)
MCP是可选的。相同的流程适用于纯HTTP API,因此人类、脚本和CI可以共享作用域访问权限,而无需看到真实凭证。有关API、代理和SSH服务的完整代理-API参考,请参见 **[README_API.md](./README_API.md)**,其中包含`curl`/Python示例。
## 全栈(Docker)
整个栈 — Postgres、后端(API + 网关 + 中继 + SSH堡垒)和仪表盘 — 通过单个命令启动:
```bash
docker compose up -d --build
```
然后打开http://localhost:3000。暴露的端口:
| 端口 | 服务 |
|---|---|
| 3000 | 仪表盘 |
| 8000 | API + 注入网关 |
| 8080 | 代理中继 |
| 2222 | SSH堡垒 |
在首次启动时,自动生成主密钥和SSH堡垒主机密钥,并存储在命名卷(`pc_keys`)中,以便容器重建后仍然存在。对于尝试或单主机部署,这很好。对于真正的生产环境,请设置自己的主密钥,以免仅在Docker卷中存储:
```bash
cp .env.example .env
# 生成密钥并粘贴到.env中作为PC_MASTER_KEY:
python -c "import base64,secrets;print(base64.b64encode(secrets.token_bytes(32)).decode())"
# 还要设置POSTGRES_PASSWORD、PC_*_PUBLIC_HOST / URL,然后:
docker compose up -d --build
```
为真正的部署添加一个TLS终止反向代理(Caddy、Traefik、nginx),并相应地设置`PC_GATEWAY_PUBLIC_URL`、`PC_RELAY_PUBLIC_HOST`和`PC_SSH_BASTION_PUBLIC_HOST`。
## 安全模型
- **封套加密** — 主密钥 → 每组织DEK(AES-256-GCM)→ 凭证密钥。密钥在内存中仅在注入时解密,之后立即丢弃。
- **不透明令牌** — `pcx_`令牌是256位随机数,存储哈希(SHA-256),绑定到代理 × 服务 × 授权,并且TTL上限(最大1小时)。
- **策略** — 允许的HTTP方法和路径通配符用于API,以及用于代理的目标主机允许列表;拒绝的请求被审计。
- **SSRF防护** — 解析为私有、环回或链路本地地址的上游被拒绝,在请求时重新检查以防御DNS重新绑定。
- **头部清理** — 代理提供的`Authorization`/`Cookie`头部在转发之前被剥离;`Set-Cookie`和身份验证头部从响应中被剥离。网关还可以编辑如果上游回显真实密钥。
- **终止开关** — 撤销单个令牌,禁用代理(撤销其所有令牌),或禁用服务。
- **审计** — 每个令牌颁发、续期、撤销、网关请求、中继连接、SSH会话和策略拒绝都被记录,不含密钥。
- **多租户** — 所有数据都按组织范围限定,带有每个组织的单独加密密钥。
### 已知限制
- 请求签名方案(AWS SigV4等)无法透明地代理;计划通过本地临时凭证(STS)支持它们。
- 速率限制在每个进程的内存中;将其移动到Redis以进行多副本部署。
## 测试
```bash
cd backend
python -m pytest tests -q
```
测试套件涵盖保险箱仅写入行为、令牌生命周期(颁发/续期/释放/撤销)、网关注入对抗模拟上游、策略强制执行(方法和路径)、SSH堡垒、审计日志和租户隔离。