diff --git a/services/security-dashboard.sh b/services/security-dashboard.sh
index ba05155..e4c9371 100644
--- a/services/security-dashboard.sh
+++ b/services/security-dashboard.sh
@@ -426,6 +426,12 @@ def get_decisions():
return []
decisions = []
for alert in data or []:
+ # AS number/name and country live on the parent alert's "source"
+ # object, not on the individual decision — confirmed against real
+ # output (source.as_number, source.as_name, source.cn) rather than
+ # guessed, after getting evt.Enriched.ASNNumber's type wrong earlier
+ # tonight for the same underlying data.
+ source = alert.get("source") or {}
for d in alert.get("decisions") or []:
decisions.append({
"id": d.get("id"),
@@ -433,6 +439,9 @@ def get_decisions():
"scenario": d.get("scenario"),
"duration": d.get("duration"),
"origin": d.get("origin"),
+ "as_number": source.get("as_number", ""),
+ "as_name": source.get("as_name", ""),
+ "country": source.get("cn", ""),
})
return decisions
@@ -444,7 +453,11 @@ def delete_decision(decision_id):
return ok, (err or out or ("deleted" if ok else "failed"))
-def get_asn_exempt():
+def get_asn_exempt(known_names=None):
+ """known_names: optional {asn: as_name} lookup, built from current
+ decisions, to label already-exempt ASNs that aren't actively generating
+ bans right now (and so wouldn't otherwise have a name available)."""
+ known_names = known_names or {}
asns = set()
for path in ASN_SCENARIO_FILES:
try:
@@ -458,7 +471,8 @@ def get_asn_exempt():
tok = tok.strip().strip("'").strip('"')
if tok:
asns.add(tok)
- return sorted(asns, key=lambda x: int(x) if x.isdigit() else 0)
+ ordered = sorted(asns, key=lambda x: int(x) if x.isdigit() else 0)
+ return [{"asn": a, "name": known_names.get(a, "")} for a in ordered]
def set_asn_exempt(asn_list):
@@ -530,7 +544,7 @@ INDEX_HTML = """