前言
自建服务逐渐多起来以后,每个服务都要单独维护一套账号。代码仓库、文件同步、资料管理各有各的入口,账号和密码也需要分别管理。
这次在云服务器上部署 Authentik,作为统一身份提供者,后续再逐个接入应用。
本文使用的 Authentik 版本为 2026.8.5,数据库为 PostgreSQL 16。域名、目录和账号均使用示例,部署时自行替换。
一、Authentik 介绍
1.1 身份认证与应用授权
Authentik 是一个可以自建的身份提供者(IdP)。它维护用户、组和认证会话,为接入的应用提供统一的身份认证,也可以从 Microsoft、Google 等外部身份源接收用户身份。
接入后,应用可以把登录请求交给 Authentik,再根据返回的身份信息建立自己的会话。应用内部的资源权限仍需要配置,例如 Gitea 中哪些仓库允许访问、Nextcloud 中哪些目录可以共享。统一登录不会自动替应用完成这些授权设置。
这次的关系可以先理解为:
text12345Microsoft / Google ↓ 外部身份源 Source Authentik 本地用户与认证会话 ↓ 应用对应的 Provider Gitea / Nextcloud 等下游应用(后续接入)
因此,Google 登录 Authentik 和 Gitea 使用 Authentik 登录,需要配置的对象不同。前者创建 Source,后者为 Gitea 创建 Application 和 Provider。
1.2 核心配置对象
| 对象 | 用途 | 本文中的例子 |
|---|---|---|
| User / Group | 本地用户与分组,承载账号、属性和权限关系 | 已有管理员账号及其外部身份绑定 |
| Source(身份源) | 接入外部身份,配置匹配方式和后续流程 | Microsoft、Google OAuth Source |
| Application(应用) | 表示一个接入服务,关联认证提供者和访问配置 | 后续接入的 Gitea |
| Provider(提供者) | 按 OIDC、SAML 等协议向应用提供认证能力 | Gitea 对应的 OIDC Provider |
| Flow(流程) | 组织一次登录、注册、授权等操作的步骤 | 默认登录流程 |
| Stage(阶段) | 执行一个具体步骤 | 识别用户、校验密码、建立登录会话 |
| Binding(绑定) | 把阶段接到流程中并指定顺序,或把策略、用户、组等条件接到目标上 | 登录流程中的 Stage Bindings |
| Policy(策略) | 根据条件决定是否允许访问或执行相应流程、阶段 | 后续按用户组限制应用访问 |
| Brand | 按访问域名选择站点外观及默认流程等设置 | 认证入口使用的默认登录 Flow |
Source 里的“账号绑定”和 Flow 的 Stage Binding 也不是同一件事。前者记录某个外部身份属于哪个本地用户,后者表示一个流程要执行哪些步骤。
Outpost 则是部分集成方式使用的独立组件,例如代理认证或 LDAP 集成。本文的基础部署不需要额外部署 Outpost;服务器 SSH 登录也需要另行选择并配置接入方式。
1.3 默认登录流程
安装完成后,Authentik 已带有一组默认 Flow 和 Stage,可以先在它们的基础上配置。新部署首先会接触以下对象:
| 默认对象 | 作用 | 本次如何处理 |
|---|---|---|
initial-setup |
首次初始化管理员的流程入口 | 安装后完成一次初始化 |
default-authentication-flow |
用户进入 Authentik 时使用的默认登录流程 | 保留现有本地登录能力 |
default-authentication-identification |
登录流程中的用户识别阶段,也负责列出可选身份源 | 后续按需增加外部身份源 |
default-source-authentication |
外部身份已经关联本地用户后的认证流程 | 作为 Source 的 Authentication flow 保留 |
default-source-enrollment |
外部身份尚未关联用户时使用的注册流程 | 由 Source 的 Enrollment flow 引用 |
这些是本文版本的默认名称。若实例已经自定义过流程,应以实际绑定关系为准,不能只凭名称找到一个对象就修改。
典型的本地密码登录,可以概括为下面的顺序:
text12345Identification:确定要登录哪个用户 ↓ Password:校验该用户的密码 ↓ User Login:为用户建立登录会话
实际 Flow 还可以包含验证器检查等阶段,并按绑定条件决定是否执行。输入用户名、验证身份和建立会话是不同步骤;添加外部登录按钮时,不需要删掉整个密码登录流程。Flow 文档介绍了阶段、执行顺序与策略的关系。
点击 Google 时,浏览器会转到 Google 授权,再回到 Authentik 的 Source 回调。之后根据已有绑定和匹配结果,进入认证、注册或已登录用户的绑定处理。这也解释了为什么浏览器授权成功,还可能在返回 Authentik 后遇到“不能注册”或“进入了另一个用户”的情况。
1.4 输入、阶段与策略
Prompt(输入)定义一个字段,例如字段键 password、标签“新密码”、类型 Password。Prompt Stage 把若干输入排成一个表单,提交后保存在流程上下文的 prompt_data 中。User Write Stage 才会把这些值写入用户。单独创建输入,或者只让表单提交成功,都不会自动改掉账号资料。
Identification 和 Password 等专用阶段有自己的界面,不需要先创建用户名、密码 Prompt。只有需要自己组织表单时,才创建输入和 Prompt Stage。
策略也有两个常用位置:
| 位置 | 执行时机 | 例子 |
|---|---|---|
| 流程或阶段的策略绑定 | 判断能否进入流程、是否执行阶段 | 已完成 Passkey 验证时跳过密码阶段 |
| Prompt Stage 的 Validation Policies | 表单提交后检查内容 | 密码强度、注册邮箱是否符合邀请 |
阶段绑定的 Order 决定先后,不要求连续。10、20、30、100 之间留出空位,后面比较方便插入阶段。Evaluate on plan 在规划流程时检查,Re-evaluate policies 在执行阶段时重新检查;依赖前一步产生的数据时,不能只在流程开始前评估一次。
1.5 默认流程与条件策略
默认登录需要兼容本地密码、LDAP、Kerberos、应用程序密码及无密码认证,因此带有条件策略。本文版本的蓝图中,两条关键策略是:
| 默认策略 | 判断内容 |
|---|---|
default-authentication-flow-password-stage |
检查 pending_user 是否已经附带认证 backend;尚未认证时才执行密码阶段 |
default-authentication-flow-authenticator-validate-stage |
如果认证方法已是 auth_webauthn_pwl,跳过额外的认证器验证 |
它们返回 False 时,只控制所绑定的阶段是否执行,不等于整个登录失败。自建流程如果把密码登录和 Passkey 登录拆成两个入口,就不必照搬所有跳过分支;但后来再把 Passkey 自动填充混进密码流程时,需要重新考虑这些条件。
其他默认流程可以按用途看:
| 默认流程 | 阶段或职责 |
|---|---|
default-authentication-flow |
识别账号 → 密码 → MFA 检查 → 建立会话 |
default-authenticator-totp-setup |
配置 TOTP 验证器 |
default-authenticator-static-setup |
生成备用恢复码 |
default-authenticator-webauthn-setup |
注册 WebAuthn 凭据 |
default-source-authentication |
已关联的外部身份返回后建立本地会话;default-source-authentication-if-sso 限定从 SSO 上下文进入 |
default-source-enrollment |
处理外部身份对应的新用户注册;它与管理员邀请注册不同 |
default-source-pre-authentication |
身份源发起认证之前的扩展入口,默认没有持久化阶段 |
default-password-change |
已登录用户填写两次新密码 → 用户写入 |
default-user-settings-flow |
个人资料表单 → 权限检查 → 用户写入 |
default-invalidation-flow |
退出 Authentik 会话 |
default-provider-authorization-explicit-consent |
授权同意阶段,默认同意有效期为 4 周 |
default-provider-authorization-implicit-consent |
已登录后免确认地继续提供者授权,默认空流程 |
default-provider-invalidation-flow |
供应用退出协议调用,默认空流程 |
default-request |
访问申请扩展入口,默认空流程;当前版本的访问申请属于 Enterprise Preview 功能 |
default-password-change-password-policy 检查默认改密表单的密码;default-user-settings-authorization 则按租户设置和用户组属性,限制用户名、姓名、邮箱能否修改。它们直接放在 Prompt Stage 的验证策略里,不一定出现在普通 Policy Binding 列表中。
默认 Source 注册还带有两条策略:default-source-enrollment-if-sso 限制从外部身份返回的上下文进入;default-source-enrollment-if-username 检查上游是否已提供用户名,没有时才显示用户名输入。随后用户写入阶段采用 Always Create,再建立会话。这解释了为什么开放 Source 注册时,匿名外部登录可能创建第二个本地账号。
空流程不一定是漏配。有些协议处理会在运行时追加阶段;直接打开空流程 URL,不能代替从应用或身份源进入的测试。
1.6 蓝图、Bootstrap 与 OOBE
Blueprint(蓝图)是一份 YAML 配置配方,可以创建流程、阶段、策略、角色和属性映射。镜像内的默认流程也由蓝图生成。实例会监测蓝图文件变化并执行发现任务,因此删除默认对象前,应先检查对应蓝图是否仍启用。官方蓝图说明
停用蓝图不会删除已有对象;删除对象也不会自动停用蓝图。已经导出的流程蓝图可以用于恢复和复用,但导出文件需要检查是否含凭据或私有配置,不能直接全部公开。
首次部署还涉及两个容易混淆的部分:
authentik Bootstrap准备管理员组和初始akadmin,也支持从部署环境读取初始凭据。当前条目使用state: created,已有对象不会因此反复被覆盖;对象被删后重新应用仍可能创建它。- OOBE(Out-of-box Experience)是首次网页初始化。
initial-setup收集管理员邮箱、两次密码和 Base URL,再更新初始管理员并登录。
OOBE 的入口策略 default-oobe-password-usable 检查是否由正式初始化入口启动,以及初始管理员是否还没有可用密码。default-oobe-prefill-user 把 akadmin 放进 pending_user,default-oobe-base-url-valid 检查站点地址。原生收尾步骤保存地址、标记初始化完成并停用 OOBE 蓝图。正常运行后,不需要把这个向导复制成日常管理流程。
蓝图列表中还有另一类系统基础配置:
| 类别 | 提供的对象 |
|---|---|
| OAuth2、Proxy、SAML Provider | 标准 Scope、协议属性及代理所需映射 |
| SCIM、Google Workspace、Microsoft Entra Provider | 向下游目录同步用户和组的映射;不是 Google/Microsoft 社交登录 Source |
| LDAP、Kerberos Source | 把外部目录属性转换成 Authentik 用户属性 |
| RAC Provider | RDP、SSH 远程连接参数 |
| Object Attributes - User | 姓名、地址、语言等用户扩展属性的定义 |
| RBAC Read-only、Agent Users | 只读管理角色,以及自助创建 Agent 用户的权限预设 |
| Migration - Remove old prompt fields | 按明确名称清理旧版输入对象的历史迁移 |
系统映射蓝图的存在不会自动连接外部服务。后续创建 Provider 或 Source 并选择映射时,才会使用它们。自建全部日常流程,也不要求将这些协议对象逐个改名。
1.7 事件、通知与品牌
事件日志保存发生了什么,例如登录失败、策略异常或配置错误。通知规则通过事件匹配策略挑选事件,再决定接收用户和严重级别;通知传输负责邮件、站内通知或 Webhook。创建了 SMTP 或邮件传输,并不等于已经配置收件人和触发规则。
默认事件蓝图提供 default-notify-configuration-error、default-notify-configuration-warning、default-notify-exception、default-notify-update 四条规则,分别使用配置错误、配置警告、策略/属性映射异常、版本更新的 Event Matcher 策略。default-email-transport 和 default-local-transport 是它们使用的传输。是否实际发信,还要查看当前规则收件组和全局 SMTP;存在默认对象不等于通知已可用。
品牌设置可选择登录 Logo、favicon、背景和默认流程。欢迎语通常来自流程的 Title,页面外观和流程执行不是同一层。邮件模板也有独立的渲染和图片机制,不能只改网页 Logo 就假定邮件会跟着更新。后续按需配置。
二、部署 Authentik
2.1 准备目录与密钥
服务器需要安装 Docker Engine、Compose v2,并准备一个可用域名。示例使用 auth.example.com,DNS 指向 HTTPS 反向代理所在主机。如果同时配置 AAAA 记录,也要保证 IPv6 的访问路径可用。
以下命令在服务器宿主机执行。/srv/example/authentik 是示例部署目录:
bash12345678910sudo install -d -m 700 -o "$(id -u)" -g "$(id -g)" /srv/example/authentik cd /srv/example/authentik mkdir -p custom-templates/email/doratiger # 仅首次创建;已有部署不要重新生成数据库密码和密钥 if [ ! -e .env ]; then umask 077 printf 'PG_PASS=%s\nAUTHENTIK_SECRET_KEY=%s\n' \ "$(openssl rand -hex 32)" "$(openssl rand -hex 48)" > .env fi
PG_PASS 用于数据库连接,AUTHENTIK_SECRET_KEY 是 Authentik 的持久配置,均应随部署备份。不能在重建容器时顺手换掉。
2.2 Compose 配置
本次部署由 PostgreSQL、server 和 worker 三个服务组成。server 提供 Web/API,worker 执行后台任务,两者使用同一版本的 Authentik 镜像。
下面是按本次服务关系整理的最小新部署示例,使用命名卷保存数据;已有实例迁移时应保留原挂载。保存为 compose.yaml:
yaml123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657name: authentik x-authentik-environment: &authentik-environment AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?set secret key} AUTHENTIK_POSTGRESQL__HOST: postgresql AUTHENTIK_POSTGRESQL__USER: authentik AUTHENTIK_POSTGRESQL__NAME: authentik AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS:?set database password} services: postgresql: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: authentik POSTGRES_DB: authentik POSTGRES_PASSWORD: ${PG_PASS:?set database password} volumes: - database:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, "pg_isready -U authentik -d authentik"] interval: 10s timeout: 5s retries: 5 server: image: ghcr.io/goauthentik/server:2026.8.5 command: server restart: unless-stopped environment: *authentik-environment depends_on: postgresql: condition: service_healthy ports: - "127.0.0.1:19000:9000" volumes: - data:/data - ./custom-templates:/templates worker: image: ghcr.io/goauthentik/server:2026.8.5 command: worker user: root restart: unless-stopped environment: *authentik-environment depends_on: postgresql: condition: service_healthy volumes: - data:/data - ./custom-templates:/templates - certs:/certs volumes: database: data: certs:
这里没有给 worker 挂载 Docker socket。当前基础部署不需要它自动管理其他容器。以后使用自动部署 Outpost 的功能时,再按需要配置。官方安装文档也说明了这一挂载的用途。
启动并检查服务:
bash12345docker compose config -q docker compose pull docker compose up -d docker compose ps curl -fsS http://127.0.0.1:19000/-/health/ready/
本文保留当时使用的版本。新装其他版本时,应使用对应版本的 Compose 和升级说明,不把不同版本的组件与存储目录混在一起。
2.3 HTTPS 与初始管理员
我使用 1Panel 的 OpenResty 配置 HTTPS 反向代理。示例站点为 auth.example.com,后端指向 http://127.0.0.1:19000,并开启 WebSocket 支持。需要保留请求的 Host,正确传递 X-Forwarded-Proto 和客户端转发信息,具体要求见 Authentik 反向代理文档。
这里的回环地址要求反向代理能访问宿主机网络。如果 OpenResty 运行在独立的 Docker bridge 网络里,容器内的 127.0.0.1 指向 OpenResty 自己,应另行配置可达的上游地址或共享 Docker 网络。
HTTPS 可用后,先从站点根地址进入,让当前版本的原生 Setup 入口启动初始化:
text1https://auth.example.com/
当前版本会检查初始化流程的启动上下文,不建议手工拼接 initial-setup URL 绕过入口。按向导设置 akadmin 的邮箱、密码和站点 Base URL,再进入管理员界面。这个账号保留本地登录方式,后续绑定外部身份时也从这个已登录的账号开始操作。
三、部署后的检查与备份
先验证本地密码登录、退出和重新登录,再修改流程。创建一个普通测试账号,保留管理员会话,用无痕窗口检查修改后的配置,避免把唯一的管理入口一起改坏。
备份范围包括 PostgreSQL、.env、Compose 文件、/data、自定义模板和证书挂载。数据库使用 pg_dump 等一致性备份,不直接复制运行中的数据库文件。示例在部署目录执行,备份保存在宿主机:
bash12345mkdir -p backups chmod 700 backups umask 077 docker compose exec -T postgresql pg_dump -U authentik -d authentik -Fc \ > "backups/authentik-$(date +%Y%m%d-%H%M%S).dump"
数据库备份含用户和敏感配置,不放到博客资源目录。升级前同时阅读目标版本的升级说明,server 和 worker 使用同一版本。
参考
支付宝
微信