KoronisKoronis

Distributed card-testing detection · replay of a held-out campaign
Idle
Before incident T−04:57
Events scored0
Peak event risk
Campaign alerts0
Velocity rules No campaign alert

Risk score vs frozen threshold

Live event feed

newest first

Evidence graph

schematic layout, real link counts

Incident & recommended action

Awaiting traffic
Press Replay incident to stream the held-out campaign one event at a time.
Expected cost by action — lowest wins

Held-out detection

Which mechanism carries the signal

Both mechanisms matter, and they do different jobs. Strip the graph edges and the model still alerts on the first declined authorisation — at far lower precision and many times the false positives. Strip the authorisation outcome and the first alert arrives later, because coordination has to accumulate first, but precision recovers. Remove both and there is nothing left, so no third signal source is hiding in the features.

Response policy — merchant cost and analyst workload

Event thresholding reaches the same decision and hands an analyst eighteen times the triage. Consolidation, not detection, is the difference. Always-hold escalates false incidents and costs more than doing nothing. All action costs and effectiveness figures are declared assumptions, not measurements.

Remaining-exposure forecast

The policy is not allowed to know the future. It sees the first events of an incident and a conformalised forecast of what is still ahead. Coverage is measured, not claimed. Campaign lengths vary across streams — with a fixed length, "remaining" is a constant minus what you have seen and a forecaster scores brilliantly while learning nothing.

Incident-level reliability

A well-calibrated event model does not give a calibrated incident probability for free — the events inside an incident are strongly dependent, which is the entire signal. Incident risk is a separate model, fitted on calibration incidents and measured here. The top bin separates cleanly (0.999 → 1.000). The bottom bin is under-confident — 0.077 predicted against 0.234 observed, on 77 of the 93 held-out incidents — and the middle bins hold too few incidents to determine.

Traffic-profile transfer stress test

Synthetic merchant shapes, not real merchants. Everything is fitted on the base profile and frozen before any shifted traffic is scored. Each shifted profile is flagged, and the feature named is one that profile genuinely alters.

Status: experimental decision support, not a safety control. The false-flag rate on held-out base traffic is too high to depend on, and the reason is measurable — the signal substantially tracks campaign shape rather than merchant shift:

Live, "different merchant" and "under attack" cannot be separated before deciding. The standard fix — monitoring drift on a far slower timescale than detection — is not implemented here.

Per-event inference

Does the architecture earn its place?

The other ablations remove data sources. This one removes the two design decisions in the model itself. The heterophily gate was argued for on the grounds that rings camouflage into legitimate traffic, which predicts it should help more as camouflage rises. It did the opposite at two layers, where it was measurably net-negative. At the three layers finally selected the difference is noise — so the honest statement is that the gate was harmful at one depth and irrelevant at another, and a calibration-only selection removed it either way. Depth is the component that still earns its place, measured across a width × depth grid rather than by this table alone.

Vantage point: merchant or gateway

The same campaign, the same frozen model and threshold — the only variable is how much of the stream the detector may see at once. A ring split across M merchants leaves each one n/M attempts, and co-occurrence goes as attempts squared, so a merchant's view should carry about M times less signal. At M = 1 the two views are the same stream and score identically, which is the control. The gap then opens monotonically, as predicted. Even at M = 16 the merchant view still detects this campaign: this measures a widening gap, not a blindness boundary.

Detectability frontier

All 16 cells

What this is

Koronis detects coordinated card-testing campaigns: attempts that are individually ambiguous but share enough infrastructure to form measurable temporal structure. It is a detector, not a general fraud model.

The sequence it actually follows

  • A declined authorisation raises risk on its own — early, and noisy.
  • Related events accumulate, and shared devices, IPs and BIN ranges start linking them together.
  • Coordination becomes decisive, and the alert reaches a precision an operations team can act on.

Post-authorisation limitation

The outcome of an attempt is observed only after it is submitted. No detector can prevent the attempt it learns from. The value is in stopping the attempts that follow, which is why detection latency is reported at all.

Where a payment gateway would put it

A design proposal, not something that has been built. The placement is reasoned; the constants under it are measured. Nothing in this repository talks to a payment system, and no part of it can.

Because it is post-authorisation, it never sits on the checkout's critical path. It consumes the authorisation outcome stream asynchronously and writes decisions to a key-value store keyed by entity, which the pre-auth path reads with a lookup — the same shape as the velocity counters most gateways already run there. A lookup is not a model call.

  • Sizing follows from the measured constants. 0.91 ms per event and 1,095 events/sec per worker, so nine workers cover roughly 9,900 events/sec. Frequency state is fixed at 4 MB however many distinct entity values pass through — which matters, because a card-testing campaign mints a fresh card id per attempt.
  • Splitting it across machines costs accuracy, and that was measured rather than assumed. Partitioning a graph deletes edges; replicating the entities that actually recur restores recall from 0.72 to 0.99 at eight shards, for 2.42× the scoring work. Reported honestly: every partitioned configuration is worse than not partitioning at all — ₹645 undivided against ₹2,412 at eight shards — so more workers is a cost to justify, not a free lever.
  • The output is a recommendation with its evidence. An incident arrives with the attempts it links, the forecast it was decided on, and the cost of each alternative. It is a signal source for an existing risk stack, not a replacement for one.

What would have to be true first, stated plainly: the model is fitted once and frozen, which is what makes the hold-out honest and is not what a deployment wants; the data is semi-synthetic, and BIN — the relation carrying most of the signal — is the one whose real behaviour differs most from the simulation; and any deployment would begin in shadow mode, scoring and logging without acting, until its false-positive rate had been measured on real traffic.

Limitations

Semi-synthetic data

Background traffic and campaigns are generated, not observed. Ground truth exists because it was constructed. The hold-out extrapolates to a campaign spread wider than anything in training, but that is not the same as detecting a campaign in the wild.

The loader has an unfinished path for the real IEEE-CIS transaction set; it raises rather than half-working. The dataset was obtained and profiled, then deliberately not used: a contiguous slice runs at ~210 events/hour against the ~1,500 the simulator is tuned to, and at that density an injected campaign dominates its own window — the thin-traffic regime a previous fix removed. Matching the density by compressing IEEE's timeline would discard the real arrival structure that is the point of using it. IEEE-CIS also carries no authorisation outcome, so approved would have to be modelled from its fraud flag — synthesising the mechanism the detector leans on.

What it will not catch

An attacker who uses genuinely fresh infrastructure for every single attempt leaves no graph signal. That limit is real — and it is also the point: driving spread that far costs one device, IP and BIN per attempt.

Cost figures are assumptions

Rupee amounts are declared constants, not measurements, and they assume detection halts a campaign immediately. Read them as the cost of latency, not guaranteed savings.

The drift guardrail is experimental

Koronis can detect that live traffic sits outside its calibration distribution and lower automation, routing an incident to review instead. On held-out base traffic it raises that flag too often to be depended on, and the reason is measurable: the signal partly tracks campaign shape rather than merchant shift. It is decision support that can ask for a human, not a control anything should rely on.

Actions are simulated

Every recommended action is decision support in a modelled merchant workflow. Nothing blocks a payment, calls a gateway or touches live infrastructure. The cost and effectiveness figures behind each rung are declared assumptions, stated so they can be replaced.

Defence-only

No network capability anywhere in the codebase, no live payment integration, no real card data, no real BIN ranges. The campaign generator produces labelled test data from in-memory frames and reproduces only characteristics already published in Visa's anti-enumeration guidance.