AstronRPA 外部集成安全契约:MCP/REST 认证、授权矩阵与 n8n 安全接入实践

  • RPA
  • 工作流自动化
  • 低代码
  • 桌面应用
  • 后端
  • 前端
  • 企业应用

【免费下载链接】astron-rpa

Enterprise-grade desktop RPA client with a pluggable library of atomic capabilities, policy‑friendly packaging, and CI/CD‑friendly CLI. Integrates with leading Agent platforms and LLMs for end‑to‑end desktop/web automation. 这是一个镜像仓库,有issue、pr欢迎去github提交。

项目地址: https://gitcode.com/ifly_opensource/astron-rpa
点击查看 免费下载

导读

本文以 backend/openapi-service/EXTERNAL_INTEGRATION_SECURITY.md 为主体,系统讲解 AstronRPA 面向外部 Agent 平台与 LLM 的集成安全边界:外部调用如何通过 API Key 完成身份认证、每类入口点被强制执行哪些资源权限、工作流能力边界如何收敛、API Key 生命周期如何管理,以及 n8n 社区节点应如何安全接入。读完本文,你将掌握 AstronRPA 的信任边界模型、授权矩阵、密钥轮换流程与 HTTPS 部署验收清单,能够在生产环境中正确、安全地开放 RPA 工作流的对外执行能力。

一、集成安全契约总体概览

AstronRPA(OpenAPI 服务)对外暴露两类传输通道,均受同一安全契约约束:

  • MCP Streamable HTTP:主通道,承担工作流的发现(discovery)、执行(execution)与查询(query);
  • REST:辅助通道,是显式的兼容性接口(compatibility interface)。

两条通道共享相同的认证、授权与执行记录机制。契约中有两条铁律:

  1. 单传输原则:认证失败或启动响应不确定(uncertain start response)时,禁止在另一条传输通道上重试启动同一任务;
  2. 单一身份源:外部调用只能携带一种明确的凭据,绝不接受"先用 API Key 失败、再回退到桌面会话身份"的双重身份语义。

从源码看,这一契约的落点非常明确:

二、身份与信任边界(Identity and Trust Boundary)

2.1 凭据形态与校验规则

外部调用恰好使用以下两种凭据之一:

  • Authorization: Bearer <API_KEY>;
  • X-API-Key: <API_KEY>。

两条传输通道使用同一个活跃密钥查找(active-key lookup)与 bcrypt 校验逻辑。凭据解析规则在 extract_api_key() 中实现:

  • 重复或冲突的 Authorization 头(多个值)→ 直接拒绝;
  • 格式错误的 Bearer 头(非两段、非 Bearer 前缀、空值)→ 拒绝;
  • 重复的 X-API-Key 头 → 拒绝;
  • REST 请求的 ?key= URL 查询参数凭据 → 默认拒绝(allow_query_api_key=False);
  • 最终必须恰好得到一个凭据,多于或少于一个都会抛出 APIKeyAuthenticationError。

2.2 MCP URL Key 与迁移开关

MCP 通道的 URL 查询密钥默认关闭。配置项 MCP_ALLOW_QUERY_API_KEY=true 只是临时的、仅限 MCP 的迁移选项,不是生产环境推荐配置。理由在 app/config.py 的注释中写得很清楚:URL 查询串经常出现在浏览器历史与代理访问日志中,存在泄密风险。

认证存储故障(如数据库不可用)时统一返回 HTTP 503,且不泄露任何数据库细节(见 MCPAPIKeyAuthMiddleware:只记录异常类型名,不记录敏感异常文本)。

2.3 每次请求重新校验,无正向缓存

密钥在每一个请求上都重新校验,不存在"认证成功后缓存、吊销后仍存活"的正向认证缓存。这意味着:密钥被吊销后,即使请求发生在既有 HTTP 连接上,也会立即被拒绝。

2.4 桌面会话与网关身份剥离

桌面端的密钥管理、工作流发布走既有已认证的会话网关。OpenAPI 网关在认证前会剥离外来请求携带的 user_id、X-User-Id、user-info 请求头,只转发从既有 robot/auth 服务获得的身份。相关实现见 docker/volumes/nginx/lua/openapi_auth.lua:

ngx.req.clear_header("user_id")
ngx.req.clear_header("X-User-Id")
ngx.req.clear_header("user-info")

具体行为(见 gateway-routes.conf 与 app/dependencies/init.py):

  • 外部入口(/workflows/execute、/workflows/execute-async、/workflows/stop-current、/workflows/copy-workflow、/health/local-check、/health/remote-check、/executions/get、/executions/{id})→ 必须走 API Key 认证;
  • 混合入口(/workflows/get、/workflows/get/{project_id})→ 若携带 API Key 凭据,一律以 API Key 身份读取,凭据无效时绝不回退到会话身份;无凭据时保留设计器的既有视图;
  • 管理路由(密钥创建/列表/吊销、工作流 upsert、Astron 凭据管理等)→ 只接受桌面会话身份,API Key 不能访问管理路由,也不能冒充桌面 WebSocket 连接。

2.5 端口私密性与信任边界

OpenAPI 容器端口必须保持私有(docker-compose 中端口被注释,仅通过网关暴露,见 docker/docker-compose.yml)。robot-service 的内部发布请求仍须在受信任服务网络上断言 user_id。如果直接公网暴露该端口,或用一个"转发调用方身份头"的替代代理,都会击穿该信任边界。升级时必须同时升级 OpenAPI 应用与其网关策略。

2.6 用户级绑定与租户隔离

OpenAPI 的密钥、工作流与执行记录目前绑定到 user_id,而非已验证的租户上下文(tenant context)。OpenAPI 不实现第二套账户体系,会话认证只提供既有身份。因此:

  • 测试/生产环境、租户隔离应使用独立的身份与独立部署;
  • 共享部署要求同一用户在两个租户持有不同授权,不在本契约支持范围内;
  • 在请求数据里带上 tenant/user ID 并不构成授权。

三、当前授权矩阵(Current Authorization Matrix)

原文档给出的授权矩阵是理解整个安全模型的核心,完整继承如下:

入口点身份强制执行的资源权限
固定 MCP list/getAPI Key属主、外部访问已启用、有效已发布版本;固定工具要求精确的 projectId
动态 MCP discovery/callAPI Key相同属主/开放发布策略;启动时重新校验 discovery 期间解析到的版本
固定 MCP / REST startAPI Key授权项目/当前版本 + 已注册范围的准入(在创建记录/派发之前);仅限执行器;无委托的手机号身份
MCP execution get/cancel / REST execution list/getAPI Key执行属主与当前工作流属主、已启用外部访问、有效的已接受执行版本
带 API Key 的 REST workflow list/getAPI Key当前属主开放的、已发布的工作流;遗留示例别名仅可解析到该属主授权副本
密钥 create/list/revoke、工作流 upsert、Astron 凭据管理经私有网关的已认证桌面会话当前用户;API Key 不能铸造密钥或授予外部工作流访问权
/workflows/stop-currentAPI Key仅针对已认证用户自己的客户端;无调用方可选目标身份
/health/remote-checkAPI Key只报告该用户客户端的存在;不启动工作
/health/local-checkAPI Key比较一个诊断客户端身份;提供的比较值不授权访问
/users/register、/users/get-key、跨用户复制/委托启动已禁用历史共享令牌/手机号查询不能证明委托授权

3.1 拒绝行为与错误语义

  • 普通重新发布(republication)保留对已接受执行记录的访问;
  • 外部访问吊销、工作流删除或属主变更 → 拒绝访问(包括 REST 列表计数);API Key 吊销 → 拒绝请求;
  • 上述变更不会停止已经接受的(already accepted)任务;
  • 缺失资源与不可见资源具有等价的拒绝行为;
  • REST start 对不可用项目返回 404、对不允许的版本或执行模式返回 403;执行详情返回 404;工作流详情保留既有响应信封、资源不可用时无数据;
  • MCP 工具拒绝使用 isError/安全业务错误,而不是 HTTP 授权状态码。

这些规则在源码中的落实可参看 require_workflow_access()(属主、状态、版本三重校验,抛出 WORKFLOW_NOT_FOUND/VERSION_NOT_ALLOWED),以及 workflows.py 中的 _execution_http_error()(CLIENT_OFFLINE/CLIENT_CAPABILITY_UNCONFIRMED → 503,CLIENT_PROTOCOL_UNSUPPORTED → 409,其余按 404/403 映射)。

3.2 用户级权限边界

API Key 当前是用户级权限,没有 per-key 作用域(scopes)或过期时间字段。属主显式开启外部访问,即把该发布版本的执行权授予属主自己的密钥。需要特别强调的是:

  • 读取工作流元数据 ≠ 执行一个恰好做只读业务的工作流;
  • MCP 工具注解(tool annotations)与 n8n 节点过滤不能约束服务端授权。

四、工作流能力边界(Workflow Capability Boundaries)

外部集成不是"一张工作流全开放"。能力按以下矩阵分级准入:

能力集成要求
元数据读取已认证属主 + 允许的工作流;不作为连接测试来执行
只读业务工作流显式启用的发布版本、受控输入与外部凭据
外部写入独立评审过的工作流/身份;用原始稳定业务键恢复不确定启动
文件 / Office授权文件句柄、访问限制与生命周期策略;无任意本地路径
桌面 / UI授权执行器、会话就绪、真实停止确认
AI 自动调用允许的工具/输入 + 独立授权;模型输出不是授权
高风险/不可逆工作评审过的允许列表 + 人工审批或禁止自动调用

这些是准入要求(admission requirements),不是新实现的 per-key 能力作用域。管理员拥有的声明(declaration)会对已注册用户在固定 MCP、动态 MCP 与 REST 上施加额外准入检查。受支持的 JSON 与已声明秘密输入遵循 执行管理契约;文件与运行时对象仍不支持。运维人员只应发布其确实允许集成身份执行的工作流。

五、API Key 生命周期与迁移(Key Lifecycle and Migration)

5.1 创建与存储

通过已登录桌面设置创建密钥。只有创建响应会返回新的原始密钥;openapi_auth 只存储其哈希与 8 字符前缀。后续密钥列表返回掩码(如 prefix + "******************",见 api_key.py 服务层)。

原始密钥必须存放在调用方的凭据存储中(如 n8n Credentials),永远不要放进工作流 JSON、URL、源码或导出的示例里。实现上,密钥生成使用 secrets 随机 32 位大小写字母+数字,哈希使用 bcrypt(见 app/utils/api_key.py);校验时先按 8 字符前缀定位活跃记录,再执行 bcrypt 校验(见 validate_api_key())。该校验还会拒绝超过 72 字节的密钥,以避免 bcrypt 前缀截断造成的"长密钥前缀相同即通过"风险。

5.2 轮换流程(不启动任务)

  1. 为目标身份/环境创建新密钥;
  2. 用新 Credential 初始化 MCP,发现/读取授权工作流;
  3. 将调用方切换到新 Credential —— 空授权工作流列表是成功的认证结果,不是执行任务的理由;
  4. 通过属主会话吊销旧密钥;此后 MCP/REST 请求(包括既有 HTTP 连接上的请求)必须拒绝它。

保持新旧密钥重叠期短暂。若吊销前校验失败,保留旧 Credential 的同时修复配置。已吊销密钥不会由此流程重新激活:必要时再创建一个密钥。吊销阻止新请求,但不是执行取消;由于密钥没有自动过期,运维需自行安排轮换并显式吊销未使用/已泄露的密钥。

5.3 部署前需评审的兼容性变更

  • API Key 无法访问会话管理端点或认证 WebSocket;
  • 网关移除原始公共用户头与无效 Bearer 回退;
  • REST start 不能再选择禁用/未发布/其他版本、编辑器执行或其他用户的手机号;未知顶层执行字段被拒绝,业务输入请放入 params;
  • 遗留共享令牌手机号密钥供给与跨用户复制返回拒绝;请使用已认证密钥管理,委托执行不受支持;
  • 既有外部调用方在普通重新发布后仍可访问已接受的执行;吊销访问仍拒绝读取与取消——持有执行 ID 并不建立授权;
  • 遗留用户供给可能在历史用户记录中存过明文 default_api_key。此变更阻断该公共供给路径,但不重写既有数据库行或备份。请清点受影响密钥、轮换/吊销它们,并按部署的数据保留策略清除过时的明文副本;不执行自动破坏性数据迁移。

per-key 作用域、自动过期、共享租户授权与委托身份均不由本契约提供。

六、n8n 凭据与接入(n8n Credentials)

6.1 凭据字段契约

字段契约
MCP Endpoint部署提供的完整 HTTPS URL,包含其配置路径;不要猜测或丢弃路径段
API Key秘密凭据字段;标准 Bearer 头,绝不放进查询数据
ProtocolMCP 2025-11-25 over Streamable HTTP;无自动协议升级/回退

6.2 节点行为要求

使用正常的证书链/主机名校验。Loopback/tunnel 传输仅用于开发测试环境,不是 Community Node 的要求。AstronRPA 社区节点提供凭据 UI,且所有业务操作均通过 MCP 完成;其 n8n SDK 依赖被限制在独立节点包内。

连接测试可以初始化 MCP、发现工具并执行一次授权读取,但不得调用 execute/stop、使用 REST 回退启动或自动重试启动。需要区分以下失败类别:

  1. 无效/已吊销密钥;
  2. TLS/网络失败;
  3. 协议不匹配;
  4. discovery 服务失败;
  5. 已认证但无可见工作流。

n8n 工作流只保留一个凭据引用(Credential reference)。实例加密密钥、凭据共享与加密备份属于 n8n 管理员职责范围。

七、部署与验收(Deployment and Acceptance)

7.1 HTTPS 部署前提

遵循 HTTPS 部署指南。部署方提供并维护服务器、DNS、证书/私钥及续期;项目方提供应用配置、镜像与文档。共享开发者证书与 SSH 隧道都不是生产依赖。

7.2 Casdoor 初始化与轮换

Casdoor 在首次初始化时生成独立签名密钥与应用 Secret,并在重启后保留。部署同步命令只把所选应用的 Secret 与公共签名证书复制进被 Git 忽略的 .env。从早期公共 bootstrap 密钥初始化的部署需要显式密钥/Secret 轮换与默认账户审查——仅更新 JSON 或网关 TLS 证书无法完成该轮换。详见 HTTPS 指南的"认证初始化/轮换"章节。

7.3 升级与回滚流程

  • 升级前:备份部署配置,记录应用镜像与源码版本;保持客户端空闲;
  • 网关策略与应用一起部署,校验渲染后的 nginx 配置,只 reload 本项目网关;
  • 校验:登录、Secure cookie、WSS、MCP POST/SSE(需关闭缓冲——参见 gateway-routes.conf 中 MCP 位置的 proxy_buffering off);
  • 证书更换/续期后:重复信任/主机名校验,重连客户端/MCP 调用方;
  • 回滚:使用项目保存的配置/镜像回滚;不要改动主机级代理/证书配置或无关服务;回滚安全代码也会恢复其旧暴露面,回滚期间必须隔离外部访问。

7.4 桌面客户端与 Scheduler 传输

  • 桌面客户端须同步更新:其 Chromium 进程必须使用正常证书校验,移除历史全局证书错误旁路;
  • Scheduler 的 remote transport 持有已验证的 HTTPS/WSS 连接;捆绑的本地 router 通过 loopback 连接该 transport 并继续路由本地模块;
  • 不要将该二进制作为独立远程 TLS 客户端运行:其历史 transport 跳过证书校验;
  • 配置的公共 remote_addr 仍是部署 URL,无需 SSH 隧道;
  • 会话按配置的 origin 持久化在客户端工作目录的 .remote-cookies 下;只有该 origin 的既有会话从 .cookie.json 迁移;上游 cookie 不委托给二进制的临时 loopback 身份;
  • 登出清空新存储(跨重启生效);损坏的本地会话数据被丢弃且不记录其内容,因此仍可重新登录;损坏的新存储不会恢复旧遗留凭据;两个会话存储路径均被 Git 排除;
  • HTTP 与 WSS 请求不会携带会话凭据自动跟随重定向——请显式配置最终部署端点;
  • HTTPS 网关监听器为 Casdoor 会话 cookie 添加 Secure/HttpOnly(含网关的 Casdoor 代理路径);显式遗留 HTTP 监听器保留既有 cookie 行为。

7.5 WebSocket 管理器兼容性

OpenAPI 的 WebSocket 管理器将每条收到的消息绑定到自己的处理程序(包括缓冲的 busy/success 回复)。这是对捆绑 rpawebsocket 1.0.7 监听器的兼容性修复,保留既有线上协议,不实现服务重启后的持久执行恢复。

7.6 验收标准

单元/ASGI 测试与隔离的 OpenResty 测试不构成生产 TLS 验收。部署验收要求真实的 HTTPS/WSS:

  • 真实部署域名下的可信连接;
  • 错误/过期证书的拒绝;
  • 真实 n8n/桌面成功、业务失败、离线/busy 与超时/同 ID 续跑;
  • 脱敏检查(redaction checks);
  • 证书更换/恢复演练。

不可用条件记为 untested(未测试)。

7.7 日志与历史数据保护

  • 审查网关/服务/客户端日志与 n8n 历史中的凭据和内部错误数据;
  • 合法工作流结果可能包含业务机密:限制历史访问、保留与导出;
  • 受管执行(managed execution)以持久幂等性、对账与已确认取消扩展本安全契约,见 执行管理;
  • 取消使用与执行相同的执行属主、当前工作流属主/外部访问检查;
  • 遗留客户端保留 supportsCancel=false;吊销密钥仍不能取消正在运行的工作。

八、安全模型的源码级印证

本契约并非纸面文档,仓库中的实现与测试均可验证:

  • 认证:MCPAPIKeyAuthMiddleware 在每个 Streamable HTTP 请求进入 MCP SDK 前认证,失败统一 401(带 WWW-Authenticate: Bearer)或 503;REST 侧依赖 get_user_id_from_api_key 同样只接受头部凭据、绝不接受 URL key;
  • 授权:workflow_authorization.py 是固定/动态 MCP 与外部 REST 共享的资源策略,属主、状态、版本任一不满足即安全拒绝;
  • 网关剥离:openapi_auth.lua 在转发前清除 user_id/X-User-Id/user-info,并区分外部入口、混合入口与会话入口;
  • 测试验证:test_external_security.py 使用真实模型与 MCP/REST 路由构建跨传输安全用例(属主/他者/已吊销密钥、启用/禁用/未发布工作流、旧版本执行等),test_mcp_auth.py 覆盖 MCP 认证边界。

结语

AstronRPA 的外部集成安全契约围绕一条主线展开:外部调用永远只信任 API Key 这一种身份,且每个入口点都有明确的最小权限。无论是通过 MCP 还是 REST 接入,认证失败、启动不确定、凭据冲突都遵循"拒绝并保持原状"的保守语义,绝不跨传输重试、绝不回退身份。配合上述密钥轮换、能力分级与 HTTPS 验收流程,运维人员可以把 RPA 能力安全、可控地开放给 n8n 等 Agent 平台,同时避免"模型输出即授权""凭据进 URL""执行 ID 即访问权"等常见集成误区。

  • RPA
  • 工作流自动化
  • 低代码
  • 桌面应用
  • 后端
  • 前端
  • 企业应用

【免费下载链接】astron-rpa

Enterprise-grade desktop RPA client with a pluggable library of atomic capabilities, policy‑friendly packaging, and CI/CD‑friendly CLI. Integrates with leading Agent platforms and LLMs for end‑to‑end desktop/web automation. 这是一个镜像仓库,有issue、pr欢迎去github提交。

项目地址: https://gitcode.com/ifly_opensource/astron-rpa
点击查看 免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值