JumpServer PAM 账号密码查询 API:Python 集成指南(account-secret 接口实战)
【免费下载链接】jumpserverJumpServer is an open-source Privileged Access Management (PAM) platform that provides DevOps and IT teams with on-demand and secure access to SSH, RDP, Kubernetes, Database and RemoteApp endpoints through a web browser.项目地址: https://gitcode.com/GitHub_Trending/ju/jumpserver
JumpServer 作为开源特权访问管理(PAM)平台,为运维和 IT 团队提供了统一的账号资产托管与安全审计能力。当外部业务系统需要获取托管资产的账号密码时,JumpServer 提供了 RESTful 的集成应用(Integration Application)接口。本文围绕 apps/accounts/demos/python/README.zh-hans.md 文档,结合 Python 示例代码 与仓库源码,完整讲解账号密码查询接口的请求方式、参数约定、签名认证原理、服务端校验逻辑与常见问题,读完即可编写出可安全接入 JumpServer 的 Python 客户端。
1. 接口概览
本 API 提供 PAM 资产账号密码查询服务,支持 RESTful 风格调用,并以 JSON 格式返回数据。它的本质是"集成应用"(Integration Application)能力的一部分:管理员先在 PAM 平台中创建应用并绑定账号,外部系统再凭应用的 Key 以 HTTP 签名方式换取指定资产的账号密码。
- 请求方式:
GET - 接口路径:
api/v1/accounts/integration-applications/account-secret/ - 返回格式:
application/json
1.1 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| asset | str | 是 | 资产名称 |
| account | str | 是 | 账号名称 |
1.2 响应示例
{ "id": "72b0b0aa-ad82-4182-a631-ae4865e8ae0e", "secret": "123456" }其中id为集成应用(即调用方)的 ID,secret为查询到的账号密码。
说明:响应中的
id对应调用方集成应用自身,而不是资产或账号 ID。这一行为由 application.py 中的Response(data={'id': request.user.id, 'secret': secret})决定。
2. 环境要求
官方 Python 示例的运行环境要求如下:
Python 3.11+requests==2.31.0httpsig==1.3.0
其中httpsig用于实现 HTTP 签名认证(HTTP Signature),requests负责发起 HTTP 请求。需要注意的是,setup.py中的python_requires='>=3.6'是 SDK 打包时的最低声明,而官方 Demo 面向 Python 3.11+ 验证,生产使用建议以 3.11+ 为准。
3. 运行示例:API Key 从哪来
3.1 在 PAM 中创建应用
Q: API Key 如何获取?
A: 您可以在PAM - 应用管理中创建应用,以生成KEY_ID和KEY_SECRET。
在 JumpServer 中,这个"应用"对应数据模型 IntegrationApplication,其核心字段包括:
name:应用名称,与组织组合后唯一(unique_together = [('name', 'org_id')]);secret:应用的密钥(即KEY_SECRET),加密存储(EncryptTextField);accounts:该应用可查询的账号集合(JSONManyToManyField),即权限边界——应用只能查询被授权绑定的账号;ip_group:允许调用来源的 IP 分组白名单;is_active:应用是否启用。
应用创建后,应用 ID 即为KEY_ID,secret即为KEY_SECRET。密钥可通过refresh_secret重新生成(见 application.py,random_string(36)生成 36 位随机串),刷新后旧密钥立即失效,客户端需同步更新。
3.2 快速运行官方 Demo
仓库提供了开箱即用的示例 demo.py,支持通过环境变量注入配置:
export API_URL="http://127.0.0.1:8080" export API_KEY_ID="72b0b0aa-ad82-4182-a631-ae4865e8ae0e" export API_KEY_SECRET="6fuSO7P1m4cj8SSlgaYdblOjNAmnxDVD7tr8" export ORG_ID="00000000-0000-0000-0000-000000000002" python demo.pyDemo 中提供的默认值仅为占位示例,实际使用时请替换为在应用管理中创建的真实凭据。运行时输出如下(查询资产ubuntu_docker的root账号):
# demo.py 核心调用 if __name__ == "__main__": client = APIClient() result = client.get_account_secret(asset="ubuntu_docker", account="root") print(result)4. 签名认证原理:HTTP Signature + HMAC-SHA256
该接口并不使用简单的 Token 或 Basic Auth,而是采用HTTP Signature(httpsig)签名方案。Demo 中认证对象的构建方式如下:
from httpsig.requests_auth import HTTPSignatureAuth self.auth = HTTPSignatureAuth( key_id=KEY_ID, secret=KEY_SECRET, algorithm='hmac-sha256', headers=['(request-target)', 'accept', 'date', 'x-jms-org'] )签名会覆盖以下请求要素,防止请求被篡改或重放:
(request-target):请求方法 + 路径(get /api/v1/accounts/integration-applications/account-secret/);accept:application/json;date:RFC 7231 格式的 GMT 时间戳;x-jms-org:组织 ID。
对应的请求头由 Demo 组装:
headers = { 'Accept': 'application/json', 'X-JMS-ORG': ORG_ID, 'Date': datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'), 'X-Source': 'jms-pam' }其中Date必须与签名时使用的date一致,格式为%a, %d %b %Y %H:%M:%S GMT(如Tue, 09 Sep 2026 02:41:38 GMT)。跳板机等中间层不会影响 httpsig 对(request-target)的规范化计算,因此无需额外处理。
此外,仓库还提供了更完整的封装 jms_pam/main.py:
SecretRequest:对asset/asset_id/account/account_id做参数校验;Secret:统一封装secret与错误描述desc,valid = not desc;JumpServerPAM:客户端门面,_get_auth()中签名头为['(request-target)', 'accept', 'date'],send()负责拼接 URL、发起请求并解析响应。
该模块可通过 setup.py 打包为jms-pam库(pip install .),供业务系统以库的方式集成。
5. 服务端校验逻辑与参数进阶
虽然 README 只列出了asset+account两个参数,但服务端实际支持四种参数的组合查询。序列化器定义位于 service.py:
class IntegrationAccountSecretSerializer(serializers.Serializer): asset = serializers.CharField(required=False, allow_blank=True) asset_id = serializers.UUIDField(required=False, allow_null=True) account = serializers.CharField(required=False, allow_blank=True) account_id = serializers.UUIDField(required=False, allow_null=True)- 提供
account_id时,必须唯一提供,且不能再传asset/asset_id/account; - 提供
account(账号名称)时,必须同时提供asset(资产名称)或asset_id(资产 ID)之一; account_id与asset_id不允许同时出现;- 至少需要提供
asset或asset_id之一,以及account或account_id之一。
服务端命中账号的查找逻辑见 application.py:优先按account_id精确匹配;否则按account名称,再叠加asset_id或asset__name过滤,最后统一叠加应用绑定的账号集合做权限过滤,返回distinct().first()。
请求处理主流程位于 application.py:
- 参数校验失败直接返回
400及{'error': serializer.errors}; - 以
request.user作为集成应用,调用service.get_account(**serializer.data)查询账号,查不到则抛出JMSException('Not found'); - 每次查询都会写入
IntegrationApplicationLog审计日志(记录远端 IP、服务名、账号与资产信息,见 audits),满足 PAM 审计要求; - 若系统配置了
SECURITY_DISABLE_VIEW_SECRET(禁止查看密码),则secret字段返回None——即使查询成功也不返回明文密码。
鉴权方面,get_account_secret使用RBACPermission,要求调用方拥有accounts.view_integrationapplication权限;应用模型 is_valid / is_authenticated 直接与is_active绑定,即应用被停用后接口立即拒绝服务。
6. 完整可运行示例
以下代码综合 README 参数表与仓库实现,形成最小可运行客户端(可与demo.py对比使用):
import os import requests from datetime import datetime from httpsig.requests_auth import HTTPSignatureAuth API_URL = os.getenv("API_URL", "http://127.0.0.1:8080") KEY_ID = os.getenv("API_KEY_ID", "") KEY_SECRET = os.getenv("API_KEY_SECRET", "") ORG_ID = os.getenv("ORG_ID", "00000000-0000-0000-0000-000000000002") class APIClient: def __init__(self): self.session = requests.Session() self.auth = HTTPSignatureAuth( key_id=KEY_ID, secret=KEY_SECRET, algorithm='hmac-sha256', headers=['(request-target)', 'accept', 'date', 'x-jms-org'] ) def get_account_secret(self, asset, account): url = f"{API_URL}/api/v1/accounts/integration-applications/account-secret/" headers = { 'Accept': 'application/json', 'X-JMS-ORG': ORG_ID, 'Date': datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'), 'X-Source': 'jms-pam' } params = {"asset": asset, "account": account} response = self.session.get( url, auth=self.auth, headers=headers, params=params, timeout=10 ) response.raise_for_status() return response.json() if __name__ == "__main__": client = APIClient() print(client.get_account_secret(asset="ubuntu_docker", account="root"))调用时替换API_URL、KEY_ID、KEY_SECRET为真实环境值;若查询的是组织内的资产,务必让ORG_ID与X-JMS-ORG保持一致,否则服务端会在签名校验阶段因x-jms-org不一致而拒绝请求。
7. 常见问题(FAQ)与排查指引
- Q: API Key 如何获取?A: 在 PAM - 应用管理中创建应用,生成
KEY_ID与KEY_SECRET;创建后可在应用详情中查看一次性 Secret,也可通过刷新接口重新生成。 - Q: 返回 401/签名失败?检查三处:
KEY_SECRET是否与应用当前 Secret 一致(刷新过则需同步);Date头是否为 GMT 格式且与签名时一致;X-JMS-ORG是否与签名头列表中的x-jms-org匹配。 - Q: 返回 "Account not found"?确认账号名/资产名拼写正确,且该账号已被授权绑定到集成应用(
accounts字段);跨组织查询需使用正确的ORG_ID。 - Q: 返回 200 但
secret为 null?这是服务端开启了SECURITY_DISABLE_VIEW_SECRET的安全配置,属于预期行为,需由管理员评估后调整。 - Q: 请求来源被拒绝?应用配置了
ip_group白名单,请确认发起请求的出口 IP 在允许范围内,且应用处于is_active启用状态。
8. 版本历史
| 版本号 | 变更内容 | 日期 |
|---|---|---|
| 1.0.0 | 初始版本 | 2025-02-11 |
延伸阅读
- 官方 Python 示例:demo.py 与 jms_pam/main.py
- 服务端视图实现:application.py
- 集成应用模型:application.py
- 参数序列化器:service.py
- 路由注册:urls.py
- 同接口的 curl / Go / Java / Node 实现见 apps/accounts/demos 目录,便于对照迁移
【免费下载链接】jumpserverJumpServer is an open-source Privileged Access Management (PAM) platform that provides DevOps and IT teams with on-demand and secure access to SSH, RDP, Kubernetes, Database and RemoteApp endpoints through a web browser.项目地址: https://gitcode.com/GitHub_Trending/ju/jumpserver
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考