bogdanticu88/Tessera

GitHub: bogdanticu88/Tessera

Tessera 是构建于 OpenFGA 之上的 M2M API 授权控制平面,通过关系 tuple 实现实时按请求授权和精准的客户端终止能力。

Stars: 0 | Forks: 0

Tessera

CI .NET 8 OpenFGA License: MIT

# Tessera Tessera 是一个基于关系的授权控制平面,专为机器到机器 (M2M) API 设计,构建于 [OpenFGA](https://openfga.dev) 之上。它位于你的授权引擎旁边,从不处于请求的热路径上,并确保每个请求检查所读取的关系数据是正确、最新且可由运维人员控制的。其核心特性是一个精准的熔断开关:吊销客户端只需删除单个 tuple,因此下一次实时检查会将其拒绝,无需进行 token 吊销、缓存刷新或重新部署。 ## 它解决什么问题 大多数 M2M 集成会颁发长期有效的 bearer token(例如 90 分钟)。如果其中一个泄露,你必须与攻击者赛跑,在其过期前检测并吊销它。Tessera 改变了这个模型: - token 只是资格证明。授权是在每次请求时,通过 Tessera 管理的关系 tuple 进行 OpenFGA 检查来实时决定的。 - 终止一个客户端意味着删除它的 tuple。token 在加密上依然有效,但下一次检查将返回拒绝 (deny)。吊销是即时且精准的:仅针对单一客户端,不会影响任何其他客户端。 - Tessera 保持在热路径之外。你的网关直接调用 OpenFGA。Tessera 只负责管理状态:开通客户端、从 GitOps 调和授权、发送审计以及执行终止操作。 ## 功能 ### 实时的按请求授权 授权在每次请求时通过 OpenFGA 检查进行评估。刻意不设置长期有效的允许缓存,因此授权状态的变更会在下一次请求时立即生效。 ### 精准的熔断开关 终止操作会删除客户端的 tuple 并确认它们已被移除。它只影响确切的某一个客户端,且不会触及任何 token。恢复操作将通过声明的意图重新进行授权。 ### 幂等的 GitOps 调和 声明的授权通过差异(写入“期望状态减去现有状态”,删除“现有状态减去期望状态”,并首先进行去重)进行调和。相同的代码既运行在真实的 OpenFGA(其写入和删除并非幂等)上,也运行在内存中的参考存储上。 ### 规范化的身份解析 无论网关看到的是什么(application id、subscription key、certificate thumbprint),都会被标准化为一个规范的客户端引用,并附带一个用于控制高风险操作的保障级别。 ### 持久的终止哨兵 终止操作会首先设置一个持久的哨兵 (sentinel),然后才会触及任何 tuple。调和过程会遵循该哨兵,且绝不会复活已被终止的客户端。 ### 可插拔的存储和接收器 核心仅依赖于接口:`IAuthorizationStore`、`IClientRegistry`、`IIdentityResolver`、`IAuditSink` 和 `IClientLock`。项目自带内存中的参考实现,因此开箱即用;你可以在不修改核心代码的情况下提供生产环境实现。 ## 架构 Tessera 分离了两个平面。你的网关和 OpenFGA 处理请求的热路径。Tessera 管理这些检查所读取的状态。 ``` flowchart LR C[Client] --> GW[Gateway] GW --> FGA[(OpenFGA check)] FGA -->|allow| BE[Backend] FGA -->|deny| X[403] OP[Operator / GitOps / CLI] --> T[Tessera control plane] T --> REG[(Client registry and sentinels)] T --> AUD[(Audit sink)] T -->|write and delete tuples, the kill switch| FGA ``` 声明的意图按如下方式映射到 OpenFGA 的 tuple。HTTP 方法是关系 (relation),而不是对象 id 的一部分,因为 OpenFGA 的对象 id 只允许包含一个冒号。 | 概念 | OpenFGA 结构 | |---------|---------------| | 客户端 | user `client:{client_ref}` | | api group 的成员关系 | `client:{ref}` relation `member` object `api_group:{group}` | | 特定 endpoint 上的授权 | `client:{ref}` relation `{method}` object `api_endpoint:{canonical_path}` | | 业务单元分组 | `client:{ref}` relation `member_of` object `bu_group:{bu}` | 参考实现所执行的设计不变量: 1. 每个客户端引用的互斥性。每个变更路径都会按客户端进行序列化,因此终止和授权操作不会交错。单副本使用进程内锁;多副本使用数据库咨询锁。 2. 幂等的调和差异。所有 tuple 变更都会经过差异计算,因此在非幂等引擎上重新运行也是安全的。 3. 调和永远不会复活已终止的客户端。被终止的客户端会保留其哨兵,并被调和过程跳过。 4. 单一的规范形式。网关为检查而构建的字符串与 Tessera 写入的字符串在字节上是完全一致的,全程使用序号比较 (ordinal comparison),因为 OpenFGA 是大小写敏感的。 5. 哨兵优先的终止。持久的哨兵会在任何 tuple 被删除之前设置,这正是使终止操作在面对并发授权时依然安全的原因。 ## 要求 - .NET 8 SDK - 一个 OpenFGA 实例(通过下方的 Docker Compose 提供) - 用于本地技术栈的 Docker 和 Docker Compose(可选,用于真实的引擎) ## 使用 Docker Compose 快速开始 1. 启动 OpenFGA: docker compose up -d 2. 运行示例,它将执行以下操作:注册一个客户端,授权一个 endpoint,运行检查(允许),终止该客户端(删除 tuple),再次检查(拒绝),并恢复它: dotnet run --project samples/Tessera.Sample 该示例默认使用内存中的参考存储,因此即使没有 Docker 也能运行。 ## 结合 Helm 的 Kubernetes 用于嵌入该库的控制平面服务的 chart 位于 `charts/tessera` 下。这是一个通用的起点;你需要在 values 中设置你的镜像和 OpenFGA 连接。 ``` helm install tessera charts/tessera \ --set image.repository=your-registry/your-tessera-service \ --set openfga.apiUrl=http://openfga:8080 ``` ## 开发环境配置 ``` dotnet build Tessera.sln # build dotnet test Tessera.sln # run the test suite dotnet run --project samples/Tessera.Sample ``` 一个 `Makefile` 封装了这些命令:`make build`、`make test`、`make run`、`make up`、`make down`。 ## 配置参考 Tessera 通过实现一小组接口并提供配置来进行集成。你不需要修改核心代码。 | 接口 | 你需要提供 | 包含的参考实现 | |-----------|-------------|------------------------------------| | `IIdentityResolver` | 请求如何映射到客户端引用和保障级别 | claim 或 header 解析器 | | `IAuthorizationStore` | OpenFGA 绑定(或替代方案) | 内存存储 | | `IClientRegistry` | 持久的客户端和终止哨兵存储 | 内存注册表 | | `IAuditSink` | 审计事件的去向 | 控制台输出接收器 | | `IClientLock` | 每个客户端引用的互斥锁 | 进程内锁 | 你的 API 接口是以数据形式提供的,因此路径参数仅在声明的位置折叠为 `{param}`: ``` { "endpoints": [ { "method": "get", "path": "orders/{param}/items" }, { "method": "post", "path": "orders" } ] } ``` 典型部署使用的环境变量列在 `.env.example` 中。 内存存储并未掩盖两个行为,因为真实的 OpenFGA 会有这些行为,而你的适配器必须处理它们: - 读取是分页的;需循环处理 continuation token。 - 每次请求的写入和删除有上限(大约 100 个 tuple);请对大批量数据进行分块。 ## 路线图 ### v1.1 - 针对 `IAuthorizationStore` 的 OpenFGA SDK 适配器,支持分页和分块 - 带有数据库咨询锁的 PostgreSQL 注册表实现 - 用于调和循环的 Leader 选举 ### v1.2 - 最小化的 HTTP 接口(终止、恢复、注册),带有 issuer 和 audience 验证 - 参考 SIEM 审计接收器 - GitOps 调和 worker 和漂移检测 ## 许可证 MIT。请参见 [LICENSE](LICENSE)。 ## 关于 Tessera 是一个由 OpenFGA 支持的授权控制平面的通用参考实现。它构建于公开技术(OpenFGA 和 Zanzibar 模型,标准 .NET)之上,旨在被采纳和扩展,而不是被 fork 和修改。
标签:API网关, M2M通信, .NET 8, OpenFGA, 令牌吊销, 关系型访问控制, 子域名突变, 授权系统, 请求拦截, 身份与访问控制