syntax = "proto3"; package appks.core.v1; // ============================================================ // JWT Payload // ============================================================ message TokenClaims { string sub = 1; // user id (uuid) string iss = 2; // issuer (e.g. "appks") int64 iat = 3; // issued at (unix seconds) int64 exp = 4; // expires at (unix seconds) string jti = 5; // unique token id (for revocation) string scope = 6; // space-separated scopes map extra = 7; // extensible fields (workspace_id, role, etc.) } // ============================================================ // Issue (appks REST API → core) // ============================================================ message IssueTokenRequest { string user_id = 1; int64 ttl_secs = 2; // access token lifetime repeated string scopes = 3; map extra = 4; } message IssueTokenResponse { string access_token = 1; // JWT string refresh_token = 2; // opaque, stored in Redis int64 expires_at = 3; string key_id = 4; // kid header for the signing key } // ============================================================ // Refresh // ============================================================ message RefreshTokenRequest { string refresh_token = 1; } message RefreshTokenResponse { string access_token = 1; string refresh_token = 2; // rotated int64 expires_at = 3; string key_id = 4; } // ============================================================ // Revoke // ============================================================ message RevokeTokenRequest { oneof target { string jti = 1; // revoke single token string user_id = 2; // revoke all tokens for user } } message RevokeTokenResponse { int32 revoked_count = 1; } // ============================================================ // Verify (imks → core, RPC 模式) // imks 把客户端携带的 JWT 发给 core 验证 // ============================================================ message VerifyTokenRequest { string token = 1; } message VerifyTokenResponse { bool valid = 1; TokenClaims claims = 2; // only set when valid = true string reason = 3; // "expired", "revoked", "invalid_signature", etc. } // ============================================================ // Key Distribution (imks → core, 本地验证模式) // imks 拉取公钥/解密密钥,本地验证 JWT,无需每次 RPC // 密钥窗口 3h,imks 定期刷新 // ============================================================ message SigningKey { string kid = 1; // key id (matches JWT header kid) string algorithm = 2; // "HS256", "RS256", "EdDSA", ... string key_material = 3; // 对称: base64 secret / 非对称: PEM public key int64 issued_at = 4; // 签发时间 int64 expires_at = 5; // 过期时间 (issued_at + 3h window) bool active = 6; // 是否为当前活跃签名密钥 } message GetSigningKeysRequest { // 空 = 返回所有未过期密钥 // 非空 = 只返回指定 kid 的密钥 string kid = 1; } message GetSigningKeysResponse { repeated SigningKey keys = 1; // 可能同时有多个有效密钥(滚动窗口) int64 next_rotation_at = 2; // 下次密钥轮换时间,imks 据此安排刷新 } // ============================================================ // Service // ============================================================ service TokenService { // --- 令牌生命周期 (appks REST handler 调用) --- rpc IssueToken(IssueTokenRequest) returns (IssueTokenResponse); rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse); rpc RevokeToken(RevokeTokenRequest) returns (RevokeTokenResponse); // --- imks 验证 (RPC 模式) --- rpc VerifyToken(VerifyTokenRequest) returns (VerifyTokenResponse); // --- imks 密钥拉取 (本地验证模式) --- // imks 启动时拉取,之后根据 next_rotation_at 定期刷新 rpc GetSigningKeys(GetSigningKeysRequest) returns (GetSigningKeysResponse); }