Skip to content

bruceblink/Keylo

Repository files navigation

Keylo v1.1.1

Keylo 是一个轻量、可扩展的 统一认证与授权服务(Auth Service),为你的多服务系统提供统一的 JWT 签发、Session 管理和 OAuth 支持。

快速上手建议:


🚀 特性

  • ✅ 基于 RS256 的 JWT 签发与验证,内置 JWKS 公钥发布
  • /v1/auth/token(用户认证)、/v1/admin/token(管理令牌)、/v1/auth/refresh/v1/auth/logout/v1/auth/me 核心 API(当前 refresh 主要用于管理客户端链路)
  • ✅ 用户 Token 内省与服务 Token 内省
  • ✅ 服务凭证模式与 service_access Token
  • ✅ GitHub OAuth 登录,可扩展其他 OAuth 提供商
  • ✅ RBAC、管理员客户端、审计日志与黑名单机制
  • ✅ PostgreSQL 自动迁移,Redis 可选增强限流、锁定和 OAuth state
  • ✅ 使用 Axum 0.8 + Tokio 的模块化 Rust 服务架构
  • ✅ Docker / GHCR 镜像发布支持
  • ✅ 客户端密钥 bcrypt 哈希存储,杜绝明文泄露风险
  • ✅ 生产环境强制 Redis 限流,禁止降级为内存模式
  • ✅ 密码复杂度策略(大写、小写、数字、特殊字符)
  • ✅ OAuth state 原子消费(GETDEL),消除 TOCTOU 竞态
  • ✅ 服务 Token audience 严格校验
  • ✅ 数据库连接池大小可通过 DB_POOL_SIZE 环境变量配置

📋 前置要求

  • Rust 1.70+ (安装 Rust)
  • PostgreSQL 12+ (或使用 Docker)
  • Docker & Docker Compose (可选,用于本地开发)

🧪 测试

Keylo 包含完整的测试套件,包括单元测试、集成测试、数据库测试和负载测试。

运行所有测试

使用提供的测试脚本(推荐):

# Linux/macOS
./scripts/run_tests.sh

# Windows (PowerShell)
./scripts/run_tests.ps1

手动运行测试

  1. 启动测试数据库
docker run -d --name keylo-test-db \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=keylo_test \
  -p 5432:5432 postgres:15
  1. 设置环境变量
export TEST_DATABASE_URL="postgres://postgres:password@localhost:5432/keylo_test"
  1. 运行不同类型的测试
# 单元测试
cargo test --lib

# 集成测试
cargo test --test integration_test

# 数据库集成测试
cargo test --test database_integration_test

# 负载测试
cargo test --test load_test

# 所有测试
cargo test

测试覆盖率

生成测试覆盖率报告:

cargo install cargo-tarpaulin
cargo tarpaulin --out Html

CI/CD

项目包含 GitHub Actions CI/CD 配置,自动运行:

  • 代码格式检查 (cargo fmt)
  • 代码质量检查 (cargo clippy)
  • 安全审计 (cargo audit)
  • 完整测试套件
  • 覆盖率报告

第三方集成

第三方系统对接 Keylo 的登录流程、Token 内省和服务接入方式见 docs/THIRD_PARTY_INTEGRATION.md

多客户端统一用户池与 API 级授权接入说明见 docs/MULTI_CLIENT_RBAC_INTEGRATION.md

完整接口清单见 docs/API_REFERENCE.md

如果你是以 AgileBoot 这类 Spring Boot 管理后台接入 Keylo,可进一步参考 docs/AGILEBOOT_INTEGRATION.md

生产部署与发布说明

Keylo 的生产部署要求、发布能力边界和密钥轮换建议见以下文档:


🔧 开发

1. 克隆项目

git clone https://github.com/bruceblink/Keylo.git
cd keylo

2. 配置环境变量

复制 .env.example.env:

cp .env.example .env

编辑 .env 设置你的配置:

JWT_ISSUER=keylo
JWT_KEY_ID=keylo-rs256-1
# 生产环境建议使用路径方式加载 RSA 密钥
JWT_PRIVATE_KEY_PATH=./keys/private.pem
JWT_PUBLIC_KEY_PATH=./keys/public.pem
DATABASE_URL=postgres://keylo_user:keylo_password@localhost:5432/keylo
SERVER_ADDR=127.0.0.1
SERVER_PORT=2345
ENVIRONMENT=development

开发环境下如果未提供 RSA 密钥,Keylo 会使用内置开发密钥对;生产环境必须显式配置私钥和公钥。

3. 启动 PostgreSQL (使用 Docker Compose)

docker-compose up -d

这将启动:

  • PostgreSQL 数据库 (监听 5432)
  • Redis 服务 (监听 6379, 可选)

等待数据库准备好:

docker-compose ps

4. 构建并运行

cargo run

服务将在 http://127.0.0.1:2345 启动。

查看日志:

RUST_LOG=keylo=debug cargo run

🔑 API 快速指引

为避免 README 与实现长期漂移,完整接口说明统一收敛到专门文档:

常用接口(快速确认)

  • 公开:POST /v1/auth/tokenPOST /v1/admin/tokenPOST /v1/auth/refreshPOST /v1/service/token
  • 用户:GET /v1/auth/mePOST /v1/auth/logoutPOST /v1/user/change-password
  • 管理:/v1/admin/*/v1/admin/users/*/v1/admin/services/*
  • RBAC:/api/rbac/*
  • OAuth:公开流程 /v1/auth/oauth/*,管理接口 /api/oauth/*

Refresh Token 说明(重要)

当前实现中:

  • POST /v1/admin/token 返回 access_token + refresh_token
  • POST /v1/auth/token 当前仅返回 access_token

即:POST /v1/auth/refresh 所使用的 refresh_token 主要来源于管理客户端登录链路。


🏗️ 项目结构

src/
├── main.rs          # 启动入口,服务器初始化
├── lib.rs           # 库根模块
├── config.rs        # 环境配置管理
├── state.rs         # AppState 定义,应用全局状态
├── startup.rs       # 路由初始化,应用启动逻辑
├── db/              # 数据访问层
├── handlers/        # HTTP handlers
├── middleware/      # 鉴权与授权中间件
├── models/          # 领域模型
├── routes/          # 路由定义(auth/user/rbac/oauth/service)
├── errors.rs        # 错误定义
└── utils.rs         # 工具函数

docs/                # 对接、发布与运维文档
migrations/          # SQLx 迁移脚本
tests/               # 集成与负载测试
Dockerfile           # 容器镜像配置
docker-compose.yml   # 开发环境容器编排
Cargo.toml           # 项目依赖配置

🛠️ 技术栈

组件 技术 版本
Web 框架 Axum 0.8
异步运行时 Tokio 1.0
JWT jsonwebtoken 10
数据库 SQLx 0.8
数据库系统 PostgreSQL 12+
日志 tracing 0.1
序列化 serde 1.0

📝 环境变量配置

变量 默认值 说明
JWT_ISSUER keylo JWT 签发方
JWT_KEY_ID keylo-dev-rs256-1 JWKS 中公开的当前密钥 ID
JWT_PRIVATE_KEY_PATH `` RSA 私钥文件路径,生产推荐
JWT_PUBLIC_KEY_PATH `` RSA 公钥文件路径,生产推荐
JWT_PRIVATE_KEY_PEM `` RSA 私钥 PEM 内容,可替代路径
JWT_PUBLIC_KEY_PEM `` RSA 公钥 PEM 内容,可替代路径
DATABASE_URL postgres://user:password@localhost:5432/keylo 数据库连接字符串
SERVER_ADDR 127.0.0.1 服务器监听地址
SERVER_PORT 2345 服务器监听端口
ENVIRONMENT development 运行环境
TOKEN_EXPIRY_SECONDS 900 Token 过期时间(秒)
REFRESH_TOKEN_EXPIRY_SECONDS 2592000 刷新 Token 过期时间(秒)
MAX_FAILED_LOGIN_ATTEMPTS 5 连续登录失败锁定阈值
LOGIN_LOCKOUT_SECONDS 300 登录锁定时长(秒)
AUTH_RATE_LIMIT_WINDOW_SECONDS 60 登录限流窗口(秒)
AUTH_RATE_LIMIT_MAX_REQUESTS 30 限流窗口内单主体最大请求数
AUTH_GLOBAL_RATE_LIMIT_MAX_REQUESTS 300 限流窗口内全局最大请求数
ADMIN_CLIENT_ID `` 管理员客户端 ID(建议生产配置)
ADMIN_CLIENT_SECRET `` 管理员客户端密钥(建议生产配置)
REDIS_URL `` Redis 地址(配置后启用分布式状态存储)
REDIS_KEY_PREFIX keylo Redis key 前缀(多环境隔离)
DB_POOL_SIZE 10 数据库连接池最大连接数
AUDIT_LOG_RETENTION_DAYS 30 审计日志保留天数
SERVICE_TOKEN_EXPIRY_SECONDS 3600 服务 Token 过期时间(秒)
ENABLE_SUPER_ADMIN_BOOTSTRAP false 是否启用超级管理员首启引导
SUPER_ADMIN_USERNAME `` 超级管理员用户名(引导启用时)
SUPER_ADMIN_EMAIL `` 超级管理员邮箱(引导启用时)
SUPER_ADMIN_PASSWORD `` 超级管理员初始密码(引导启用时)
RUST_LOG keylo=debug 日志级别

🔐 JWKS

Keylo 默认使用 RS256 签发 JWT,并通过 /.well-known/jwks.json 暴露公开验签密钥集合。

  • 生产环境不要使用内置开发密钥
  • 下游系统推荐优先使用 JWKS 做本地验签
  • 需要统一吊销控制时,继续结合 /v1/auth/introspect/v1/service/introspect

RSA 密钥生成

本地开发如果不显式提供 RSA 密钥,Keylo 会回退到内置开发密钥;生产环境必须显式提供私钥和公钥。

推荐使用 OpenSSL 生成 2048 位或以上的 RSA 密钥对:

mkdir -p keys
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out keys/private.pem
openssl rsa -pubout -in keys/private.pem -out keys/public.pem

生成后建议检查文件内容:

openssl pkey -in keys/private.pem -text -noout
openssl pkey -pubin -in keys/public.pem -text -noout

如果在 Linux 服务器部署,建议进一步限制私钥权限:

chmod 600 keys/private.pem
chmod 644 keys/public.pem

随后配置环境变量:

JWT_KEY_ID=keylo-rs256-1
JWT_PRIVATE_KEY_PATH=./keys/private.pem
JWT_PUBLIC_KEY_PATH=./keys/public.pem

如果使用 Docker Compose,默认会把 ${JWT_KEYS_DIR:-./keys} 挂载到容器 /app/keys,因此容器内推荐配置为:

JWT_PRIVATE_KEY_PATH=/app/keys/private.pem
JWT_PUBLIC_KEY_PATH=/app/keys/public.pem

🩺 健康检查

Keylo 提供标准探针端点,便于容器编排和网关探活:

  • GET /healthz:进程存活检查(liveness)
  • GET /readyz:依赖就绪检查(readiness),会返回数据库/Redis 的检查状态

示例:

curl http://127.0.0.1:2345/healthz
curl http://127.0.0.1:2345/readyz

🗄️ 数据库迁移

服务启动时会自动执行 migrations/ 下的 SQLx 迁移,并初始化默认客户端。当前版本迁移覆盖用户、客户端、刷新 Token、OAuth、RBAC、审计日志和服务客户端等核心表结构。


测试命令与测试脚本请以本文前面的“🧪 测试”章节为准。


🐳 使用 Docker 部署

使用 GitHub Container Registry 镜像

docker pull ghcr.io/bruceblink/keylo:v1.1.1

运行容器

docker run --rm -p 2345:2345 \
  -v $(pwd)/keys:/app/keys:ro \
  -e ENVIRONMENT=production \
  -e JWT_ISSUER=keylo \
  -e JWT_KEY_ID=keylo-rs256-1 \
  -e JWT_PRIVATE_KEY_PATH=/app/keys/private.pem \
  -e JWT_PUBLIC_KEY_PATH=/app/keys/public.pem \
  -e DATABASE_URL="postgres://keylo_user:keylo_password@db:5432/keylo" \
  -e ADMIN_CLIENT_ID="cli-admin-root" \
  -e ADMIN_CLIENT_SECRET="replace-with-strong-admin-secret" \
  -e REDIS_URL="redis://redis:6379" \
  ghcr.io/bruceblink/keylo:v1.1.1

本地构建镜像

docker build -t keylo:latest .

Docker Compose 开发依赖

docker-compose up -d
docker-compose ps
docker-compose logs -f postgres

如果你希望在容器中直接运行 Keylo,请确保同时提供 PostgreSQL、Redis 和 RSA 密钥文件;生产环境不再支持 JWT_SECRET 这种共享密钥模式。

当前仓库的 docker-compose.yml 默认按生产模板组织:

  • keylo 服务默认监听 0.0.0.0:2345
  • compose 与本地统一使用同名变量(如 DATABASE_URLREDIS_URL),按运行场景调整取值
  • 默认要求提供管理客户端(ADMIN_CLIENT_ID / ADMIN_CLIENT_SECRET
  • 默认挂载 ${JWT_KEYS_DIR:-./keys}/app/keys
  • Redis 默认启用,满足生产环境的限流、登录锁定和 OAuth state 依赖

首次在服务器部署时,建议先准备 .env 或 shell 环境变量,再执行:

docker compose down -v --remove-orphans
docker compose up -d --build
docker compose logs -f keylo-service

✨ 当前核心能力

1. 统一认证

  • 支持用户登录、客户端登录和用户注册
  • 支持 Access Token / Refresh Token(当前 refresh 主要用于管理客户端链路)
  • 支持 me、登出和黑名单

2. 服务间鉴权

  • 支持服务客户端注册与密钥轮换
  • 支持 service_access Token 签发
  • 支持服务 Token 内省与用户 Token 内省

3. 第三方集成

  • 默认使用 RS256 与 JWKS
  • 下游系统可本地验签
  • 高敏接口可叠加内省做实时吊销校验

4. 运维与安全基线

  • 启动时自动执行 SQLx 迁移
  • 生产环境强制要求显式 RSA 密钥、管理员客户端和 Redis
  • 支持审计日志、限流、登录锁定和 OAuth state 管理

🚦 演进方向

后续增强方向:

  • 多把 RSA 密钥并行发布
  • 自动密钥轮换流程
  • 更细粒度的健康检查与 readiness 探针
  • 更完善的网关接入样例

📖 开发指南

添加新的认证 Provider

src/routes/oauth.rs 和对应 handler 中注册新的 OAuth 提供商逻辑。

自定义 Claims

编辑 src/models/jwt.rs 中的 Claims 结构与签发逻辑,并同步评估内省与下游验签兼容性。

数据库操作

新增表结构时,优先在 migrations/ 中追加 SQLx 迁移,再更新 src/db/ 下的数据访问层。


⚠️ 安全建议

  1. 生产环境:
  • 使用 RSA 2048 位或更高密钥
  • 私钥只保留在 Keylo 服务端
  • 设置 ENVIRONMENT=production
  • 显式配置 ADMIN_CLIENT_IDADMIN_CLIENT_SECRETREDIS_URL
  • 为外部访问启用 HTTPS 和反向代理
  1. 下游系统:
  • 优先通过 JWKS 获取公钥并做本地验签
  • kid 不匹配或验签失败时刷新 JWKS 缓存
  • 对强实时吊销场景补充调用内省接口
  1. 数据库与运行环境:
  • 使用强数据库密码并限制网络暴露
  • 定期备份 PostgreSQL 数据
  • 不要在生产环境启用开发密钥或数据库失败回退模式

🤝 贡献

欢迎提交 Issue 和 Pull Request,详细开发约定见 CONTRIBUTING.md


📄 许可证

MIT License - 查看 LICENSE 文件


💬 支持


Last Updated: 2026年04月17日

About

Keylo 是一个轻量、可扩展的 统一认证与授权服务(Auth Service),为你的多服务系统提供统一的 JWT 签发、Session 管理和 OAuth 支持。

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages