Federated Threat Intelligence: Sharing IOCs Without Sharing Content AegisGate, an open-source AI security platform, has shipped a federated threat intelligence system that lets organizations share indicators of compromise without exposing raw attack payloads. The system fingerprints detections with SHA-256 over a canonicalized struct, distributes signed IOC bundles via HTTP gossip with ECDSA P-256 signatures, and weights peers using an EWMA reputation score with a 7-day half-life, so corroborated detections can escalate a response from alerting to blocking. The fundamental problem in threat intelligence is latency. Organization A detects a novel prompt injection. Organizations B, C, and D won't see it until someone writes a blog post, a vendor updates a signature, and a SIEM rule gets deployed. In AI security, that latency window is measured in hours — and attacks iterate faster than that. I've been building AegisGate https://github.com/aegisgatesecurity — an open-source AI security platform — and we just shipped a federated threat intelligence system that closes that gap. This post is about the architecture and the hard design decisions. AI attacks are distributed. An attacker hits Organization A with a novel prompt injection today, and hits Organizations B through Z tomorrow. Traditional threat intel sharing has too much friction: We needed something where the first organization to see an attack instantly benefits every other organization — without sharing content, without a central authority, and without blind trust. When AegisGate detects a threat, it creates an Indicator of Compromise IOC . But we don't share the raw attack payload. We compute a SHA-256 fingerprint over the canonicalized detection struct — capturing the technique, pattern match, and confidence without any original content. Two organizations can independently detect the same novel attack, produce the same fingerprint, and confirm they're seeing the same thing — without either knowing what the other's actual prompt said. Instances communicate via HTTP gossip. Every instance exposes a /manifest endpoint listing its signed IOC bundles. Peers periodically pull manifests, verify signatures, and ingest new IOCs. Each bundle is signed with ECDSA P-256 . The keyring is per-instance, and peers discover each other's public keys through a bootstrap peer list. No central authority — it's a trust mesh. type Bundle struct { IOCs IOC json:"iocs" Signature ECDSASig json:"signature" PublicKey ECDSAPubKey json:"publicKey" Timestamp time.Time json:"timestamp" } Not all peers are equal. We track reputation using an Exponentially Weighted Moving Average EWMA with a 7-day half-life: Scores range 0.0 to 1.0. The threshold for "trusted" is configurable, and reputation determines how IOCs from that peer are handled. This is the core insight. When your local AegisGate detects a threat, it creates a local IOC. If a peer later shares an IOC with the same fingerprint, that's corroboration — independent confirmation. In conservative mode default , corroboration escalates the response: "alert and log" becomes "block." One organization's threat → every organization's protection. In aggressive mode , peer IOCs alone can trigger blocking — for high-trust federation partners where you want to benefit from their detections before you see the attack yourself. Beyond peer gossip, we support standard TAXII feeds for existing TI platforms. Each feed has a configurable reputation weight 0.0–1.0 and severity floor. High-trust feeds ≥0.5 count as corroboration; low-trust feeds contribute IOCs but don't independently escalate. Shipping the gossip protocol was necessary but not sufficient. Four hardening layers were needed for production. Every gossip endpoint is rate-limited per-IP with a token bucket default 60/min . A CIDR allow-list lets trusted partner networks bypass: type SyncConfig struct { RateLimitPerMinute int // default 60 PeerAllowList string // CIDRs that bypass rate limiting } This prevents a compromised peer from DOSing your manifest endpoint and caps the blast radius of a flooding peer. The IOC admin API already sits behind dashboard auth middleware. We added a second layer — bearer token authentication using crypto/subtle.ConstantTimeCompare : func a iocAdminAPI requireAdminToken next http.Handler http.Handler { return http.HandlerFunc func w http.ResponseWriter, r http.Request { if a.adminToken == "" { next.ServeHTTP w, r // backward compatible: no token = no extra auth return } token := strings.TrimPrefix r.Header.Get "Authorization" , "Bearer " if subtle.ConstantTimeCompare byte token , byte a.adminToken = 1 { w.Header .Set "WWW-Authenticate", "Bearer" http.Error w, "Unauthorized", http.StatusUnauthorized return } next.ServeHTTP w, r } } When the token is set, both layers must pass. When unset, backward compatible. The ECDSA keyring file contains private keys that sign IOC bundles. In production, this can't sit on disk in plaintext. We encrypt with AES-256-GCM . Passphrase → SHA-256 → 32-byte key. The encrypted file is a JSON envelope: { "encrypted": true, "nonce": "