Files
synapse/internal/components/sigil/sigil.go
2026-06-28 03:24:26 +08:00

447 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package sigil 灵玺 - 身份与凭证层
//
// 皇帝的玉玺是最高凭证。在此协议中,
// 每个 Agent 的初始身份都需经过"铸玺"过程,
// 每一次交互都要"验玺",确保穿透零信任边界后
// 的每一次握手都正统且不可篡改。
package sigil
import (
"crypto/hmac"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"encoding/json"
"fmt"
"hash"
"sync"
"time"
"synapse/pkg/types"
)
// =============================================================================
// Agent Identity - Agent 身份
// =============================================================================
// AgentIdentity Agent 身份凭证
type AgentIdentity struct {
// Agent 基本信息
AgentID string `json:"agent_id"`
AgentName string `json:"agent_name"`
SystemID string `json:"system_id"`
// 身份凭证
PublicKey string `json:"public_key,omitempty"` // 公钥(可选)
PrivateKey string `json:"private_key,omitempty"` // 私钥(本地保存,不对外)
AuthSecret string `json:"-"` // HMAC 密钥(不序列化)
// 权限与角色
Roles []string `json:"roles,omitempty"`
Permissions []string `json:"permissions,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
// 生命周期
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
}
// IdentityManager 身份管理器
type IdentityManager struct {
mu sync.RWMutex
identities map[string]*AgentIdentity // agent_id -> identity
config *IdentityConfig
}
// IdentityConfig 身份管理配置
type IdentityConfig struct {
DefaultAlgorithm string // 默认签名算法
TokenTTL time.Duration // Token 有效期
}
// DefaultIdentityConfig 返回默认身份配置
func DefaultIdentityConfig() *IdentityConfig {
return &IdentityConfig{
DefaultAlgorithm: "HMAC-SHA256",
TokenTTL: 24 * time.Hour,
}
}
// NewIdentityManager 创建身份管理器
func NewIdentityManager(config *IdentityConfig) *IdentityManager {
if config == nil {
config = DefaultIdentityConfig()
}
return &IdentityManager{
identities: make(map[string]*AgentIdentity),
config: config,
}
}
// CreateIdentity 铸玺 - 创建新身份
func (im *IdentityManager) CreateIdentity(agentID, agentName, systemID string, authSecret string) (*AgentIdentity, error) {
if agentID == "" {
return nil, fmt.Errorf("agent_id is required")
}
im.mu.Lock()
defer im.mu.Unlock()
if _, exists := im.identities[agentID]; exists {
return nil, fmt.Errorf("agent %s already exists", agentID)
}
identity := &AgentIdentity{
AgentID: agentID,
AgentName: agentName,
SystemID: systemID,
AuthSecret: authSecret,
Roles: []string{"agent"},
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
im.identities[agentID] = identity
return identity, nil
}
// GetIdentity 获取身份
func (im *IdentityManager) GetIdentity(agentID string) (*AgentIdentity, error) {
im.mu.RLock()
defer im.mu.RUnlock()
identity, ok := im.identities[agentID]
if !ok {
return nil, fmt.Errorf("agent %s not found", agentID)
}
return identity, nil
}
// RevokeIdentity 废玺 - 撤销身份
func (im *IdentityManager) RevokeIdentity(agentID string) error {
im.mu.Lock()
defer im.mu.Unlock()
identity, ok := im.identities[agentID]
if !ok {
return fmt.Errorf("agent %s not found", agentID)
}
now := time.Now()
identity.RevokedAt = &now
identity.UpdatedAt = now
return nil
}
// IsRevoked 检查是否已撤销
func (im *IdentityManager) IsRevoked(agentID string) (bool, error) {
im.mu.RLock()
defer im.mu.RUnlock()
identity, ok := im.identities[agentID]
if !ok {
return false, fmt.Errorf("agent %s not found", agentID)
}
return identity.RevokedAt != nil, nil
}
// =============================================================================
// Signature - 签名验证
// =============================================================================
// SignatureAlgorithm 签名算法
type SignatureAlgorithm string
const (
AlgHMACSHA256 SignatureAlgorithm = "HMAC-SHA256"
AlgHMACSHA512 SignatureAlgorithm = "HMAC-SHA512"
)
// Signer 签名器
type Signer struct {
algorithm SignatureAlgorithm
secret string
}
// NewSigner 创建签名器
func NewSigner(algorithm SignatureAlgorithm, secret string) *Signer {
if algorithm == "" {
algorithm = AlgHMACSHA256
}
return &Signer{
algorithm: algorithm,
secret: secret,
}
}
// SignMessage 对消息签名
func (s *Signer) SignMessage(msg *types.UnifiedSynapseMessage) error {
if msg == nil {
return fmt.Errorf("message is nil")
}
// 构造待签名内容:sender_id + receiver_id + timestamp + payload
payloadJSON, _ := json.Marshal(msg.Payload)
signContent := fmt.Sprintf("%s|%s|%s|%s",
msg.Sender.AgentID,
msg.Receiver.AgentID,
string(msg.Timestamp),
string(payloadJSON),
)
signature, err := s.sign([]byte(signContent))
if err != nil {
return err
}
msg.Signature = hex.EncodeToString(signature)
msg.SignatureAlgorithm = string(s.algorithm)
return nil
}
// VerifySignature 验证消息签名
func (s *Signer) VerifySignature(msg *types.UnifiedSynapseMessage) (bool, error) {
if msg == nil || msg.Signature == "" {
return false, fmt.Errorf("no signature to verify")
}
// 构造待签名内容
payloadJSON, _ := json.Marshal(msg.Payload)
signContent := fmt.Sprintf("%s|%s|%s|%s",
msg.Sender.AgentID,
msg.Receiver.AgentID,
string(msg.Timestamp),
string(payloadJSON),
)
expectedSig, err := s.sign([]byte(signContent))
if err != nil {
return false, err
}
actualSig, err := hex.DecodeString(msg.Signature)
if err != nil {
return false, fmt.Errorf("invalid signature format: %w", err)
}
return hmac.Equal(expectedSig, actualSig), nil
}
// sign 生成 HMAC 签名
func (s *Signer) sign(data []byte) ([]byte, error) {
var h hash.Hash
switch s.algorithm {
case AlgHMACSHA256:
h = hmac.New(sha256.New, []byte(s.secret))
case AlgHMACSHA512:
h = hmac.New(sha512.New, []byte(s.secret))
default:
return nil, fmt.Errorf("unsupported algorithm: %s", s.algorithm)
}
h.Write(data)
return h.Sum(nil), nil
}
// =============================================================================
// Auth Token - 认证令牌
// =============================================================================
// AuthToken 认证令牌
type AuthToken struct {
TokenID string `json:"token_id"`
AgentID string `json:"agent_id"`
SystemID string `json:"system_id"`
Roles []string `json:"roles"`
IssuedAt time.Time `json:"issued_at"`
ExpiresAt time.Time `json:"expires_at"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
// TokenManager 令牌管理器
type TokenManager struct {
mu sync.RWMutex
tokens map[string]*AuthToken // token_id -> token
config *TokenConfig
signer *Signer
}
// TokenConfig 令牌配置
type TokenConfig struct {
DefaultTTL time.Duration
}
// DefaultTokenConfig 返回默认令牌配置
func DefaultTokenConfig() *TokenConfig {
return &TokenConfig{
DefaultTTL: 24 * time.Hour,
}
}
// NewTokenManager 创建令牌管理器
func NewTokenManager(signer *Signer, config *TokenConfig) *TokenManager {
if config == nil {
config = DefaultTokenConfig()
}
return &TokenManager{
tokens: make(map[string]*AuthToken),
config: config,
signer: signer,
}
}
// IssueToken 颁发令牌
func (tm *TokenManager) IssueToken(agentID, systemID string, roles []string) (*AuthToken, string, error) {
tm.mu.Lock()
defer tm.mu.Unlock()
tokenID := fmt.Sprintf("token-%d", time.Now().UnixNano())
now := time.Now()
token := &AuthToken{
TokenID: tokenID,
AgentID: agentID,
SystemID: systemID,
Roles: roles,
IssuedAt: now,
ExpiresAt: now.Add(tm.config.DefaultTTL),
}
tm.tokens[tokenID] = token
// 生成签名令牌字符串
tokenJSON, _ := json.Marshal(token)
signature, _ := tm.signer.sign(tokenJSON)
signedToken := fmt.Sprintf("%s.%s", string(tokenJSON), hex.EncodeToString(signature))
return token, signedToken, nil
}
// ValidateToken 验证令牌
func (tm *TokenManager) ValidateToken(signedToken string) (*AuthToken, error) {
// 解析令牌(简化实现)
parts := splitToken(signedToken)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid token format")
}
tokenJSON := []byte(parts[0])
signature, err := hex.DecodeString(parts[1])
if err != nil {
return nil, fmt.Errorf("invalid signature format")
}
// 验证签名
expectedSig, err := tm.signer.sign(tokenJSON)
if err != nil {
return nil, err
}
if !hmac.Equal(expectedSig, signature) {
return nil, fmt.Errorf("invalid token signature")
}
var token AuthToken
if err := json.Unmarshal(tokenJSON, &token); err != nil {
return nil, fmt.Errorf("invalid token payload")
}
// 检查过期
if time.Now().After(token.ExpiresAt) {
return nil, fmt.Errorf("token expired")
}
return &token, nil
}
// RevokeToken 撤销令牌
func (tm *TokenManager) RevokeToken(tokenID string) error {
tm.mu.Lock()
defer tm.mu.Unlock()
delete(tm.tokens, tokenID)
return nil
}
func splitToken(s string) []string {
// 简化实现,找最后一个点
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '.' {
return []string{s[:i], s[i+1:]}
}
}
return []string{s}
}
// =============================================================================
// Authorization - 授权检查
// =============================================================================
// Authorizer 授权检查器
type Authorizer struct {
identityMgr *IdentityManager
}
// NewAuthorizer 创建授权检查器
func NewAuthorizer(identityMgr *IdentityManager) *Authorizer {
return &Authorizer{
identityMgr: identityMgr,
}
}
// HasRole 检查角色
func (a *Authorizer) HasRole(agentID, role string) (bool, error) {
identity, err := a.identityMgr.GetIdentity(agentID)
if err != nil {
return false, err
}
for _, r := range identity.Roles {
if r == role {
return true, nil
}
}
return false, nil
}
// HasPermission 检查权限
func (a *Authorizer) HasPermission(agentID, permission string) (bool, error) {
identity, err := a.identityMgr.GetIdentity(agentID)
if err != nil {
return false, err
}
for _, p := range identity.Permissions {
if p == permission {
return true, nil
}
}
return false, nil
}
// CanSendMessage 检查是否可以发送消息
func (a *Authorizer) CanSendMessage(fromAgentID, toAgentID string, msgType string) (bool, error) {
// 检查发送方是否存在且未被撤销
fromIdentity, err := a.identityMgr.GetIdentity(fromAgentID)
if err != nil {
return false, err
}
if fromIdentity.RevokedAt != nil {
return false, fmt.Errorf("sender identity revoked")
}
// 检查接收方是否存在
_, err = a.identityMgr.GetIdentity(toAgentID)
if err != nil {
return false, err
}
return true, nil
}