开发
组织、团队与文件夹权限
把一家工作室的人、团队和空间放在一起:按团队给空间授权,限制谁能改某个文件夹,用公司的身份提供方登录,导出审计记录。
组织(organization)装着一家公司的人和它的团队。一个空间可以属于一个组织,之后组织的团队就能在空间里有角色:有人加入剪辑组,就一次性拿到剪辑组在所有项目里的权限,离开时也一起收回。不属于组织的空间和以前完全一样。
| 组织角色 | 能做什么 |
|---|---|
owner(所有者) | 管理员能做的都能做,另外能任命所有者、设置单点登录。最后一个所有者不能离开。 |
admin(管理员) | 加人、移人、建团队,把自己管理的空间放进组织,导出审计记录。 |
member(成员) | 查看组织的成员、团队和自己所在的空间。 |
成员和团队
sidespace org create "Harbor Pictures"
sidespace org members "Harbor Pictures" --add [email protected] --role admin
sidespace team create "Harbor Pictures" 剪辑组
sidespace team add "Harbor Pictures" 剪辑组 [email protected] [email protected]
sidespace org attach "Film A" "Harbor Pictures" # 你管理 Film A,并且是组织管理员
sidespace team grant "Film A" 剪辑组 editorcurl -X POST "https://side.example.com/v1/orgs" -H "Authorization: Bearer $SIDESPACE_TOKEN" \
-H "Content-Type: application/json" -d '{"name": "Harbor Pictures"}'
curl -X POST "https://side.example.com/v1/orgs/$ORG/teams" -H "Authorization: Bearer $SIDESPACE_TOKEN" \
-H "Content-Type: application/json" -d '{"name": "剪辑组"}'
curl -X POST "https://side.example.com/v1/orgs/$ORG/teams/$TEAM/members" -H "Authorization: Bearer $SIDESPACE_TOKEN" \
-H "Content-Type: application/json" -d '{"email": "[email protected]"}'
curl -X PUT "https://side.example.com/v1/spaces/$SPACE/org" -H "Authorization: Bearer $SIDESPACE_TOKEN" \
-H "Content-Type: application/json" -d '{"org_id": "'"$ORG"'"}'
curl -X PUT "https://side.example.com/v1/spaces/$SPACE/teams/$TEAM" -H "Authorization: Bearer $SIDESPACE_TOKEN" \
-H "Content-Type: application/json" -d '{"role": "editor"}'把人加进团队时,如果他还不在组织里,会以成员身份加入。新建组织只能由人来做(令牌需要 admin 权限范围);给团队空间角色要空间管理员(令牌需要 members:manage)。
成员在空间里的角色
一个人在空间里的角色,取他自己的授权和他所在团队在这个空间的角色中最高的那个。GET /v1/spaces/{sid}/members 三样都给出:
{ "user": { "email": "[email protected]" }, "role": "editor", "direct_role": "viewer",
"teams": [{ "id": "team_…", "name": "剪辑组", "role": "editor" }] }只通过团队进入空间的人,direct_role 是 null。加入或离开团队,角色立刻跟着变。如果某人还通过团队有权限,从空间移除他会被拒绝(409,并说明是哪个团队),因为“移除”就该是真的不在了:先把他移出团队,或取消团队的角色。
文件夹权限
文件夹可以有规则,限制或放宽在里面能改什么。规则从不限制能看到什么。
default_role:没有单独授权的人在里面最多能做什么(viewer、commenter或editor;null表示按各自在空间里的角色)。grants:给空间成员(按邮箱)或组织的团队(按名字)单独的角色,可以高于他们在空间里的角色。比如让查看者能往某个交付文件夹上传。- 离得最近的、有规则的文件夹说了算。上下层的规则不叠加,所以一个文件夹的规则在一个地方就能看清。
- 空间管理员不受限制,没人能把空间所有者锁在外面。
# 剪辑室能看 /final,只有交付组能改
sidespace access "Film A" /final --default viewer --grant team:交付组=editor
sidespace access "Film A" /final # 你在那里是什么角色,由哪个文件夹决定
sidespace access "Film A" --list # 所有有规则的文件夹
sidespace access "Film A" /final --clearcurl -X PUT "https://side.example.com/v1/spaces/$SPACE/nodes/$FOLDER/access" \
-H "Authorization: Bearer $SIDESPACE_TOKEN" -H "Content-Type: application/json" \
-d '{"default_role": "viewer", "grants": [{"kind": "team", "name": "交付组", "role": "editor"}]}'每次写入都按所在位置检查角色:新建(看父文件夹)、保存新版本、改名和移动(看原位置和新的父文件夹)、删除、恢复、附加信息、预览文件、评论(评论者)、分享链接和 AI 运行。被拒绝的写入返回 403,消息里写明这个文件夹需要什么角色。GET /v1/spaces/{sid}/nodes/{nid}/access 返回你在那里的 role、你的 space_role 和决定它的规则(governed_by),应用可以在别人动手之前就说清楚;网页版会在这种文件夹上显示“这里你是查看者”,并收起你做不了的操作。
单点登录
组织可以通过 OpenID Connect 让成员用公司的身份提供方登录:Okta、Microsoft Entra ID、Google Workspace、Keycloak、Authing,以及任何提供 /.well-known/openid-configuration 的服务。所有者设置,管理员可以查看。
- 在身份提供方登记回调地址。
GET /v1/orgs/{oid}/sso会给出它;还没设置单点登录时,它返回的404里也写着。 - 为每个邮箱域名添加 DNS TXT 记录
_sidespace.<域名>,值是同一个调用给出的domain_proof(sidespace-verify=…),证明域名是你们的。否则谁都能声称gmail.com。 - 为这些域名接入身份提供方:
sidespace org sso "Harbor Pictures" --issuer https://harbor.okta.com --client-id 0oa… \
--client-secret - --domain harbor.example --required < secret.txt
sidespace org sso "Harbor Pictures" # 查看(不会显示密钥)
sidespace org sso "Harbor Pictures" --offcurl -X PUT "https://side.example.com/v1/orgs/$ORG/sso" -H "Authorization: Bearer $SIDESPACE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"issuer": "https://harbor.okta.com", "client_id": "0oa…", "client_secret": "…", "domains": ["harbor.example"], "required": true}'没有 TXT 记录的域名会被拒绝(422,code 为 domain_unproven)。Client secret 用服务器的密钥封存,从不返回;之后再 PUT 时不传它就保持不变。开启 required 后,这些域名不能再用邮箱验证码登录。通过单点登录进来的人会以成员身份加入组织。
在应用里登录
应用不接触身份提供方的令牌。用对方的邮箱开始登录,在浏览器里打开返回的 url,再用 handle 轮询,直到有结果:
curl -X POST https://side.example.com/v1/auth/sso/start -H "Content-Type: application/json" \
-d '{"email": "[email protected]", "device_name": "Ben 的笔记本"}'
# → {"url": "https://harbor.okta.com/…", "handle": "sso_…", "expires_at": "…"}
curl -X POST https://side.example.com/v1/auth/sso/poll -H "Content-Type: application/json" -d '{"handle": "sso_…"}'
# 等待中返回 202;成功返回 200,令牌和邮箱登录的一样;过期或已取走返回 410没有组织为这个域名设置单点登录时,start 返回 404。POST /v1/auth/email/start(或 verify)返回 403、code 为 sso_required 时,就改走这个流程。sidespace login EMAIL --sso 和网页版的登录页都是这样做的。
审计导出
管理员可以导出组织里发生过的事,按时间从早到晚。令牌需要 admin 权限范围。
sidespace org audit "Harbor Pictures" --since 2026-10-01 --format csv -o audit.csvcurl "https://side.example.com/v1/orgs/$ORG/audit?since=2026-10-01&format=jsonl" -H "Authorization: Bearer $SIDESPACE_TOKEN"每条记录有 at、source、kind、actor_id、actor_email,适用时还有 actor_kind(人、AI agent 或插件)、via(令牌或 AI 动作)、space_id、space_name、target、path 和 detail。记录来自两处:
org:组织的变化(成员、团队、空间角色、文件夹规则、单点登录设置)和每一次单点登录。space:组织里各个空间的每次文件改动,取自空间的变更日志,带着当时的文件名。空间放进组织时,它之前的历史也一起带进来。
since 和 until 接受 RFC 3339 时间或日期,默认是最近 30 天。一次最多返回 20 万条;更多时从最后一条的时间开始再导出。网页版里,管理员在组织的审计导出页下载。