安全与认证配置

外部认证、Vertex AI、OAuth、认证配置文件、工具策略、主动记忆、上下文引擎、审计日志、健康检查、插件、Prompt 智能以及环境变量参考的配置。


[external_auth]

配置 OAuth2/OIDC 外部认证,允许用户通过 Google、GitHub、Okta、Auth0 或 Keycloak 等身份提供商登录。

[external_auth]
enabled = true
issuer_url = "https://accounts.google.com"
client_id = "your-client-id.apps.googleusercontent.com"
client_secret_env = "LIBREFANG_OAUTH_CLIENT_SECRET"
redirect_url = "http://127.0.0.1:4545/api/auth/callback"
scopes = ["openid", "profile", "email"]
allowed_domains = ["example.com"]
session_ttl_secs = 86400

# 下面两份映射所匹配的声明值从令牌的哪些位置读取。
# 使用点号路径;`<client>` 会被替换为该提供商的 client_id。
# 默认为 ["roles", "groups"]。
claim_paths = ["realm_access.roles", "resource_access.<client>.roles", "groups"]

# 哪些 IdP 群组可以调用 API,以及对应的权限级别。
# 默认为空:未配置时,OIDC bearer 令牌不会通过任何认证。
[external_auth.role_map]
"librefang-owners" = "owner"
"librefang-operators" = "admin"
"engineering" = "user"

# 哪些 IdP 群组会让调用方成为本地 [[groups]] 条目的成员。
# 与 role_map 相互独立:成员身份本身不携带任何权限。
[external_auth.group_map]
"platform-oncall" = "oncall"
"sox-reviewers" = "compliance"
字段类型默认值说明
enabledboolfalse启用外部认证。
issuer_urlstring""OIDC 发行者 URL,用于在 {issuer_url}/.well-known/openid-configuration 进行提供商发现。
client_idstring""在身份提供商注册的 OAuth2 客户端 ID。
client_secret_envstring"LIBREFANG_OAUTH_CLIENT_SECRET"存放 OAuth2 客户端密钥的环境变量名称。
redirect_urlstring"http://127.0.0.1:4545/api/auth/callback"OAuth2 授权码流程的回调 URL。
scopeslist of strings["openid","profile","email"]请求的 OAuth2 权限范围。
allowed_domainslist of strings[]限制登录到这些邮箱域名。空列表 = 允许所有。
audiencestring""要验证的 JWT audience 声明。为空时默认使用 client_id。
session_ttl_secsu6486400会话令牌有效期(秒)。默认 24 小时。
require_email_verifiedbooltrue拒绝 ID 令牌中没有 email_verified = true 的登录。仅当提供商不签发该声明时才设为 false。
providerslist of objects[]多个 OIDC/OAuth2 提供商。配置后优先于上述单提供商字段。
role_maptable of string → string{}IdP 角色/群组声明值 → LibreFang 角色(owner / admin / user / viewer / guest)。详见下文。
group_maptable of string → string{}IdP 群组/角色/scope 声明值 → 调用方将被视为其成员的 [[groups]] 条目名称。详见下文。
claim_pathslist of strings["roles","groups"]两份映射所匹配的声明的点号路径。<client> 会被替换为提供商的 client_id。详见下文。

role_map:把 ID 令牌变成 API 凭据

在这里添加条目之前,通过验证的 OIDC bearer 令牌不会授予任何权限——守护进程会用提供商的 JWKS 验证令牌,而调用方仍然收到与完全不带令牌时相同的 401。 授予权限的是这份映射本身,因此权限始终来自运维人员写下的配置,而不是身份提供商单方面的决定。

键是 claim_paths 解析出的声明值(默认为 roles 和 groups 两个声明),值是 LibreFang 角色,使用与 [[users]] role 和 [channel_role_mapping] 相同的 viewer < user < admin < owner 阶梯。 持有多个已映射群组的调用方会获得权限最高的匹配项,因此声明的顺序(那是提供商的事,不是你的)无法决定最终生效的角色。

以下三种情况有意不授予任何权限,而不是回退到某个默认值:

  • 映射中不存在的声明值,
  • 存在但指向无法识别的角色字符串的声明值(例如 "admn" 这类拼写错误,会在启动和配置重载时以 WARN 报告),
  • 来自既未配置 audience 也未配置 client_id 的提供商的令牌,因为此时 JWT audience 校验被禁用,任何由该发行者密钥签名的令牌都会通过验证。

require_email_verified 同样适用于此:邮箱未经提供商验证的令牌不携带任何角色。

该映射从配置快照中实时读取,因此 POST /api/config/reload 会让修改在下一个请求生效,无需重启。 它有意不能通过 POST /api/config/set 写入——能编辑它的调用方可以通过写入自己已持有的群组名把自己提升为 owner——但 GET /api/config 可以读回它,以便确认当前哪些群组携带权限。

group_map:把 IdP 群组接到 LibreFang 团队上

[[groups]](见身份一节)为团队命名——值班轮换、项目组、部门——好让权限和归属可以指向团队,而不必逐个列出成员。 group_map 让这些团队的成员身份来自你的身份提供商,而不是靠手工录入、然后在有人换岗时悄悄过期。

键与 role_map 一样是声明值;值是 [[groups]] 的名称。 和角色一样,成员身份是映射得来的,绝不按名称匹配:除非你写下了那条映射,否则名为 oncall 的 IdP 群组不会加入本地的 oncall 群组。 这一点值得说清楚——在允许自助创建群组的租户里,按名称匹配意味着任何能建群的人都可以挑一个名字,从而获得那个团队所拥有的一切。

成员身份会做什么、不会做什么:

  • 它会把群组自身的名称以及 roles 列表中的每个字符串作为绑定规则的角色字符串授予调用方,并在归属判断中把调用方视为该群组的成员。
  • 它不会授予任何 RBAC 权限。名为 owner 的群组只是一个叫 owner 的团队。如果你希望某个 IdP 声明同时携带成员身份和权限,就把它同时写进 role_map 和 group_map——两条条目,刻意为之。

成员身份在每个请求上都从所出示的令牌重新计算,且绝不会写入 config.toml。 这正是撤销权限能够生效的原因:在身份提供商中把某人移出群组,其当前令牌过期后这里的成员身份即随之消失,本地无需任何清理。 反过来则不会发生——身份提供商不再声明某个群组,并不会把那个人从你手写的 [[groups]] members 列表中移除。members 中的名字是你自己的授权,只有你能收回。当两边都指向同一个人时,结果就是二者的并集。

group_map 的值若指向 [[groups]] 中不存在的群组,则不授予任何成员身份,并会在启动和配置重载时以 WARN 报告——包括群组被删除或改名而映射未同步这种最常见的情况。

GET /api/authz/whoami 会报告调用方凭据实际解析成了什么:角色、principal、生效的群组、其中哪些来自令牌,以及群组授予的角色字符串。SSO 登录后权限不如预期时,先看这里。

claim_paths:声明值从哪里来

两份映射匹配的是同一组解析出来的声明值,而 claim_paths 决定这组值由令牌的哪些部分构成。 条目是点号路径,因此 Keycloak 的 realm_access.roles 和 resource_access.<client>.roles 都可以寻址;<client> 会被替换为该提供商自己的 client_id,所以同一条条目可以跨提供商使用,也绝不会取到同一令牌中其他客户端的角色。 解析结果为字符串数组的路径贡献其中每个元素;解析结果为单个字符串的路径贡献其按空白分隔的各个词。解析不到任何内容的路径不是错误——各家提供商签发的声明本就不同。

默认值是 ["roles", "groups"]。 scope 有意不在其中:roles 和 groups 是身份提供商关于用户的断言,而 scope 描述的是某个客户端应用申请并获得了什么,同一租户中为其他 OAuth 客户端签发的令牌同样携带它。 如果你需要它,把 "scope" 加进列表,并且只在已设置 audience 的情况下这样做——没有 audience 绑定时,守护进程根本不会派生任何授权。

注意,增加一条路径会同时扩大 role_map 和 group_map 的匹配范围,因为两者读取同一组值。

出于与 role_map 相同的理由,group_map 和 claim_paths 通过 POST /api/config/set 是只读的,也出于同样的理由可以通过 GET /api/config 读回。

对于多提供商配置,使用 [[external_auth.providers]],支持以下字段:id、display_name、issuer_url、auth_url、token_url、userinfo_url、jwks_uri、client_id、client_secret_env、redirect_url、scopes、allowed_domains、audience。


[terminal]

配置交互式终端 WebSocket 端点的访问控制。

[terminal]
enabled = true
allow_remote = false
allowed_origins = ["https://dashboard.example.com"]
tmux_enabled = true
max_windows = 16
# tmux_binary_path = "/usr/local/bin/tmux"
字段类型默认值说明
enabledbooltrue终端功能总开关。设为 false 时,终端 WebSocket 端点会被完全禁用。
allow_remoteboolfalse允许来自远程或反向代理的连接。当未配置认证时,还必须同时将 allow_unauthenticated_remote 设为 true,否则连接会被拒绝。默认行为是仅允许本地无认证访问。
allow_unauthenticated_remoteboolfalse强制防呆开关。当 allow_remote = true 且未配置任何认证时,必须显式将本项设为 true 才能对外暴露未认证的 shell;否则即使 allow_remote = true,此类连接也会被拒绝。
allowed_originslist of strings[]除 localhost 之外,允许用于终端 WebSocket 连接的额外浏览器 Origin 列表。适用于 dashboard 部署在自定义域名下的情况。["*"] 表示允许任意 HTTP/HTTPS origin,应仅在明确知情的情况下使用。
require_proxy_headersboolfalse当为 true 时,没有代理头(X-Forwarded-For、X-Real-IP)的环回连接将被拒绝。仅在使用注入这些头的反向代理时启用。(旧名:trust_proxy_headers,仍作为别名兼容。)
tmux_enabledbooltrue启用基于 tmux 的多窗口终端。仅当系统上存在 tmux 二进制文件时生效。
max_windowsu3216最大同时存在的 tmux 窗口数量。用于防止资源耗尽。
tmux_binary_pathstring 或 nullnulltmux 二进制文件的显式路径。如果为 null,则通过 PATH 解析。

说明:

  • 对于非浏览器客户端,缺少 Origin 头是允许的。
  • allow_remote = true 不会关闭认证;如果已配置 API Key 或 dashboard 凭据,远程客户端仍然需要提供有效认证。
  • 对浏览器访问,优先使用明确的 HTTPS origin,而不是 "*"。
  • [rate_limit] 中的 ws_terminal_messages_per_minute(默认值:3600)控制交互式终端会话的每连接 WebSocket 消息吞吐量。

[vertex_ai]

配置 Google Cloud Vertex AI 作为 LLM 提供商。

[vertex_ai]
project_id = "my-gcp-project"
region = "us-central1"
credentials_path = "/path/to/service-account.json"

凭据按以下顺序解析:

  1. 配置中的 credentials_path(JSON 字符串或文件路径)
  2. VERTEX_AI_SERVICE_ACCOUNT_JSON 环境变量
  3. GOOGLE_APPLICATION_CREDENTIALS 环境变量(文件路径)
  4. gcloud auth print-access-token CLI 后备
字段类型默认值说明
project_idstring 或 nullnullGCP 项目 ID。回退到 VERTEX_AI_PROJECT_ID、GOOGLE_CLOUD_PROJECT,或服务账号 JSON 中的 project_id 字段。
regionstring 或 nullnullVertex AI 端点的 GCP 区域。回退到 VERTEX_AI_REGION 或 GOOGLE_CLOUD_REGION 环境变量。默认:"us-central1"。
credentials_pathstring 或 nullnullGCP 服务账号 JSON 密钥文件的路径,或原始 JSON 字符串。

[oauth]

配置仪表盘使用的 PKCE(Proof Key for Code Exchange)流程的 OAuth 客户端 ID。

[oauth]
google_client_id = "your-google-client-id.apps.googleusercontent.com"
github_client_id = "your-github-app-client-id"
microsoft_client_id = "your-azure-app-client-id"
slack_client_id = "your-slack-app-client-id"
字段类型默认值说明
google_client_idstring 或 nullnull用于 PKCE 流程的 Google OAuth2 客户端 ID。
github_client_idstring 或 nullnull用于 PKCE 流程的 GitHub OAuth 应用客户端 ID。
microsoft_client_idstring 或 nullnullMicrosoft(Entra ID / Azure AD)OAuth 应用客户端 ID。
slack_client_idstring 或 nullnullSlack OAuth 应用客户端 ID。

[auth_profiles]

为每个提供商配置多个 API Key 配置文件,以实现当某个 Key 被限速或用尽时的轮换。

[auth_profiles]
anthropic = [
  {name = "primary", api_key_env = "ANTHROPIC_API_KEY_1", priority = 0},
  {name = "secondary", api_key_env = "ANTHROPIC_API_KEY_2", priority = 1},
]
openai = [
  {name = "main", api_key_env = "OPENAI_API_KEY", priority = 0},
]

值是从提供商名称到 AuthProfile 对象列表的映射:

字段类型默认值说明
namestring必填配置文件名称(例如 "primary"、"secondary")。
api_key_envstring必填存放该配置文件 API Key 的环境变量名称。
priorityu320Key 选择优先级。值越小越优先。

[tool_policy]

配置全局工具访问规则、分组和递归深度限制。引用 ToolPolicy 类型。

[tool_policy]
subagent_max_depth = 10
subagent_max_concurrent = 5

[[tool_policy.global_rules]]
pattern = "shell_*"
effect = "deny"

[[tool_policy.groups]]
name = "web_tools"
tools = ["web_search", "web_fetch"]
字段类型默认值说明
agent_ruleslist of ToolPolicyRule[]每个 Agent 的工具规则(最高优先级,最先检查)。
global_ruleslist of ToolPolicyRule[]应用于所有 Agent 的全局工具规则(在 agent 规则之后检查)。
groupslist of ToolGroup[]命名工具组,便于在规则中重用。
subagent_max_depthu3210子 Agent 最大生成深度。
subagent_max_concurrentu325最大并发子 Agent 数。

ToolPolicyRule 字段:

字段类型说明
patternstring匹配工具名称的 Glob 模式(例如 "shell_*"、"web_*"、"mcp_github_*")。
effectstring"allow" 或 "deny"。拒绝优先:只要有任何 deny 规则匹配,该工具就会被阻止,无论是否有 allow 规则。

ToolGroup 字段:

字段类型说明
namestring组名(例如 "web_tools"、"code_tools")。
toolslist of strings包含在该组中的工具名称模式。

[proactive_memory]

配置主动记忆提取(mem0 风格的自动记忆管理)。引用 ProactiveMemoryConfig 类型。

[proactive_memory]
enabled = true
auto_memorize = true
auto_retrieve = true
max_retrieve = 10
extraction_threshold = 0.7
# extraction_model = "gpt-4o-mini"             # 使用默认提供商
# extraction_model = "anthropic/claude-haiku-4" # 指定特定提供商
# extraction_model = "anthropic:claude-haiku-4" # 冒号格式也可用
extract_categories = ["user_preference", "important_fact", "task_context", "relationship"]
session_ttl_hours = 24
duplicate_threshold = 0.5
confidence_decay_rate = 0.01
max_memories_per_agent = 1000
字段类型默认值说明
enabledbooltrue主开关——为 false 时整个主动记忆子系统被禁用。
auto_memorizebooltrue每次 Agent 执行后自动提取并存储记忆。
auto_retrievebooltrue每次 Agent 执行前自动检索相关记忆。
max_retrieveusize10每次查询检索的最大记忆数。
extraction_thresholdf320.7近似重复检测的置信度阈值(0.0-1.0)。
extraction_modelstring 或 nullnull用于提取的 LLM 模型。支持 提供商/模型 格式(如 "anthropic/claude-haiku-4")、提供商:模型 格式,或裸模型名(使用默认提供商)。为 null 时使用基于规则的提取。没有单独的 extraction_provider 字段。
extract_categorieslist of strings["user_preference", "important_fact", "task_context", "relationship"]从对话中提取的类别。
session_ttl_hoursu3224会话记忆的 TTL(小时)。超过此时间的记忆在每次 Agent 执行前被清理。
duplicate_thresholdf320.5重复检测的相似度阈值(0.0-1.0)。有嵌入向量时使用余弦相似度,否则回退到 Jaccard 词重叠。
confidence_decay_ratef640.01每天的置信度衰减率。遵循指数衰减:conf x e^(-rate x days)。默认 0.01 约 70 天减半。
max_memories_per_agentusize1000每个 Agent 的最大记忆数。超出时优先淘汰原始对话行,其次才是抽取出的事实;同类之内按置信度从低到高淘汰。0 = 无上限。

[context_engine]

配置可插拔的上下文组装引擎,控制 Agent 记忆如何被召回并组装到提示词中。

[context_engine]
engine = "default"
# plugin = "qdrant-recall"    # 解析为 ~/.librefang/plugins/qdrant-recall/

[context_engine.hooks]
# ingest = "~/.librefang/scripts/my_recall.py"
# after_turn = "~/.librefang/scripts/my_indexer.py"
# runtime = "python"   # python(默认)| v | node | deno | go | native

[[context_engine.plugin_registries]]
name = "Official"
github_repo = "librefang/librefang-registry"
字段类型默认值说明
enginestring"default"内置引擎名称。目前仅支持 "default"。
pluginstring 或 nullnull插件名称。解析为 ~/.librefang/plugins/<name>/plugin.toml。设置时优先于手动 hooks。
hooks.ingeststring 或 nullnullingest 钩子的脚本路径(在收到新用户消息时调用)。
hooks.after_turnstring 或 nullnullafter_turn 钩子的脚本路径(在每轮对话完成后调用)。
hooks.runtimestring 或 null"python"运行钩子脚本的启动器。可选:python、v、node、deno、go、native(直接执行预编译二进制)。
plugin_registrieslist of objects官方注册表插件注册表(GitHub owner/repo),用于浏览可安装的插件。

[audit]

配置审计日志保留策略。

[audit]
retention_days = 90
字段类型默认值说明
retention_daysu3290审计日志条目的保留天数。0 = 无限期保留。

[health_check]

配置 LLM 提供商的定期健康检查。

[health_check]
health_check_interval_secs = 60
字段类型默认值说明
health_check_interval_secsu6460提供商健康检查的间隔(秒)。

[plugins]

配置额外的插件注册表,用于搜索可安装的上下文引擎插件。

[plugins]
plugin_registries = ["acme-corp/librefang-plugins"]
字段类型默认值说明
plugin_registrieslist of strings[]额外的 GitHub owner/repo 插件注册表。与 context_engine.plugin_registries 合并。

[prompt_intelligence]

配置 Prompt 版本管理和 A/B 实验功能。启用后,LibreFang 自动追踪 prompt 版本历史,支持运行 A/B 实验对比不同 prompt 变体。详细文档见 Prompt 智能指南。

[prompt_intelligence]
enabled = false
hash_prompts = true
max_versions_per_agent = 50
字段类型默认值说明
enabledboolfalse总开关。关闭时不追踪 prompt 版本,不运行实验
hash_promptsbooltrue计算 prompt 内容哈希用于去重
max_versions_per_agentu3250每个 agent 最大 prompt 版本数,超出后自动清理最旧的非活跃版本

环境变量

以下是配置中引用的所有环境变量的完整表格。这些变量不由配置文件本身读取——它们在运行时由内核和通道适配器读取。

LLM 提供商密钥

变量使用者说明
ANTHROPIC_API_KEY[default_model]Anthropic API Key(Claude 系列模型)。
GEMINI_API_KEYGemini 驱动Google Gemini API Key。别名:GOOGLE_API_KEY。
OPENAI_API_KEYOpenAI 兼容驱动OpenAI API Key。
GROQ_API_KEYGroq 提供商Groq API Key(快速 Llama 推理)。
DEEPSEEK_API_KEYDeepSeek 提供商DeepSeek API Key。
PERPLEXITY_API_KEYPerplexity 提供商 / 网页搜索Perplexity API Key。
OPENROUTER_API_KEYOpenRouter 提供商OpenRouter API Key。
TOGETHER_API_KEYTogether AI 提供商Together AI API Key。
MISTRAL_API_KEYMistral 提供商Mistral AI API Key。
FIREWORKS_API_KEYFireworks 提供商Fireworks AI API Key。
COHERE_API_KEYCohere 提供商Cohere API Key。
AI21_API_KEYAI21 提供商AI21 Labs API Key。
CEREBRAS_API_KEYCerebras 提供商Cerebras API Key。
SAMBANOVA_API_KEYSambaNova 提供商SambaNova API Key。
HUGGINGFACE_API_KEYHugging Face 提供商Hugging Face Inference API Key。
XAI_API_KEYxAI 提供商xAI (Grok) API Key。
REPLICATE_API_KEYReplicate 提供商Replicate API Key。

网页搜索密钥

变量使用者说明
BRAVE_API_KEY[web.brave]Brave Search API Key。
TAVILY_API_KEY[web.tavily]Tavily Search API Key。
PERPLEXITY_API_KEY[web.perplexity]Perplexity Search API Key(与 LLM 提供商共用)。

通道令牌

变量通道说明
TELEGRAM_BOT_TOKENTelegram从 @BotFather 获取的 Bot API 令牌。
DISCORD_BOT_TOKENDiscordDiscord Bot 令牌。
SLACK_APP_TOKENSlackSlack 应用级令牌(xapp-),用于 Socket Mode。
SLACK_BOT_TOKENSlackSlack Bot 令牌(xoxb-),用于 REST API。
WHATSAPP_ACCESS_TOKENWhatsAppWhatsApp Cloud API 访问令牌。
WHATSAPP_VERIFY_TOKENWhatsAppWebhook 验证令牌。
MATRIX_ACCESS_TOKENMatrixMatrix 家服务器访问令牌。
EMAIL_PASSWORDEmail邮箱密码或应用专用密码。
TEAMS_APP_PASSWORDTeamsAzure Bot Framework 应用密码。
MATTERMOST_TOKENMattermost(sidecar)Mattermost Bot 令牌(sidecar 适配器 —— 写入 ~/.librefang/secrets.env)。
TWITCH_OAUTH_TOKENTwitchTwitch OAuth 令牌。
ROCKETCHAT_TOKENRocket.Chat (sidecar)Rocket.Chat 个人访问令牌(sidecar 适配器 —— 写入 ~/.librefang/secrets.env)。
ZULIP_API_KEYZulipZulip Bot API Key。
XMPP_PASSWORDXMPPXMPP 账号密码。
GOOGLE_CHAT_SERVICE_ACCOUNTGoogle Chat服务账号 JSON 密钥。
LINE_CHANNEL_SECRETLINE (sidecar)LINE Channel Secret(librefang.sidecar.adapters.line —— 写入 ~/.librefang/secrets.env)。
LINE_CHANNEL_ACCESS_TOKENLINE (sidecar)LINE Channel Access Token(sidecar 适配器)。
REDDIT_CLIENT_SECRETRedditReddit 应用客户端密钥。
REDDIT_PASSWORDRedditReddit Bot 账号密码。
MASTODON_ACCESS_TOKENMastodonMastodon 访问令牌。
BLUESKY_APP_PASSWORDBlueskyBluesky 应用密码。
FEISHU_APP_SECRETFeishu飞书/Lark 应用密钥。
REVOLT_BOT_TOKENRevoltRevolt Bot 令牌。
NEXTCLOUD_TOKENNextcloud (sidecar)Nextcloud Talk 应用密码 / OAuth bearer(librefang.sidecar.adapters.nextcloud)。
GUILDED_BOT_TOKENGuildedGuilded Bot 令牌。
KEYBASE_PAPERKEYKeybaseKeybase 纸钥匙。
THREEMA_SECRETThreemaThreema Gateway API 密钥。
WEBEX_BOT_TOKENWebex (sidecar)Webex Bot Bearer 令牌(librefang.sidecar.adapters.webex)。
PUMBLE_BOT_TOKENPumblePumble Bot 令牌。
FLOCK_BOT_TOKENFlockFlock Bot 令牌。
TWIST_TOKENTwistTwist API 令牌。
MUMBLE_PASSWORDMumbleMumble 服务器密码。
DINGTALK_APP_KEYDingTalk钉钉 App Key / Client ID(sidecar 适配器 librefang.sidecar.adapters.dingtalk,仅 stream 模式)。
DINGTALK_APP_SECRETDingTalk钉钉 App Secret / Client Secret(sidecar 适配器 librefang.sidecar.adapters.dingtalk,仅 stream 模式)。
GITTER_TOKENGitterGitter 认证令牌。
NTFY_TOKENntfyntfy 认证令牌(公共主题可选)。
GOTIFY_APP_TOKENGotifyGotify 应用令牌(发送)。
GOTIFY_CLIENT_TOKENGotifyGotify 客户端令牌(接收)。
WEBHOOK_SECRETWebhook用于 Webhook 验证的 HMAC 签名密钥。