MoonGrd — Guardian 式认证管道框架(access/refresh 双 token 旋转 + 四段分发管线;transport/storage/crypto-free,核心零依赖)
安全信道(PSK-CR 握手 / HKDF / AEAD seq-IV / 滑窗防重放)不属于本框架—— 那是 TLS 层的活,住传输侧(moonkcp secchan)。本框架的 token 走信道传。
moon add thy1016/moongrdlet config = @moongrd.GuardConfig::make(
issuer="demo-iss",
audience="demo-app",
access_ttl_ms=60000L,
refresh_ttl_ms=600000L,
)
let signer : &@moongrd.Signer = @mooncry.HmacSha256Signer::new(session_key)
// 签发:时间与熵(jti)由调用方注入
let access = @moongrd.issue(config, signer, now, "alice", @moongrd.TokenType::Access, jti_a)
let refresh = @moongrd.issue(config, signer, now, "alice", @moongrd.TokenType::Refresh, jti_r)
// 业务门:typ 不对即拒
match @moongrd.verify_for(config, signer, now, access.token, @moongrd.TokenType::Access) {
Ok(claims) => // claims.sub 即主体
Err(e) => // 拒因:过期/签名不符/型不符……
}pub impl DoorHandler for MyDoor with admit(self : MyDoor, sub : String) -> Bool { ... }
pub impl DoorHandler for MyDoor with dispatch(self : MyDoor, sub : String, req : Json) -> Json { ... }
pub impl DoorHandler for MyDoor with audit(self : MyDoor, e : @moongrd.AuditEvent) -> Unit { ... }
let door = @handler.mount(config=config, signer=signer,
revocations=revocations, handler=my_door)
let resp = door.run(now, access_token, req)let door = @moongrd.Guard::new(
config=config, signer=signer, revocations=revocations,
resolve=async fn(sub : String) -> User? { ... }, // sub → 主体
dispatch=async fn(u : User, req : Req) -> Resp { ... }, // 业务到达
)let door = @moongrd.Guard::new(
config=config, signer=signer, revocations=revocations,
resolve=..., dispatch=...,
audit=async fn(e : @moongrd.AuditEvent) -> Unit { ... },
protocol=my_protocol,
)match @moongrd.refresh(config, signer, store, now, refresh_token, next_jti) {
Ok(r) => // 新 refresh 到手;access 用 issue() 另发
Err(@moongrd.RefreshErr::Replayed(family)) => // 盗用!全族已自动作废
Err(@moongrd.RefreshErr::Verify(Expired(_))) => // 回握手重登录
...
}let handler = @handler.FlexDoor::demo(allow=["alice"], prefix="[admin] ")
// 运行时一键换装(已挂门即时生效):
handler.swap_admit(admit=@handler.admit_none()) // 紧急停门
handler.swap_admit(admit=@handler.admit_allowlist(allow=["alice", "carol"]))
handler.swap_audit(audit=@handler.audit_collector(log=lines))moon run examples/walkthrough # 全链六幕:登录/门/旋转/重放撤族/篡改拒
moon run examples/session_lifecycle # 会话一生五幕:登录→过期→换发→登出
moon run examples/handler_demo # 回调方言三幕
moon run examples/signer_swap # 换 verify 算法三幕(HMAC-SHA512/CMAC/Ed25519)| 入口(@moongrd) | 作用 |
|---|---|
| GuardConfig::make(issuer~, audience~, access_ttl_ms~, refresh_ttl_ms~) | 配置(drift 默认 5000ms) |
| issue(config, signer, now, sub, typ, jti) | 签发(纯函数) |
| verify(config, signer, now, token) | 校验(任一 typ) |
| verify_for(config, signer, now, token, typ) | 带门校验 |
| refresh(config, signer, store, now, token, next_jti) | 换发(旋转 + 重放撤全族) |
| Guard::new(config~, signer~, revocations~, resolve~, dispatch~, audit?, protocol?) | 四段门单构造点 |
| Guard::run(now, token, req) | 过门 |
| trait 五位 | Signer Cipher RefreshStore RevocationStore AuthProtocol |
| 入口(@handler) | 作用 |
|---|---|
| DoorHandler(admit/dispatch/audit)+ mount(...) | 回调方言接线 |
| admit_allowlist / admit_all / admit_none | 预制准入 |
| dispatch_echo | 预制派工 |
| audit_println / audit_silent / audit_collector | 预制审计 |
| FlexDoor::new / demo + swap_admit / swap_dispatch / swap_audit | 可换装门房 |
| 入口(@mooncry / @memstore) | 作用 |
|---|---|
| HmacSha256Signer::new(key) | 真签名面(RFC 4231 KAT 过 trait) |
| AesGcmCipher::new(key) | AEAD 密封面 |
| MemRefreshStore::new / sweep、MemRevocationStore::new | 内存账本 |
VerifyErr Malformed(线形/编码/定型败) · BadMac(签名不符/篡改)
· Expired(claims) · NotYetValid(claims) · WrongIssuer(claims)
· WrongAudience(claims) · WrongType(claims)
RefreshErr Verify(内含 VerifyErr;Expired = 回握手信号)
· UnknownToken(mac 过但账本无记录) · Replayed(family)(已撤族)
· Revoked(claims)
GuardErr Verify(内含) · Revoked · Unresolved(sub)| 扩展点 | 形 |
|---|---|
| Signer / Cipher / AuthProtocol(有状态算法/协议面) | trait |
| RefreshStore / RevocationStore(多式共享状态) | trait |
| resolve / dispatch / audit(单钩子) | 闭包 |
| TTL / drift / issuer / audience | 字段配置 |
| 校验序、线形格式、Claims 形状、旋转策略 | 钉死(安全语义) |
moon test --target native # 38 罐pub(open) trait AuthProtocol {
async fn verify_access(self : Self, config~ : GuardConfig, signer~ : &Signer, now~ : Int64, token~ : String) -> Result[Claims, VerifyErr]
}pub(open) trait Cipher {
fn seal(Self, plaintext : Bytes, nonce : Bytes, aad : Bytes) -> Bytes
fn open(Self, ciphertext : Bytes, nonce : Bytes, aad : Bytes) -> Bytes?
}pub(open) trait RefreshStore {
fn put(Self, jti : String, record : RefreshRecord) -> Unit
fn get(Self, jti : String) -> RefreshRecord?
fn mark_used(Self, jti : String) -> Unit
fn revoke_family(Self, family_id : String) -> Unit
}pub(open) trait RevocationStore {
fn revoked(Self, jti : String) -> Bool
fn revoke(Self, jti : String) -> Unit
}pub(open) trait Signer {
fn sign(Self, payload : Bytes) -> Bytes
fn verify(Self, payload : Bytes, mac : Bytes) -> Bool
}pub(all) struct Guard[TSubj, TReq, TResp] {
config : GuardConfig
signer : &Signer
revocations : &RevocationStore
protocol : &AuthProtocol
resolve : async (String) -> TSubj?
dispatch : async (TSubj, TReq) -> TResp
audit : async (AuditEvent) -> Unit?
}fn[TSubj, TReq, TResp] Guard::new(config~ : GuardConfig, signer~ : &Signer, revocations~ : &RevocationStore, resolve~ : async (String) -> TSubj?, dispatch~ : async (TSubj, TReq) -> TResp, audit? : async (AuditEvent) -> Unit, protocol? : &AuthProtocol) -> Guard[TSubj, TReq, TResp]fn GuardConfig::make(issuer~ : String, audience~ : String, access_ttl_ms~ : Int64, refresh_ttl_ms~ : Int64) -> GuardConfigpub struct TokenProtocol {
}impl AuthProtocol for TokenProtocolasync fn verify_access(self : TokenProtocol, config~ : GuardConfig, signer~ : &Signer, now~ : Int64, token~ : String) -> Result[Claims, VerifyErr]async fn TokenProtocol::verify_access(self : TokenProtocol, config~ : GuardConfig, signer~ : &Signer, now~ : Int64, token~ : String) -> Result[Claims, VerifyErr]fn issue(config : GuardConfig, signer : &Signer, now : Int64, sub : String, typ : TokenType, jti : String) -> Issuedfn refresh(config : GuardConfig, signer : &Signer, store : &RefreshStore, now : Int64, token : String, next_jti : String) -> Result[Refreshed, RefreshErr]fn verify(config : GuardConfig, signer : &Signer, now : Int64, token : String) -> Result[Claims, VerifyErr]Install
Download zipMoonGrd — Guardian 式认证管道框架(access/refresh 双 token 旋转 + 四段分发管线;transport/storage/crypto-free,核心零依赖)