Activepieces 企业版认证与授权指南:SAML SSO、联邦 OAuth、OTP 与项目级 RBAC 全解析
Activepieces 企业版认证与授权指南SAML SSO、联邦 OAuth、OTP 与项目级 RBAC 全解析【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces导读本文以 EE Authentication (SSO/RBAC) 为核心骨架系统梳理 Activepieces 企业版EE认证层如何在社区版CE之上叠加能力SAML 2.0 SSO、Google/GitHub 联邦 OAuth、OTP 邮件验证流、按项目的 RBAC 授权以及为嵌入场景设计的 Managed Auth JWT 交换。读完本文你将掌握各认证路径的完整调用链从 HTTP 入口到federatedAuthn汇聚点、OTP 原语的安全细节过期、重发、尝试计数、RBAC 的权限判定模型以及企业部署中最容易踩中的版本边界与坑。所有 SSO 路径最终都汇聚到authenticationService.federatedAuthn()它负责创建或关联用户身份并签发标准的 Activepieces JWT。一、EE 认证层总览模块与存储1.1 实体与服务划分EE 认证层由以下模块组成全部位于 packages/server/api/src/app/ee/authentication/模块职责saml-authn/SAML 2.0 服务提供方SP实现登录入口、ACS 回调、域名发现与验证federated-authn/Google 联邦 OAuth登录重定向与 code 交换otp/OTP 原语现位于 packages/server/api/src/app/authentication/otp/已迁出ee/见后文enterprise-local-authn/企业本地认证邮箱验证、密码重置project-role/RBAC 服务与中间件rbac-service.ts、rbac-middleware.tsee-authorization.ts计划plan与平台归属ownership相关的 preHandler 授权钩子managed-authn/Managed Auth面向 Embedding SDK 的 JWT 交换位于 packages/server/api/src/app/ee/managed-authn/1.2 配置存储platform.federatedAuthProvidersSSO 与联邦认证的配置统一存放在平台行platform row的federatedAuthProviders字段中典型结构如下{ saml: { entityId: https://idp.example.com/metadata, ssoUrl: https://idp.example.com/sso, certificate: -----BEGIN CERTIFICATE-----... }, google: { clientId: ...apps.googleusercontent.com, clientSecret: ... } }从源码看SAML 侧的服务在 authn-sso-saml-service.ts 中通过getSamlConfigOrThrow读取该字段且要求平台 ID 非空、SAML 配置存在否则分别抛出Platform ID is required for SAML authentication与SAML IDP metadata is not configured for this platform错误Google 侧的 clientId/clientSecret 则来自系统环境变量GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET见 federated-authn-service.ts 的getClientIdAndSecret。二、SAML 2.0 SSO2.1 完整流程SAML SSO 由 authn-sso-saml-controller.ts 暴露以下端点发起登录浏览器访问POST /v1/authn/saml/login服务端读取平台配置的 SAML provider构建 SP 客户端后返回 IdP 重定向地址302 redirect到 IdP。IdP 回传断言用户在 IdP 完成认证后IdP 以 POST 形式把 SAML 断言提交到 ACSAssertion Consumer Service端点POST /v1/authn/saml/acs。解析与汇聚服务端调用samlClient.parseAndValidateLoginResponse解析断言取出email / firstName / lastName然后调用authenticationService.federatedAuthn({ provider: UserIdentityProvider.SAML, predefinedPlatformId: platformId, ... })——创建/关联用户并签发 JWT。落地控制器把认证响应序列化后重定向到/authenticate前端路由即 packages/web/src/app/routes/authenticate/ 的 SAML ACS 回调落地页同时通过applicationEvents发送USER_SIGNED_UP事件source 标记为sso。该能力由platform.plan.ssoEnabled门控——前端 SSO 设置页也由LockedFeatureGuard键为ssoEnabled包裹未开启该计划的平台连设置入口都看不到。2.2 ACS 地址的多环境处理源码细节getAcsUrl的实现值得注意authn-sso-saml-service.ts非 Cloud 环境直接返回domainHelper.getPublicApiUrl({ path: /v1/authn/saml/acs })。Cloud 环境为兼容仍在使用自定义域名的企业客户优先用platformUtils.getLegacyHostByPlatformId返回旧主机名拼接 ACS 地址https://legacyHost/api/v1/authn/saml/acs没有 legacy host 时则返回{baseUrl}?platformIdplatformId把平台 ID 放进 query 参数供 ACS 回调识别。对应地ACS 端点在解析platformId时依次尝试query 参数中的platformId→ legacy host 反查 → 请求上下文推断platformUtils.getPlatformIdForRequest。2.3 域名发现Discover与域名验证为支持按邮箱域名自动跳转对应平台的 SSO服务还提供POST /v1/authn/saml/discover入参为域名服务端先按ssoDomain查平台再依次校验ssoDomainVerification.status VERIFIED、plan.ssoEnabled、hasSamlConfigured全部通过才返回{ platformId }否则返回{ platformId: null }见 authn-sso-saml-service.ts。POST /v1/authn/saml/sso-domain与POST /v1/authn/saml/sso-domain/verify前者设置 SSO 域名后者触发验证例如生成 TXT 记录供域名持有者配置。三、联邦 OAuthGoogle / GitHub联邦 OAuth 提供两条端点federated-authn-service.ts/v1/authn/federated/login返回 Google 的授权重定向 URLFederatedAuthnLoginResponse.loginUrl。/v1/authn/federated/claim携带授权码code可附带platformId发起交换服务端用 clientId/clientSecret 换取 idToken解析出email / firstName / lastName / imageUrl后同样调用federatedAuthn({ provider: UserIdentityProvider.GOOGLE, ... })签发 JWT。需要特别注意的是联邦 OAuth 的重定向地址固定使用FRONTEND_URL不支持自定义域名这是文档明确标注的边界。在 federated-authn-service.ts 中可以看到getThirdPartyRedirectUrl走的是domainHelper.getInternalUrl({ path: /redirect })。前端方面Google 登录已从早期的独立 OAuth 对话框简化为 SSO 页面上的googleAuthEnabled开关原sso/oauth2-dialog.tsx已删除第三方登录按钮与认证相关 hooks 位于 packages/web/src/features/authentication/。四、OTP 邮件验证流验证、重置与无密码登录OTPOne-Time Password是 EE 认证层最精细的部分也是历次决策记录反复打磨的对象。它由otpService.createAndSend/otpService.confirm两个核心方法驱动otp-service.ts。4.1 类型与过期时间OtpType枚举定义在 packages/core/shared/src/lib/ee/otp/otp-type.ts共三种export enum OtpType { EMAIL_VERIFICATION EMAIL_VERIFICATION, PASSWORD_RESET PASSWORD_RESET, EMAIL_LOGIN EMAIL_LOGIN, }每种类型在OTP_EXPIRATION_MSotp-service.ts中有独立的过期时长类型过期时间凭据形态EMAIL_VERIFICATION24 小时randomUUID()链接PASSWORD_RESET10 分钟randomUUID()链接EMAIL_LOGIN10 分钟6 位数字码用户手动输入状态机为PENDING / CONFIRMED模型 schema 见 packages/core/shared/src/lib/ee/otp/otp-model.ts数据库层对(identityId, type)有唯一约束即每个身份每种类型同时最多一行。4.2 重发语义复用旧值绝不延长寿命重发resend是此处最微妙的设计createAndSend发现已有PENDING且未过期的 OTP 时直接重新投递同一个既有值不触碰数据行。这意味着过期时间始终锚定在值的创建时刻重发无法延长一个可能已泄露的OTP 的生命周期只有当旧值过期或被消费后才会生成新值。这正是 GIT-1733 修复的问题旧实现的早退early-return让重发变成了静默的 204 空操作。设计考量记录于 000027 决策之所以不在重发时铸造新码是因为用户往往正读着第一封邮件里的码重新签发会让一半用户手里的码失效。4.3 尝试计数五猜即废原始 SQL 计数EMAIL_LOGIN的 6 位码只有 10^6 种组合暴力枚举的预算必须被显式封顶。OTP 行带有attempts计数器第 5 次错误猜测后凭据作废。计数用裸 SQL 完成UPDATE otp SET attempts attempts 1 WHERE id $1见 otp-service.ts原因有二TypeORM 的update会触碰updated列——而这正是过期与重发抑制检查读取的列一旦被刷新每次错误猜测反而会为攻击者多买 10 分钟窗口读-改-写式的自增在并发验证下可能写回相同值并行攻击下五猜预算将形同虚设原子自增保证了计数正确性。此外源码中还有一层按身份的预算MAX_ATTEMPTS_PER_IDENTITY 10配合IDENTITY_BUDGET_WINDOW_SECONDS 36001 小时窗口超出后confirm直接拒绝[otpService#confirm] identity guess budget exhausted。4.4 验证成功的清理删除行而非标记 CONFIRMEDconfirm成功后现在删除整行而非标记CONFIRMED。这同时是旧版 bug 的修复updated是updateDate列旧实现标记 CONFIRMED 会刷新它导致该身份在成功验证后 10 分钟内无法再次申请新码。OtpState.CONFIRMED目前没有任何写入方仅作为otpIsPending读取逻辑对历史遗留行的兼容判断保留。4.5 版本边界与两个关键坑坑 1CE 曾经有表无实。在无密码登录工作之前OTP 实体虽为所有版本注册但otpModule只在app.ts的 CLOUD 与 ENTERPRISE 分支注册且emailService.sendOtp在非付费版本上直接早退——CE 上表存在、迁移照跑却永远发不出任何邮件。EMAIL_LOGIN改变了这一点otpModule现在对 COMMUNITY 也注册EMAIL_LOGIN是唯一从付费版发送门禁中豁免的类型OTP 原语由此覆盖所有版本。但其上的登录流程并未跟随——000032 决策 把/otp/request、/otp/verify两条路由放进了仅在ApEdition.CLOUD且配置了 Turnstile 人机验证时注册的passwordlessAuthModule因此该豁免目前不可达CE 依然发不出任何码。两类链接型 OTP验证/重置仍是付费版专属。RBAC 基础类型属于 CESSO、Managed Auth、联邦 OAuth 为 EE/Cloud 专属。坑 2公共POST /v1/otp路由故意不能铸造登录码。该路由无认证、无rateLimit配置、也不套用任何注册防护因此其CreateOtpRequestBody把type收窄为EMAIL_VERIFICATION | PASSWORD_RESETEMAIL_LOGIN只能通过有速率限制且被门控的POST /v1/authentication/otp/request签发。若把枚举放宽回整个OtpType等于向任何人开放一个无节流的向任意地址投递可用登录码原语。坑 3验证时必须重断言平台认证策略。在 Cloud 上platformUtils.getPlatformIdForRequest对一切未认证请求返回 null因此请求作用域分支在 Cloud 从不执行平台只能在身份解析之后才可知。verifyCode因此会在解析出的平台上再次调用assertEmailAuthIsEnabledassertDomainIsAllowed这一对断言否则一个邮箱码就能把成员签入一个故意禁用了邮箱认证或移除了其域名的平台。之所以不在请求期断言是因为按地址回报这些错误会把请求端点变成存在性探测预言机existence oracle。坑 4一个常量身兼两职。TEN_MINUTES既充当confirm的新鲜度检查阈值又充当createAndSend中已有 OTP 则早退的重发抑制——在本次工作之前重发在凭据过期前根本不可能发生而请求端点仍返回 204。现在的重发会重新投递既有值且不触碰updated。坑 5email-service.ts对OtpType不穷举。frontendPath是一个只含两个成员的字面量对象却用整个联合类型索引——新增OtpType成员会直接编译失败其姊妹映射otpToTemplate类型为Recordstring, EmailTemplateData能通过类型检查却在运行时把undefined交给发送器。4.6 设计原则为何用打字的码而非魔法链接000027 决策 记录了关键背景Microsoft Safe Links、Mimecast、Proofpoint 等邮件安全网关会以 GET 预取邮件中的 URL且该行为与人工点击无法区分——一次性登录链接会被预取直接消费用户自己点击时凭据已过期。打字输入的 6 位码从根上绕开了这一类问题。五、企业本地认证邮箱验证与密码重置enterprise-local-authn/enterprise-local-authn/在 OTP 之上提供两个动作verifyEmail确认 OTP 后把身份标记为已验证resetPassword确认 OTP 后更新密码哈希。两者都属于 OTP 链接型EMAIL_VERIFICATION/PASSWORD_RESET并全程写入审计日志。对应的 DTO 与 ACL 类型定义在 packages/core/shared/src/lib/ee/authn/。六、项目级 RBAC权限模型与请求授权接线6.1 核心判定函数RBAC 的两个核心函数位于 rbac-service.tsassertPrinicpalAccessToProject({ principal, permission, projectId })注意源码中确实拼错了Prinicpal文档已注明按principal.type分派——UNKNOWN / WORKER / ONBOARDING一律拒绝USER取该用户在项目中的角色按角色 ID 与路由所需permission比对无权限则抛AUTHORIZATIONENGINE仅允许 principal 的projectId与目标一致SERVICE要求项目所属平台与 principal 的平台一致。assertUserHasPermissionToFlow({ principal, operationType, projectId })把FlowOperationType映射为Permission例如LOCK_AND_PUBLISH/CHANGE_STATUS映射为UPDATE_FLOW_STATUS再委托给上面的项目级断言同时该方法仅对CLOUD/ENTERPRISE版本生效CE 上直接放行。6.2 请求授权接线RBAC 被接入统一请求授权层assertPrinicpalAccessToProject在 packages/server/api/src/app/core/security/v2/authz/authorize.ts 中被调用覆盖每一个项目作用域的请求project-scoped request。同目录下的 authorization-middleware.ts 负责从请求解析项目 ID 并挂载中间件。6.3 三个授权钩子preHandleree-authorization.ts 导出三个 Fastify 钩子工厂钩子行为platformMustHaveFeatureEnabled(handler)读取请求 principal 的平台调用handler(platform)判定未开启时抛402FEATURE_DISABLEDprojectMustBeTeamType仅对 USER / SERVICE principal 生效要求项目为团队类型Team否则拒绝platformMustBeOwnedByCurrentUser校验user.platformRole PlatformRole.ADMIN且user.platformId platformIdAPI KeySERVICE 类型自动放行七、Managed Auth面向 Embedding 的 JWT 交换Managed Auth 是给 Embedding 场景使用的托管登录由宿主应用而非 Activepieces 前端完成身份认证后通过 managed-authn-controller.ts 与 managed-authn-service.ts 交换得到 Activepieces JWT。它由embeddingEnabled签名密钥独立门控与 SSO 的ssoEnabled互不干扰lib/external-token-extractor.ts负责从外部 token 中提取身份。前端对应实现位于 packages/web/src/features/authentication/ 的 managed auth client。八、认证速率限制默认保护零逐路由显式加入packages/server/api/src/app/core/security/rate-limit.ts 是本文档特别强调的一个安全要点rateLimitModule注册fastify/rate-limit时使用global: false——默认不保护任何路由因此每个会发送邮件或做认证工作的公共端点都必须通过config.rateLimit逐路由显式接入典型模式即authentication.controller.ts/otp-controller.ts中的API_RATE_LIMIT_AUTHN_*系列速率限制插件仅在API_RATE_LIMIT_AUTHN_ENABLED为真时注册key 使用真实客户端 IP支持CLIENT_REAL_IP_HEADER计数存储于 Redis预置的限流参数authnRateLimitAPI_RATE_LIMIT_AUTHN_MAX与API_RATE_LIMIT_AUTHN_WINDOW与emailCodeRateLimitAPI_RATE_LIMIT_EMAIL_CODE_MAX后者专门用于邮箱码端点。九、版本能力矩阵速查能力CECommunityEE / CloudRBAC 基础类型assertPrinicpalAccessToProject等✅✅OTP 原语模块注册、发送管线✅自无密码工作后✅邮箱验证 / 密码重置链接型 OTP❌✅无密码邮箱登录码EMAIL_LOGIN❌原语豁免但登录路由仅 CloudTurnstileCloud 限定SAML SSO、联邦 OAuth❌✅Managed Auth❌✅受embeddingEnabled门控十、关键文件索引EE 认证模块根packages/server/api/src/app/ee/authentication/——saml-authn/、federated-authn/、otp/现移至 packages/server/api/src/app/authentication/otp/、enterprise-local-authn/、project-role/、ee-authorization.tsRBAC 请求授权接线packages/server/api/src/app/core/security/v2/authz/Managed Authpackages/server/api/src/app/ee/managed-authn/共享企业认证导出 / DTOpackages/core/shared/src/lib/ee/authn/OTP 模型与枚举packages/core/shared/src/lib/ee/otp/前端认证 UIpackages/web/src/features/authentication/SSO 设置页 / SAML 对话框packages/web/src/app/routes/platform/security/sso/SAML ACS 落地页packages/web/src/app/routes/authenticate/认证速率限制packages/server/api/src/app/core/security/rate-limit.ts相关决策记录000027 邮箱登录码设计、000032 邮箱登录码仅限 Cloud 且需人机验证结语Activepieces 的 EE 认证层不是一个独立的第二套系统而是在 CE 认证原语上按版本叠加的模块化组合SAML 与联邦 OAuth 收敛到federatedAuthn单一入口OTP 用类型化码 过期锚定 尝试预算的精细化设计兼顾可用性与防爆破RBAC 通过authorize.ts统一接入每个项目作用域请求。部署企业版时请务必核对ssoEnabled/embeddingEnabled计划开关、SSO 域名验证状态、联邦 OAuth 的FRONTEND_URL约束以及每个公共认证端点的逐路由速率限制配置——这些正是该模块多年迭代沉淀下来的全部边界条件。【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考