security: implement audit logging and rate limiting#815
security: implement audit logging and rate limiting#815notsointresting wants to merge 2 commits intosipeed:mainfrom
Conversation
- Add SecurityConfig struct with SSRF, Audit Logging, Rate Limiting, Credential Encryption, and Prompt Injection configs - Add environment variable support for all security settings - Add default security settings in defaults.go - Foundation for comprehensive security framework
Audit Logging (pkg/audit/audit.go): - Logs tool executions, auth events, config changes - HMAC hash chain for tamper-evident logs - Configurable retention policy - Convenience functions for common events Rate Limiting (pkg/ratelimit/limiter.go): - Token bucket algorithm implementation - Global and per-user rate limiting - Separate limits for tool executions - Non-blocking and blocking wait modes
yinwm
left a comment
There was a problem hiding this comment.
Code Review: Audit Logging and Rate Limiting
Thanks for this comprehensive PR implementing audit logging and rate limiting! These are valuable security features. However, I found several critical issues that need to be addressed before merging.
🔴 Critical Issues
1. Code Overlap with PR #813, #814 - Will Cause Merge Conflicts
Same configuration changes as the previous security PRs:
SecurityConfigdefinition- Default value changes
DMScopechange- Removal of
RequestTimeoutfields
Recommendation: Depend on PR #813 being merged first, then rebase.
2. Secret Key Generation is Severely Insecure
func generateSecretKey() []byte {
key := make([]byte, 32)
// Use timestamp as a simple seed (in production, use crypto/rand)
for i := range key {
key[i] = byte(time.Now().UnixNano() % 256)
}
return key
}This implementation has severe security problems:
- Uses timestamp as random source - completely predictable
- Loop executes too fast, all bytes are nearly identical (same nanosecond)
- Comment says "in production, use crypto/rand" but it's not implemented
An attacker can easily predict the key and forge audit logs.
Fix:
import "crypto/rand"
func generateSecretKey() []byte {
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
panic("failed to generate secret key: " + err.Error())
}
return key
}3. HMAC Hash Does Not Include Complete Event Data - Can Be Tampered
func (l *Logger) computeHash(event Event) string {
signData := fmt.Sprintf("%s|%s|%s|%s|%v",
event.Timestamp.Format(time.RFC3339Nano),
event.EventType,
event.Action,
event.Resource,
event.Success,
)The hash only includes partial fields! Actor, Details, Source, SessionID, Error are NOT signed.
An attacker can modify these fields without detection, breaking audit log integrity.
Fix: Sign the complete event JSON:
func (l *Logger) computeHash(event Event) string {
// Create a copy without hash fields for signing
signEvent := event
signEvent.Hash = ""
signEvent.PreviousHash = ""
data, _ := json.Marshal(signEvent)
h := hmac.New(sha256.New, l.config.SecretKey)
h.Write(data)
return fmt.Sprintf("%x", h.Sum(nil))
}4. CleanupOldLogs Breaks Hash Chain Integrity
func (l *Logger) CleanupOldLogs() error {
// ...
// Rewrite the file with kept lines
newData := ""
for _, line := range keptLines {
newData += line + "\n"
}
return os.WriteFile(l.config.LogFilePath, []byte(newData), 0o600)
}After cleanup, the first retained log's PreviousHash still points to a deleted log entry, breaking the hash chain.
Fix: Recalculate the hash chain after cleanup, or clearly document that the chain is reset.
Summary
| Category | Count |
|---|---|
| 🔴 Critical Issues | 4 |
Verdict: Please address these critical issues before we can proceed:
-
Must Fix:
- Secret key generation must use
crypto/rand - HMAC hash must include complete event data
- Resolve merge conflicts with other PRs
- Secret key generation must use
-
Recommended:
- Fix hash chain integrity after cleanup
- Consider rate limiter double-deduction issue (global bucket not refunded when user limit fails)
|
|
|
📝 Description
This PR implements audit logging for security events and rate limiting for API/tool usage.
Audit Logging (
pkg/audit/audit.go):Rate Limiting (
pkg/ratelimit/limiter.go):🗣️ Type of Change
🤖 AI Code Generation
🔗 Related Issue
Part of #782
📚 Technical Context (Skip for Docs)
🧪 Test Environment
☑️ Checklist