From 49b49969563f338ff9b2f03e36c64d7238a5d47b Mon Sep 17 00:00:00 2001 From: anti Date: Thu, 21 May 2026 16:13:31 -0400 Subject: [PATCH] feat(model): add bgp_prefix, rpki_status, rpki_source to Attacker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bgp_prefix (max 43 chars, indexed) holds the covering CIDR from the ASN lookup. rpki_status / rpki_source hold RIPE STAT validation outcome. All nullable — null means enrichment was skipped or ASN did not resolve. --- decnet/web/db/models/attackers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/decnet/web/db/models/attackers.py b/decnet/web/db/models/attackers.py index 90271462..53e4acd4 100644 --- a/decnet/web/db/models/attackers.py +++ b/decnet/web/db/models/attackers.py @@ -76,7 +76,13 @@ class Attacker(SQLModel, table=True): # announced in the global BGP table (e.g. CGNAT, dark space). asn: Optional[int] = Field(default=None, index=True) as_name: Optional[str] = Field(default=None, max_length=128) + bgp_prefix: Optional[str] = Field(default=None, max_length=43, index=True) asn_source: Optional[str] = Field(default=None, max_length=16) + # RPKI validity (populated by the profiler from decnet.rpki.enrich_rpki). + # Values: "valid" / "invalid" / "not-found" / "unknown" / null. + # Null means enrichment was skipped (no ASN resolved, or RPKI disabled). + rpki_status: Optional[str] = Field(default=None, max_length=16) + rpki_source: Optional[str] = Field(default=None, max_length=16) # Reverse-DNS (PTR) name, one-shot resolved by the profiler at first # sighting. Nullable — many attackers run infra with no rDNS, and # private/loopback addresses never resolve. 256 chars matches