diff --git a/.env.release.example b/.env.release.example
index f11c0eb2..cee00087 100644
--- a/.env.release.example
+++ b/.env.release.example
@@ -122,6 +122,10 @@ OAUTH2_GITLAB_DISPLAY_NAME=GitLab
# contact:user.email:readonly on the Feishu open-platform app itself; scopes are not sent here.
# Set OAUTH2_FEISHU_AUTHORIZE_URI/OAUTH2_FEISHU_BASE_URI to the Lark endpoints for
# international tenants (open.larksuite.com).
+# Feishu emails are admin-imported and never confirmed with the user, so emailVerified is always
+# false. If you set skillhub.access-policy.mode=EMAIL_DOMAIN in application.yml, that policy
+# denies every unverified email and Feishu login will always fail; keep the default OPEN mode,
+# or use another policy, when enabling this provider.
OAUTH2_FEISHU_CLIENT_ID=
OAUTH2_FEISHU_CLIENT_SECRET=
OAUTH2_FEISHU_AUTHORIZE_URI=https://accounts.feishu.cn
diff --git a/docs/03-authentication-design.md b/docs/03-authentication-design.md
index 4c8ef11e..c8735b63 100644
--- a/docs/03-authentication-design.md
+++ b/docs/03-authentication-design.md
@@ -271,18 +271,37 @@ spring:
client-id: ${OAUTH2_GITHUB_CLIENT_ID}
client-secret: ${OAUTH2_GITHUB_CLIENT_SECRET}
scope: read:user,user:email
- # 二期扩展示例:
- # gitlab:
- # client-id: ...
- # authorization-grant-type: authorization_code
- # google:
- # client-id: ...
+ gitlab:
+ client-id: ${OAUTH2_GITLAB_CLIENT_ID}
+ client-secret: ${OAUTH2_GITLAB_CLIENT_SECRET}
+ authorization-grant-type: authorization_code
+ feishu:
+ client-id: ${OAUTH2_FEISHU_CLIENT_ID}
+ client-secret: ${OAUTH2_FEISHU_CLIENT_SECRET}
+ # 飞书的 scope 配在开放平台应用上,不在这里传
+ client-authentication-method: client_secret_post
+ authorization-grant-type: authorization_code
```
Spring Security OAuth2 Client 原生支持多 Provider 并存,新增 Provider 只需:
-1. `application.yml` 添加 registration 配置
-2. `CustomOAuth2UserService` 中按 `registrationId` 分支处理用户属性映射
-3. 前端登录页增加对应按钮(通过 `/api/v1/auth/providers` 自动发现)
+1. `application.yml` 添加 registration 与 provider 配置
+2. 实现一个 `OAuthClaimsExtractor`,把该 Provider 的属性映射成统一的 `OAuthClaims`
+3. 登录页无需改代码:`/api/v1/auth/methods` 只返回配置了真实 client id 的注册,
+ 图标按 provider 名解析为 `/{provider}-logo.svg`
+
+第 2 步是按 Provider 注册一个 Bean,而不是在某个类里按 `registrationId` 分支。
+账号匹配、建号、资料权威和账号守卫都在 `OAuthClaims` 之后共享,Provider 自己不做这些决策。
+
+如果该 Provider 的 userinfo 响应不是标准的扁平结构(例如飞书用
+`{code, msg, data}` 信封,且以 HTTP 200 返回错误),再额外实现一个
+`ProviderOAuth2UserService`:它声明自己负责哪个 `registrationId`,
+接管 userinfo 的加载步骤,其余流程不变。该覆盖运行在
+`RemoteIdentityIoExecutor` 边界内,因此 Provider 的 HTTP 调用不会持有数据库事务。
+
+Provider 侧还需遵守:subject 必须稳定(不要用可能在两次登录间变化的字段做
+fallback,否则同一个人会被拆成两个平台账号)、只有在 Provider 真正证明了邮箱
+所有权时才置 `emailVerified=true`、远程调用要有超时与响应大小上限、
+claims 提取过程不记录 subject/email/token。
## 4. 核心接口设计
diff --git a/docs/09-deployment.md b/docs/09-deployment.md
index 2bbf6c8c..3671c94d 100644
--- a/docs/09-deployment.md
+++ b/docs/09-deployment.md
@@ -283,7 +283,16 @@ services:
- `SKILLHUB_WEB_API_BASE_URL=/skillhub`
- `SKILLHUB_PUBLIC_BASE_URL=https://example.com/skillhub`
网关可以在转发到 Web 容器前将该前缀重写掉,但公网 URL 仍必须保留前缀,确保 OAuth、CLI 和 registry 链接正确。
-- 如果要开放真实登录,再补充 `OAUTH2_GITHUB_CLIENT_ID` / `OAUTH2_GITHUB_CLIENT_SECRET`
+- 如果要开放真实登录,再补充对应 Provider 的 client id/secret:
+ - GitHub:`OAUTH2_GITHUB_CLIENT_ID` / `OAUTH2_GITHUB_CLIENT_SECRET`
+ - GitLab:`OAUTH2_GITLAB_CLIENT_ID` / `OAUTH2_GITLAB_CLIENT_SECRET`(自建实例再设 `OAUTH2_GITLAB_BASE_URI`)
+ - 飞书:`OAUTH2_FEISHU_CLIENT_ID` / `OAUTH2_FEISHU_CLIENT_SECRET`
+ (国际版 Lark 再设 `OAUTH2_FEISHU_AUTHORIZE_URI` / `OAUTH2_FEISHU_BASE_URI`)
+
+ 留空即不展示该入口,无需改配置文件。注意:飞书邮箱由企业管理员导入、未经用户
+ 确认,因此 `emailVerified` 恒为 false;若在 `application.yml` 中把
+ `skillhub.access-policy.mode` 设为 `EMAIL_DOMAIN`,该策略会拒绝所有未验证邮箱,
+ 飞书登录将一律失败。启用飞书时请保留默认的 `OPEN` 或改用其他准入模式。
- 如果要启用密码重置验证码邮件,参见:`docs/19-smtp-password-reset-email-setup.md`
## 8 OIDC 登录配置
diff --git a/docs/skillhub/en/faq.md b/docs/skillhub/en/faq.md
index acfe6d89..c00abdf8 100644
--- a/docs/skillhub/en/faq.md
+++ b/docs/skillhub/en/faq.md
@@ -190,9 +190,14 @@ A: Skill names are generally in English; Chinese names are not currently support
A: As long as you have permission to view it, it can generally be downloaded.
-## Q: How do I hide or remove the GitHub / GitLab SSO login options on the login page?
+## Q: How do I hide or remove third-party SSO login options on the login page?
-A: Edit `application.yml` and comment out or delete the `github` and `gitlab` blocks under `spring.security.oauth2.client.registration`, along with their corresponding `provider` sections. Spring Boot then won't create these registrations at startup, and the login page won't show those entries.
+A: Login entries are config-driven: `/api/v1/auth/methods` only returns registrations that have a real client id. When a client id is empty or contains `placeholder`, that entry never reaches the login page.
+
+So there are two ways to hide one:
+
+- Leave the matching environment variable unset (for example, omit `OAUTH2_FEISHU_CLIENT_ID`). No config file change needed.
+- Or edit `application.yml` and comment out or delete the relevant registration block (`github`, `gitlab`, `feishu`) under `spring.security.oauth2.client.registration`, along with its `provider` section. Spring Boot then won't create that registration at startup.
## Q: Is SkillHub's security scanning (Skill Scanner) developed in-house by iFLYTEK? What license does it use?
diff --git a/docs/skillhub/faq.md b/docs/skillhub/faq.md
index 8906150c..75054ca0 100644
--- a/docs/skillhub/faq.md
+++ b/docs/skillhub/faq.md
@@ -190,9 +190,17 @@ A: skill name 一般使用英文,目前不支持中文名(在 OpenClaw 中
A: 只要拥有可查看的权限,一般都可以下载。
-## Q: 如何隐藏或删除登录页的 GitHub / GitLab SSO 登录方式?
+## Q: 如何隐藏或删除登录页的第三方 SSO 登录方式?
-A: 修改 `application.yml`,注释或删除 `spring.security.oauth2.client.registration` 下的 `github` 和 `gitlab` 两块,并删除对应的 `provider` 段。Spring Boot 启动时便不会创建这两个注册,登录页也不会再显示对应入口。
+A: 登录入口是配置驱动的:`/api/v1/auth/methods` 只返回配置了真实 client id 的
+注册,client id 为空或包含 `placeholder` 时该入口不会出现在登录页。
+
+所以隐藏某个入口有两种方式:
+
+- 留空对应的环境变量即可(例如不设置 `OAUTH2_FEISHU_CLIENT_ID`),无需改动配置文件。
+- 或修改 `application.yml`,注释/删除 `spring.security.oauth2.client.registration`
+ 下对应的注册块(`github`、`gitlab`、`feishu`)以及对应的 `provider` 段,
+ Spring Boot 启动时便不会创建该注册。
## Q: SkillHub 的安全扫描(Skill Scanner)是讯飞自研的吗?使用什么协议?
diff --git a/web/public/feishu-logo.svg b/web/public/feishu-logo.svg
index 0cb86de7..f929a53d 100644
--- a/web/public/feishu-logo.svg
+++ b/web/public/feishu-logo.svg
@@ -1,2 +1,2 @@
-
\ No newline at end of file
+
\ No newline at end of file