447 lines
11 KiB
Go
447 lines
11 KiB
Go
// 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
|
||
}
|