Skip to content

Sign-in and 2FA ​

The login title is Sign in to KiriVers. Flow: password → enroll or second factor (pending TTL: security.login_pending_ttl_seconds) → full session. Idle sliding TTL: security.session_idle_hours. Admin auth uses an opaque cached session token — the random string carried in Authorization: Bearer.

Who can open this: anyone who can reach the admin plane (default http://127.0.0.1:8081). Create the first account with Bootstrap the first admin.

First sign-in ​

  1. Enter Username and Password, then Sign in.
  2. First visit must Set up authenticator: scan or type the secret, enter the 6-digit code, then Confirm TOTP.
  3. Save recovery codes (shown once). Check I have saved these recovery codes, then Continue.
  4. Add a passkey (optional) appears. Use Register passkey, or Skip. Add passkeys later under Account security.

Too many TOTP tries in one 30s window: TOTP_RATE_LIMITEDTOTP attempts exhausted in one 30s period.

Configure passkeys (WebAuthn) ​

Passkeys need both system YAML keys. If security.webauthn_rp_id or security.webauthn_origins is empty, Passkey routes return NOT_READYService or Passkey not ready. Either empty webauthn_rp_id or webauthn_origins makes Passkey routes return this code (HTTP 503) (HTTP 503). TOTP and recovery codes still work.

The console then shows: “WebAuthn is not configured on the server, so passkeys cannot be added. TOTP and recovery codes still work.”

KeyTypeDefaultMeaningWhen to changeFailure
security.webauthn_rp_idstring""Relying-party ID: hostname without scheme or portTo enable passkeysEmpty → NOT_READYService or Passkey not ready. Either empty webauthn_rp_id or webauthn_origins makes Passkey routes return this code (HTTP 503)
security.webauthn_originsstring[][]Full Origin list (scheme + host + port)Must match the browser OriginEmpty or mismatch → browser reject or NOT_READYService or Passkey not ready. Either empty webauthn_rp_id or webauthn_origins makes Passkey routes return this code (HTTP 503)

Example (local admin plane http://localhost:8081):

yaml
# 进程级系统配置。监听地址与 TLS 在 admin.yaml / client.yaml,本文件不含 addr。
# -config 可指向本文件或其所在目录;同目录还需 admin.yaml 与 client.yaml。
# 环境变量前缀 KIRIVERS_(例:postgres.dsn → KIRIVERS_POSTGRES_DSN)。
# 控制台为 Zerolog ConsoleWriter(stderr,默认着色);文件为 JSON + 按大小滚动。

log:
  # 非法级别回退 info。示例用 debug 便于本机;Viper 默认 info。
  level: debug
  console:
    enabled: true
    no_color: false
  file:
    enabled: true
    dir: ./logs
    filename: kirivers.log
    max_size_mb: 100
    max_backups: 10
    max_age_days: 28
    compress: true
    local_time: true

# 与 dev/docker/compose.yml 中 PostgreSQL 服务一致,供本机开发。
# 生产环境请用环境变量 KIRIVERS_POSTGRES_DSN 覆盖,勿提交真实密钥到 config.yaml。
postgres:
  dsn: "host=127.0.0.1 user=kirivers password=8WdeOilkFYo6OcBE3bdmg2 dbname=kirivers port=5432 sslmode=disable TimeZone=Asia/Shanghai"

storage:
  driver: local
  local:
    root: ./data/storage
  s3:
    endpoint: ""
    region: auto
    bucket: ""
    access_key: ""
    secret_key: ""
    use_path_style: true
    # 公共产物 CDN 前缀;空则按 endpoint+bucket 拼匿名 GET URL。环境变量 KIRIVERS_STORAGE_S3_PUBLIC_BASE_URL。
    public_base_url: ""
  # 私有后端桶(GeoIP MMDB)。driver=s3 且未配 bucket 时 GeoIP 上传失败,不得写入公共桶。
  # 环境变量 KIRIVERS_STORAGE_PRIVATE_*。
  # private:
  #   endpoint: ""
  #   region: auto
  #   bucket: kirivers-private
  #   access_key: ""
  #   secret_key: ""
  #   use_path_style: true

# 本节点可选显示名(仅管理台节点列表;空则显示 UUID)。环境变量 KIRIVERS_NODE_DISPLAY_NAME。
node:
  display_name: ""

# 多节点下载方式,仅 storage.driver=s3 且 cache.driver=redis 时生效。s3=公共直链,local=本机代拉。
# 环境变量 KIRIVERS_CLUSTER_DOWNLOAD。
cluster:
  download: s3

security:
  # 完整管理会话空闲滑动 TTL;每次命中按当前时刻续期。管理员鉴权查缓存中的会话 Token(不透明随机串)。
  session_idle_hours: 72
  # 密码成功后的受限 token(强制绑定 / 第二因素),到期须重新密码登录。
  login_pending_ttl_seconds: 600
  # 同一 TOTP 时间步(30s)内允许的校验次数;超限返回 TOTP_RATE_LIMITED。
  totp_max_attempts_per_period: 10
  # WebAuthn 依赖方。rp_id 为空时 Passkey 接口返回 NOT_READY,TOTP 登录仍可用。
  webauthn_rp_id: ""
  webauthn_origins: []

# 私有存储短时签名 URL 的实例级 HMAC 密钥(docs/app-init.md 13.7 / C15-1)。
# 未配置时进程启动生成临时随机值并告警——重启即全部已签发 URL 失效;
# 生产环境必须显式配置(或使用环境变量 KIRIVERS_URL_SIGNING_SECRET)。
url_signing_secret: ""

jobs:
  workers: 2

# 多文件客户端 fileset 动态打包未压缩硬顶(D6)。差异路径 Manifest size 去重合计
# ≥ 该值则不入队、立即 full_package。环境变量 KIRIVERS_DYNAMIC_PACK_MAX_BYTES。
dynamic_pack:
  max_bytes: 536870912

# 原生 file_list 待下载条数平台天花板。项目可下调(0=继承),不得超出。
# 环境变量 KIRIVERS_FILE_LIST_MAX_FILES。加载后 <1 回退 16。
file_list:
  max_files: 16

# 原生 changelog 条数窗口。无 from_version 用 default_entries;有 from_version 用 max_entries 截断。
# 加载后 <1 回退 5 / 50。若 default_entries > max_entries,config.Load 失败,进程不监听。
# 环境变量 KIRIVERS_CHANGELOG_DEFAULT_ENTRIES / KIRIVERS_CHANGELOG_MAX_ENTRIES。
changelog:
  default_entries: 5
  max_entries: 50

# 热路径(Resolve / LoadCatalog)缓存。默认 memory,不连接 Redis,便于无 Redis 本机启动。
# driver=redis 时启动必须 Ping 成功,否则进程以非 0 退出且不监听(与 Postgres 宕机仍监听不同)。
# 运行中 Redis 失败会回退到进程内内存,并按 reconnect_interval_minutes 重连;成功后清空 kirivers: 前缀再切回。
# 目录快照含签名私钥,生产 Redis 必须设密码,禁止对不可信租户共享。
# 本地 docker Redis:docker compose -f dev/docker/compose.yml up -d
# 密码用环境变量覆盖,勿把 dev/docker/redis.conf 的 requirepass 当作生产密钥写进本文件:
#   KIRIVERS_CACHE_REDIS_PASSWORD
cache:
  driver: memory  # memory | redis
  redis:
    addr: "127.0.0.1:6379"
    password: ""
    db: 0
    reconnect_interval_minutes: 10

Set webauthn_rp_id to localhost (or a public hostname such as updates.example.com) and webauthn_origins to a full Origin such as http://localhost:8081. Restart the process after editing YAML.

HTTPS

Non-localhost origins need an HTTPS secure context. http://localhost:8081 is allowed.

yaml
security:
  webauthn_rp_id: localhost
  webauthn_origins:
    - http://localhost:8081
yaml
security:
  webauthn_rp_id: updates.example.com
  webauthn_origins:
    - https://updates.example.com

YAML: Security settings.

Account security (add or delete later) ​

User menu Account security (/security) is not a drawer item. Copy states this does not kick other sessions.

  1. Open Account security.
  2. Under Passkeys, click Add passkey, set Passkey name, complete the browser prompt.
  3. Delete with Delete passkey. Sessions stay signed in; TOTP is not removed.
  4. Rotate TOTP / Regenerate recovery codes also leave other sessions signed in.

If WebAuthn is not configured, Add passkey is unavailable and the console message quoted above is shown. TOTP and recovery codes still work.

clear-2fa ​

bash
kirivers admin clear-2fa alice

Clears TOTP, passkeys, and recovery codes for that account. It does not revoke existing sessions. The next sign-in must enroll TOTP again. See Bootstrap the first admin.