在一个 SaaS 系统里,“超级管理员”听起来像一个角色名称,实际上往往代表着一整套高风险能力的集合。它可能可以创建和删除租户、修改系统配置、管理管理员账户、查看审计日志、调整计费状态、操作 API 凭证,甚至通过运维工具间接接触数据库和对象存储。
麻烦也正是从这里开始。
如果一个账户同时拥有用户管理、租户管理、配置修改、数据访问、密钥管理和生产环境操作权限,那么它实际上已经成为整个 SaaS 平台的一个高价值控制点。一旦账户被盗,或者拥有权限的人发生误操作,影响范围可能从一个用户扩大到整个租户体系。
所以设计超级管理员时,首先应该改变一个思路:超级管理员不应该被理解成“所有权限全部打开的用户”,而应该被理解成一组需要受到额外约束的高风险管理能力。
超级管理员和租户管理员不是一回事
多租户 SaaS 最重要的安全边界之一,是 Tenant。
一个租户管理员通常只能管理自己的租户。例如,他可以创建本租户员工、修改本租户配置、查看本租户数据,却不应该因为拥有“管理员”角色就能够访问其他公司的数据。
超级管理员则可能需要跨租户执行平台级操作,例如暂停租户、处理计费异常、查看系统运行状态或者进行安全调查。
但“可以跨租户管理”不应该自动等于“可以读取所有租户业务数据”。
这是很多权限系统容易犯的错误。
开发人员建立一个 is_super_admin 字段,然后在代码里出现类似:
if ($user->is_super_admin) {
return true;
}
以后所有权限检查都绕过了。
这看似方便,实际上等于在整个应用里安装了一个统一的权限后门。以后任何开发人员只要在接口中忘记进一步检查资源归属,超级管理员就可能直接获得该资源的完整操作能力。
更合理的模型应该把身份、角色、数据范围和业务规则分开处理。
一个用户首先要证明“我是谁”,然后系统判断“我有什么权限”,接着判断“我可以访问哪些租户和资源”,最后还要判断“当前业务状态是否允许这个操作”。
超级管理员也不应该跳过这些层次。
RBAC 只是第一层,不是完整权限模型
SaaS 系统通常会采用 RBAC,也就是基于角色的访问控制。
例如可以设计:
Platform Admin
Tenant Admin
Security Auditor
Billing Admin
Support Admin
Read Only Admin
然后给角色分配具体权限:
tenant.read
tenant.suspend
user.create
user.disable
billing.read
billing.modify
audit.read
config.read
config.modify
api_key.revoke
这样做比简单设置一个“超级管理员”标志更加容易维护。
但 RBAC 解决的主要是“这个角色可以做什么”,并不能完整解决“这个角色可以对谁做”。
例如:
billing.modify
这个权限本身并没有说明管理员可以修改哪个租户的账单。
因此 SaaS 系统还需要 Data Scope,也就是数据访问范围。
例如:
Tenant A Admin
只能访问 Tenant A
Support Admin
可以访问被分配的租户
Platform Security Admin
可以访问安全事件和必要的审计数据
Billing Admin
可以访问计费相关数据,但不应该自动获得完整业务数据读取权限
这样才形成比较完整的权限体系。
最危险的情况是超级管理员直接绕过应用层
很多 SaaS 平台表面上拥有完善的 API 权限控制,但超级管理员在生产环境中却可以直接连接数据库。
从运维角度,这种能力有时候不可避免,但从安全架构角度,它已经属于另一条权限路径。
例如应用接口可能要求:
用户身份
租户 ID
角色
资源 ID
权限
业务状态
但管理员直接执行 SQL:
SELECT * FROM customers;
这些应用层检查全部不存在了。
所以必须区分“应用超级管理员”和“基础设施管理员”。
应用管理员负责平台功能,数据库管理员负责数据库基础设施,两者不应该因为工作方便就使用同一套长期有效的身份。
对于生产数据库访问,更合理的方式是采用独立的运维身份、短时授权、强认证、审计和审批机制。高权限访问应该成为一个可追踪的事件,而不是管理员日常工作的一部分。
多租户隔离不能依赖一个 WHERE 条件
很多 SaaS 应用的数据表都有:
tenant_id
然后查询:
SELECT *
FROM orders
WHERE tenant_id = ?
这是必要条件,但不能认为加了 tenant_id 就完成了租户隔离。
开发人员可能在另一个接口里写成:
SELECT *
FROM orders
WHERE id = ?
如果没有同时验证订单属于当前租户,攻击者或者错误的管理员权限就可能访问其他租户的数据。
因此资源授权应该发生在服务层,而不是只依赖调用者提交的 tenant_id。
例如:
认证身份
确定当前租户
检查角色和权限
加载资源
确认资源属于允许访问的数据范围
检查业务状态
执行操作
记录审计
数据库层还可以根据架构采用视图、存储过程、Row-Level Security 等机制增加第二道防线。对于高风险 SaaS,防御深度比依赖单一权限判断更加可靠。
高权限账户必须使用强认证
超级管理员账户应该强制启用 MFA。
这里的目的不是让 MFA 成为万能解决方案,而是降低单一密码泄露后的直接入侵风险。
对于高价值管理账户,可以考虑硬件安全密钥、平台认证器等抗钓鱼能力更强的认证方式。
同时还应该考虑会话本身。
例如:
较短的高权限 Session 生命周期
重新认证敏感操作
撤销异常 Session
限制管理后台登录来源
记录设备和登录信息
检测异常登录行为
特别需要注意的是,管理员登录 MFA 和管理员执行危险操作是两个不同的安全问题。
管理员已经登录,并不意味着可以点击一个按钮就永久删除租户、批量导出数据或者修改生产环境核心配置。
高风险操作应该增加第二道确认
删除租户、导出大量个人信息、修改身份认证策略、重置管理员 MFA、修改支付配置、撤销全部 API Key 等操作,都属于高风险行为。
对于这类操作,可以要求重新认证、二次确认、双人审批或者短时授权。
这比设置“每天最多修改三次配置”更加合理。
因为真正需要控制的是风险操作,而不是简单限制次数。
例如管理员一天可能需要修改几十次正常配置,但删除生产租户可能一年都不会发生一次。
因此应该针对操作本身建立风险等级:
普通读取
普通配置修改
敏感配置修改
凭证操作
批量数据操作
租户删除
身份和权限策略修改
风险越高,要求的认证和审批越严格。
Just-In-Time 权限比永久超级管理员更安全
对于偶尔才需要的高权限操作,可以采用 Just-In-Time,也就是按需授权。
管理员平时只有普通管理权限。
当需要执行生产环境高风险操作时,提交授权申请,系统经过审批后临时开放对应权限。操作完成或者授权时间到期后,权限自动撤销。
例如:
申请生产数据库访问
说明原因
指定目标资源
指定权限
指定有效时间
获得审批
临时获得访问能力
操作全部审计
授权自动失效
这种模式可以显著降低长期持有高权限凭证所产生的攻击面。
它的价值并不是让管理员“不能做事”,而是让高权限从一种永久状态变成一种有明确开始和结束时间的安全事件。
审计日志不能只是记录登录
一个成熟 SaaS 系统的审计日志至少应该能够回答几个问题:
谁做的?
什么时候做的?
从哪里做的?
操作了哪个租户?
操作了什么资源?
修改前是什么状态?
修改后是什么状态?
操作结果是什么?
如果是 API 调用,还应该记录调用来源、接口、请求标识等必要信息。
例如管理员修改某个租户的安全策略,审计记录应该能够追踪到具体用户、租户、资源和结果,而不是只留下:
Admin updated config
这种日志对于事故调查几乎没有价值。
同时也不能把完整密码、Access Token、API Secret 等敏感凭证直接写入日志。审计系统本身也是高价值数据源,需要进行访问控制、保留周期管理和防篡改设计。
API Key 和管理员权限尤其需要分开
SaaS 系统中的 API Key 是另一个容易被超级管理员滥用的地方。
管理员可能拥有创建、查看、撤销 API Key 的能力,但这不意味着系统应该允许管理员再次显示已经生成的完整 Secret。
更安全的设计通常是:
创建时显示一次
数据库只保存不可逆摘要或经过适当保护的凭证材料
后台只显示部分标识
支持撤销
支持轮换
记录创建者和使用范围
同时应该给 API Key 配置 scope,而不是让每一个 Key 都拥有完整 API 权限。
例如一个用于读取报表的 Key,不应该因为由超级管理员创建,就自动拥有删除用户和修改系统配置的能力。
支持人员不应该因为能解决问题就拥有所有数据
SaaS 公司经常会遇到一个现实问题:客户说“帮我看看这个账号为什么登录不了”,于是支持人员需要查看相关信息。
最简单的解决方案是直接给 Support Admin 全部数据读取权限。
长期来看,这会形成巨大的内部数据访问面。
更好的方式是建立专门的 Support 工具,只显示解决问题所需要的信息,并通过临时授权、数据脱敏和审计控制访问范围。
例如支持人员可能需要看到:
用户 ID
账号状态
登录时间
错误代码
安全策略状态
但没有必要看到完整身份证件、支付信息或者整个客户数据库。
这就是最小权限原则在 SaaS 运维中的实际应用。
权限系统还必须考虑业务状态
很多权限漏洞并不是角色设计错误,而是没有检查业务状态。
例如一个管理员拥有:
invoice.refund
并不意味着任何发票都可以退款。
系统还应该判断:
发票是否属于允许操作的租户
是否已经付款
是否已经退款
是否超过退款期限
当前管理员是否有足够的数据范围
是否需要审批
因此权限判断不能简单写成:
if ($user->can('invoice.refund')) {
refund($invoice);
}
更加完整的授权逻辑应该同时检查身份、权限、数据范围以及业务状态。
这也是为什么成熟 SaaS 的 Authorization 往往比一个简单的 RBAC 表复杂得多。
超级管理员账户还需要考虑紧急恢复
安全设计不能只考虑正常情况。
例如系统发生大规模故障,普通管理员权限无法恢复服务,这时候可能需要 Break-Glass,也就是紧急访问机制。
但紧急账户不能因为“紧急”两个字就变成永不过期的万能账户。
应该具备强认证、独立凭证、严格保管、使用审计以及事后复核等机制。
一旦启用紧急访问,系统应该能够明确记录什么时候启用、由谁启用、进行了什么操作以及什么时候结束。
这样既能够保留灾难恢复能力,也不会让紧急账户变成长期隐藏的超级后门。
真正需要控制的是权限的爆炸半径
设计超级管理员最重要的指标,不是“这个角色到底拥有多少权限”,而是“一个高权限账户出问题以后,影响范围有多大”。
如果一个账号被盗就可以读取所有租户的数据、修改所有身份策略、创建永久 API Key、访问生产数据库并删除全部数据,那么这个账户的 Blast Radius 就非常大。
如果权限被拆成多个角色,生产数据库访问采用独立身份,高风险操作需要重新认证,跨租户数据访问受到严格控制,管理员权限采用临时授权,同时所有关键操作都有审计,那么即使某个管理员账户被攻破,攻击者能够获得的能力也会明显受到限制。
这才是权限架构真正应该追求的结果。
SaaS 超级管理员不应该成为一个“万能账户”,而应该成为一组受到严格控制的高风险能力集合。RBAC 解决角色问题,Data Scope 解决资源范围问题,Tenant Isolation 解决多租户边界问题,MFA 和重新认证解决身份安全问题,Just-In-Time 授权解决高权限长期存在的问题,审计系统负责让高风险行为可以追踪,业务规则则负责阻止“拥有权限”被错误地理解成“任何时候都可以操作”。
当这些层次被拆开以后,管理员依然能够完成运维、客户支持、故障恢复和平台管理,但一次权限错误不再意味着整个 SaaS 平台都暴露在同一个按钮下面。这种设计虽然比一个 is_super_admin = 1 复杂得多,却也是多租户 SaaS 在进入生产环境以后必须面对的工程现实。
SaaS 系统中的超级管理员权限有多大?设计时应该避免哪些风险
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP