Authelia CLI 实战:authelia storage user webauthn 子命令与 WebAuthn 凭据的数据库级管理
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
本文基于 Authelia 官方 CLI 参考文档 authelia_storage_user_webauthn.md,系统讲解authelia storage user webauthn这一组面向数据库的 WebAuthn(FIDO2/Passkey)凭据管理子命令:涵盖 list、verify、delete、export、import 五个子命令的完整用法、继承的全局参数(存储连接与加密密钥),并结合 internal/commands/storage_run.go 的源码实现,说明每个子命令背后的调用链、导出文件格式与凭据数据模型,帮助你完成凭据巡检、密钥校验、迁移备份与故障恢复等真实运维场景。
1. 命令定位:storage 命令树中的 WebAuthn 凭据管理
authelia storage user webauthn是 Authelia CLI 中storage命令树的一个分支,专门用于"直接对数据库"管理 WebAuthn 凭据——即用户在 Authelia 门户注册的 Passkey/FIDO2 安全密钥、硬件 U2F 设备等第二因素凭据。它与 TOTP(authelia storage user totp)和 opaque identifiers(authelia storage user identifiers)并列为storage user下的三类管理对象,命令注册逻辑见 internal/commands/storage.go:
func newStorageUserCmd(ctx *CmdCtx) (cmd *cobra.Command) { cmd = &cobra.Command{ Use: cmdUseUser, // "user" Short: cmdAutheliaStorageUserShort, // ... } cmd.AddCommand( newStorageUserIdentifiersCmd(ctx), newStorageUserTOTPCmd(ctx), newStorageUserWebAuthnCmd(ctx), ) return cmd }webauthn子组本身是一个无操作的分组命令(Args: cobra.NoArgs),只有执行--help或列出子命令的用途,其下挂有 5 个真正执行的叶子命令(见 internal/commands/storage.go#L513-L533):
| 子命令 | 功能 | 定义位置 |
|---|---|---|
list [username] | 列出 WebAuthn 凭据(全部或按用户) | newStorageUserWebAuthnListCmd |
verify | 校验已注册凭据(MDS3 元数据 / AAGUID / 备份策略) | newStorageUserWebAuthnVerifyCmd |
delete [username] | 删除 WebAuthn 凭据(按用户/KID/描述符) | newStorageUserWebAuthnDeleteCmd |
export | 导出全部 WebAuthn 凭据为 YAML | newStorageUserWebAuthnExportCmd |
import <filename> | 从 YAML 文件导入 WebAuthn 凭据 | newStorageUserWebAuthnImportCmd |
命令的短描述与长描述集中定义在 internal/commands/const.go#L328-L393,与官方参考文档中的 Synopsis 一一对应:
Manage WebAuthn credentials. This subcommand allows interacting with WebAuthn credentials.运行前的统一前置流程
所有storage子命令共享一条PersistentPreRunE链(见 internal/commands/storage.go#L16-L31):
PersistentPreRunE: ctx.ChainRunE( ctx.ConfigStorageCommandLineConfigRunE, // 1. 命令行 flag 映射到配置字段 ctx.HelperConfigLoadRunE, // 2. 加载配置文件 ctx.ConfigValidateStorageRunE, // 3. 校验 storage 配置 ctx.LoadProvidersStorageRunE, // 4. 建立存储连接 ),其中第 1 步由 ConfigStorageCommandLineConfigRunE 实现,它把命令行 flag 逐一映射到配置树的具体路径——这解释了为什么文档中"Options inherited from parent commands"里那些--mysql.*、--postgres.*、--sqlite.path、--encryption-key等 flag 能直接覆盖配置文件:
flagsMap := map[string]string{ cmdFlagNameEncryptionKey: "storage.encryption_key", cmdFlagNameSQLite3Path: "storage.local.path", cmdFlagNameMySQLAddress: "storage.mysql.address", // ... postgres 系列同理 }第 3 步 ConfigValidateStorageRunE 会对storage与totp段执行校验器检查;第 4 步 LoadProvidersStorageRunE 在加载可信证书(供 MDS3 元数据签名校验使用)成功后调用getStorageProvider建立数据库连接。每个叶子命令执行完毕都会通过defer关闭存储连接。
此外,每个真正执行数据库操作的 RunE 内部还会先调用ctx.CheckSchema()确认 schema 处于可用状态,失败时统一包装为storageWrapCheckSchemaErr错误返回——这意味着在空库或未迁移的库上执行这些命令会得到明确的 schema 错误,而不是静默的无结果。
2. 命令自身的选项与继承选项(完整继承自参考文档)
2.1 webauthn 分组命令选项
参考文档给出的原始用法示例:
authelia storage user webauthn --help分组命令本身只有帮助选项:
-h, --help help for webauthn2.2 从父命令继承的选项
以下继承选项来自storage父命令(--config/--config.experimental.filters来自更上层的authelia根命令),是这组子命令连接数据库的唯一途径,完整继承自参考文档:
-c, --config strings configuration files or directories to load, for more information run 'authelia -h authelia config' (default [configuration.yml]) --config.experimental.filters strings list of filters to apply to all configuration files, for more information run 'authelia -h authelia filters' --encryption-key string the storage encryption key to use --mysql.address string the MySQL server address (default "tcp://127.0.0.1:3306") --mysql.database string the MySQL database name (default "authelia") --mysql.password string the MySQL password --mysql.username string the MySQL username (default "authelia") --postgres.address string the PostgreSQL server address (default "tcp://127.0.0.1:5432") --postgres.database string the PostgreSQL database name (default "authelia") --postgres.password string the PostgreSQL password --postgres.schema string the PostgreSQL schema name (default "public") --postgres.username string the PostgreSQL username (default "authelia") --sqlite.path string the SQLite database path这些 flag 的注册与默认值定义在 internal/commands/storage.go#L33-L46,与文档完全一致。使用要点:
- 存储类型(SQLite / MySQL / PostgreSQL)及连接参数二选一即可,其余存储段的 flag 会被配置校验忽略;
--encryption-key对应storage.encryption_key,是解密凭据中加密字段所必需的密钥。如果生产配置启用了存储加密而 CLI 未带此 flag,读取到的凭据字段将无法正确还原,因此所有官方示例都把--encryption-key与数据库地址放在同一条命令中出现;--config支持文件与目录,默认查找configuration.yml。
3. 凭据数据模型:list/verify 输出中每个字段从哪里来
理解子命令输出的前提是了解凭据如何存储在数据库中。核心结构体 model.WebAuthnCredential 定义了webauthn_credentials表的行模型:
// WebAuthnCredential represents a WebAuthn Credential in the database storage. type WebAuthnCredential struct { ID int `db:"id"` CreatedAt time.Time `db:"created_at"` LastUsedAt sql.NullTime `db:"last_used_at"` RPID string `db:"rpid"` Username string `db:"username"` Description string `db:"description"` KID Base64 `db:"kid"` AAGUID uuid.NullUUID `db:"aaguid"` AttestationType string `db:"attestation_type"` AttestationFormat string `db:"attestation_format"` Attachment string `db:"attachment"` Transport string `db:"transport"` SignCount uint32 `db:"sign_count"` CloneWarning bool `db:"clone_warning"` // ... 还有 Discoverable、BackupEligible、BackupState、PublicKey、Attestation 等字段 }其中几个字段对后续 CLI 操作意义最大:
- KID:凭据标识(credential id 的 Base64 表示),
delete --kid就是按它定位凭据; - Description:用户注册时自定义的描述符,
delete --description按它 + 用户名定位; - RPID:Relying Party ID,即注册该凭据时使用的域名/站点,在
list(无用户名形式)中输出; - AAGUID:认证器厂商全局唯一标识,是
verify命令做 AAGUID 过滤的核心输入; - SignCount / CloneWarning:签名计数器与克隆告警,每次通过该凭据登录成功后由 UpdateSignInInfo 更新。
4. list 子命令:列出 WebAuthn 凭据
list接受 0 到 1 个用户名参数(cobra.MaximumNArgs(1)),实现入口是 StorageUserWebAuthnListRunE:不带参数时走"全量分页"路径,带参数时按用户名查询。
4.1 不带用户名:全库列出
authelia storage user webauthn list authelia storage user webauthn list --config config.yml authelia storage user webauthn list --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.address tcp://postgres:5432 --postgres.password autheliapw输出表头为ID RPID KID Description Username(见 runStorageUserWebAuthnListAll),内部以limit = 10分页循环调用store.LoadWebAuthnCredentials(ctx, limit, page)直到某一页不足 10 条;若第一页即为空则报错no WebAuthn credentials in database。
4.2 带用户名:按用户列出
authelia storage user webauthn list john authelia storage user webauthn list john --config config.yml authelia storage user webauthn list john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.address tcp://postgres:5432 --postgres.password autheliapw按用户查询走store.LoadWebAuthnCredentialsByUsername,输出表头为ID KID Description(见 runStorageUserWebAuthnList)。当用户不存在或没有任何凭据时,命令返回错误user '<username>' has no WebAuthn credentials(底层对应storage.ErrNoWebAuthnCredential错误)。
排查技巧:ID和KID两列是后续delete --kid操作所需的关键输入,list通常作为删除前确认目标的第一步。
5. verify 子命令:批量校验已注册凭据
authelia storage user webauthn verifyverify是这组命令中最具"审计"性质的一个,它对数据库中每一条凭据运行校验逻辑,输出表头为ID RPID KID Username AAGUID Statement Backup MDS(见 runStorageUserWebAuthnVerify)。各列含义及判定依据(源码 internal/webauthn/credential.go#L18-L71):
| 输出列 | 来源标志位 | 判定逻辑 |
|---|---|---|
| AAGUID | IsProhibitedAAGUID | 配置了permitted_aaguids白名单时,凭据 AAGUID 不在白名单内判 No;或命中prohibited_aaguids黑名单判 No |
| Statement | MissingStatement | 凭据的attestation字段为空(缺少认证声明)判 No |
| Backup | IsProhibitedBackupEligibility | 配置了prohibit_backup_eligibility: true而凭据声明BackupEligible时判 No |
| MDS | Malformed/MetaDataValidationError | 凭据无法还原为有效 credential 显示Malformed;MDS3 元数据校验失败显示 No |
verify的过滤规则直接读取webauthn.filtering配置段,其结构定义在 internal/configuration/schema/webauthn.go#L54-L59:
type WebAuthnFiltering struct { ProhibitBackupEligibility bool `yaml:"prohibit_backup_eligibility"` // 禁止声明可备份(可导出)的认证器 PermittedAAGUIDs []uuid.UUID `yaml:"permitted_aaguids,omitempty"` // AAGUID 白名单 ProhibitedAAGUIDs []uuid.UUID `yaml:"prohibited_aaguids,omitempty"` // AAGUID 黑名单 }5.1 --verbose 与 MDS3 依赖
verify支持--verboseflag(注册于 storage.go#L594)。开启后会额外打印每条凭据的元数据校验错误明细:
Metadata Errors: Credential ID: 12: <error details>注意:MDS 列依赖 WebAuthn MetaDataProvider 的加载,因此命令会先调用webauthn.NewMetaDataProvider(config, store);若凭据元数据缓存未初始化,该列将显示na。MDS3 缓存的维护有专门的配套命令(authelia storage cache mds3 status|update|dump|delete),verify输出大面积 MDS=No 时,可先用这些命令检查缓存是否过期。
6. delete 子命令:三种定位方式删除凭据
authelia storage user webauthn delete john --all authelia storage user webauthn delete john --description Primary authelia storage user webauthn delete --kid abc123delete支持 0 或 1 个用户名参数(cobra.MaximumNArgs(1)),并配有三个 flag(注册于 storage.go#L611-L613):
| Flag | 作用 | 实现 |
|---|---|---|
--all | 删除该用户全部WebAuthn 凭据 | store.DeleteWebAuthnCredentialByUsername(ctx, user, "") |
--description <text> | 按用户 + 描述符删除单个凭据 | store.DeleteWebAuthnCredentialByUsername(ctx, user, description) |
--kid <id> | 按 KID(凭据 ID)直接删除,可跨用户 | store.DeleteWebAuthnCredential(ctx, kid) |
实现见 runStorageUserWebAuthnDelete:--kid路径与用户名路径互斥分流,成功后分别打印Successfully deleted WebAuthn credential with key id '<kid>'、Successfully deleted all WebAuthn credentials for user '<username>'或Successfully deleted WebAuthn credential with description '<desc>' for user '<user>'。
使用注意:--all属于破坏性操作且不可回滚(除非事先做过 export)。稳妥流程是先list john确认凭据清单,必要时export备份,再执行删除;--description的值必须与注册时设置的描述完全一致,可通过list的 Description 列核对。
7. export 子命令:全量导出凭据为 YAML
authelia storage user webauthn export authelia storage user webauthn export --file authelia.export.webauthn.yml authelia storage user webauthn export --config config.ymlexport不带参数(cobra.NoArgs),唯一的 flag 是--file/-f,默认导出文件名为authelia.export.webauthn.yml(见 storage.go#L562)。实现细节见 runStorageUserWebAuthnExport:
- 拒绝覆盖:执行前先用
os.Stat检查目标文件,若已存在直接报错must specify a file that doesn't exist but '<file>' exists,防止误覆盖既有备份; - 分页全量读取:与
list相同,以每页 10 条循环store.LoadWebAuthnCredentials拉全量数据; - 空库保护:没有任何凭据时报错
no data to export; - 安全落盘:文件以权限
0600创建,内容通过exportYAMLWithJSONSchema(f, "export.webauthn", export)写入,即导出文件内嵌 JSON Schema 注释(export.webauthn为该 schema 标识),便于导入侧做结构校验。
导出结构由 model.WebAuthnCredentialExport 定义,即一个webauthn_credentials列表,每行字段与数据模型一致(rpid、username、description、kid、aaguid、public_key、attestation等),因此导出文件包含完整的公钥与认证声明数据,必须按敏感信息保管,权限位0600正是这个原因。
典型备份脚本流程:
# 1. 备份(若目标文件已存在会报错,需先移走旧文件) authelia storage user webauthn export --file backup/$(date +%Y%m%d).webauthn.yml \ --config configuration.yml --encryption-key '<key>' --postgres.address tcp://db:5432 # 2. 确认行数 authelia storage user webauthn list --config configuration.yml --encryption-key '<key>'8. import 子命令:从 YAML 恢复凭据
authelia storage user webauthn import <filename> authelia storage user webauthn import authelia.export.webauthn.yml --config config.yml authelia storage user webauthn import authelia.export.webauthn.yml \ --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 \ --postgres.address tcp://postgres:5432 --postgres.password autheliapwimport采用位置参数(注意与export的--fileflag 不同),命令签名为import <filename>(cmdUseImportFileName,见 const.go#L883),且cobra.ExactArgs(1)强制恰好一个参数。实现见 runStorageUserWebAuthnImport:
os.Stat校验文件存在且不是目录,分别给出明确错误信息;- 读取文件并
yaml.Unmarshal到model.WebAuthnCredentialExport; - 空数据保护:
can't import a YAML file without WebAuthn credentials data; - 逐条调用
store.SaveWebAuthnCredential(ctx, credential)写入数据库——采用逐条保存策略,中途失败会抛出错误并保留已完成的部分导入,因此恢复中断后可用list核对缺口再补导。
迁移场景示例(数据库换库/换存储后端时的凭据搬迁):
# 旧库:导出 authelia storage user webauthn export --config old-config.yml --encryption-key '<old-key>' # 新库:导入 authelia storage user webauthn import authelia.export.webauthn.yml \ --config new-config.yml --encryption-key '<new-key>' --sqlite.path /data/new.db # 两侧 list 对比 ID/KID 数量是否一致 authelia storage user webauthn list --config new-config.yml注意 import 不校验源与目标用户来源(如 LDAP 用户名是否一致),恢复后建议对关键用户执行list <username>抽查。
9. 与其他相关命令的关系(SEE ALSO)
参考文档的 SEE ALSO 一节列出了本命令组的全部关联入口(均位于 docs/content/reference/cli/authelia/):
- authelia storage user — Manages user settings
- authelia storage user webauthn delete — Delete a WebAuthn credential
- authelia storage user webauthn export — Perform exports of the WebAuthn credentials
- authelia storage user webauthn import — Perform imports of the WebAuthn credentials
- authelia storage user webauthn list — List WebAuthn credentials
- authelia storage user webauthn verify — Verify WebAuthn credentials
从源码结构看,WebAuthn 凭据的日常注册/注销发生在 Web 门户(对应 internal/handlers/handler_register_webauthn.go 与 internal/handlers/handler_webauthn_credentials.go),而storage user webauthn这组 CLI 是面向管理员的"绕过 UI"通道:适合自动化巡检(list/verify接入监控)、故障恢复(export/import)与强制清理(delete)。
10. 常见失败模式速查
| 现象 | 原因 | 处理 |
|---|---|---|
schema 相关报错(CheckSchema包装错误) | 数据库未初始化或 schema 版本过低 | 先执行authelia storage migrate up检查/迁移 |
user 'x' has no WebAuthn credentials | 用户未注册过凭据或用户名拼写错误 | 用list(无参)核对实际用户名 |
| 导出的凭据字段乱码/解密失败 | 未提供--encryption-key或 key 与配置不一致 | 带上与生产一致的--encryption-key重新执行 |
must specify a file that doesn't exist but ... | export 目标文件已存在 | 改名或移走旧备份文件后重试 |
no WebAuthn credentials in database | 库内无凭据(export/list-all/verify 均会遇到) | 属正常提示,无需处理 |
verify 大面积MDS = Malformed / No | MDS3 缓存缺失、过期或凭据数据不完整 | 用authelia storage cache mds3 status检查缓存,必要时update |
以上所有命令行为均可在 internal/commands/storage_run_test.go 的测试用例中找到对应的断言覆盖,可作为行为基线参考。
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考