Skip to main content

Threat Studio

The backoffice pages are organised the way the extension is built: a page per entity, a page per surface. That is the right shape for configuring one thing and the wrong one for answering is this fleet protected, and by what.

Threat Studio is the other half. It lives at /extensions/cloud-apim/threat-studio, needs a backoffice session, and is reachable from the Threat Protection menu or by searching for it.

The Threat Studio workspaces page: the fleet summary, the routes no rule claims, and the ordered table of workspaces

Each row is a rule of the global preset table. The summary leads with the count that earns the page — the routes no rule claims — and the workspace shows its selector and the sections it lays down.

It stores nothing, and it keeps you in one place

There is no workspace entity, no studio database, no extra state to back up. A workspace is a rule of the global preset table, and everything else it shows is either an ordinary entity of the extension or a query over the analytics you already export. Deleting the studio would delete nothing.

Every entity is created, edited and deleted here; WAF tuning and learning run here; a caller is banned here. The studio does not hand you off to the backoffice to finish a job.

A workspace is a rule of the table​

The global preset pairs a selector with a protection, and the studio is that table with a console around it.

In the studioIn the configuration
Workspaceone rule of the global preset table
Its scopethat rule's targets, resolved against the router
Its protectionthat rule's preset — the same fields as the route-level preset
Its positionwhere the rule sits in the table, which decides who wins

So the ordering on the workspaces page is not a display preference. The table is read top to bottom and the first matching rule wins; moving a workspace up is a configuration change, and the studio says so.

What only the gateway can answer​

Which routes a rule claims goes through the expression language and the live router, so the studio asks the extension rather than guessing. What comes back is richer than a list:

  • the routes each workspace claims, and the ones it merely matches — the second list is what explains a workspace that looks empty, because a rule above it took them;
  • the routes no rule claims, which is the finding the page exists for;
  • the routes that carry their own fabric, on which the table stands down;
  • rules that sit under a catch-all and can therefore never be reached at all.

The Routes page: the routes a workspace governs, each with the posture it actually ends up with, and below them the routes it matched but a rule above took

The second table is the one that explains a workspace that looks empty — a route it matches, governed by a rule sitting higher in the table.

What each workspace has​

PageAnswers
OverviewWhat it covers, what it is armed to do, and what the traffic did
ActivityThe analytics, scoped to its routes — decisions, sources, detectors, routes, WAF, consumers
LogsThe decisions one by one, with the signals behind each one
RoutesWhich routes it governs, and the posture each of them ends up with
ScopeIts selectors
ProtectionThe arming console: which sections run — from the threat gate to the traffic, login and object guards, the API contract, uploads and the response guards — what each sensitive data detector does, which contract each route is checked against, and whether any of it can stop a request
APIThe API reports of its routes: which credential each endpoint checks, the operations used and the zombies, the shadow endpoints, and how the traffic drifts from the contracts
WAF · Bots · IP reputation · Threat policyThe entities it points at, and the state they are in
Bans & incidentsIts traffic's incidents, and what the fabric is holding right now
SettingsName, position in the table, and whether it applies at all

A workspace overview: coverage read with no analytics, then the past week of decisions

The overview leads with coverage — which works before a single event exists — then the traffic. The routes below are governed by this workspace's selectors, resolved against the router.

The two pages where you write the configuration rather than read it are Scope — the selectors that decide which routes the workspace claims — and Protection — the arming console.

The Scope page: a target on the route tags, and the opt-out toggle above it

A target reads a route field ($.tags, $.groups, $.metadata.*) or an expression, and compares it with the platform's own predicate language. Every target must match; a workspace with none claims every route.

The Protection page: the section switches, whether any of them can stop a request, and the entities each reads

It leads with the one question that matters — can any of this actually refuse a request — because a section switched off expands into nothing, and a workspace can arm everything and still only observe.

Under those, a second section covers what belongs to the install rather than to any workspace: the fleet, threat feeds, ASN databases, CrowdSec, pre-routing, shared WAF rulesets, rule feeds, alert rules, malware scanners, API contracts — imported from a URL, listed operation by operation, with what uses each — and the cluster state.

Some things cannot be scoped to a workspace, and the studio says so

Every enabled threat feed, ASN database and CrowdSec bouncer is consulted for every route whose workspace enables reputation — the mode is a per-workspace choice, the sources are not. The three pre-routing validators are further out of reach still: they run before a route is known, so no selector could ever reach them.

During an incident, Bans & incidents is worked from the studio: what the fabric is holding right now, the incidents it is still watching, and the allowlist — with the one action there was no way to start before, banning a caller by hand.

The Bans & incidents page, install-wide: an active ban with its evidence, the open incidents, the allowlist, and a button to ban an address

A ban is issued against a caller — an IP, an api key, a user — and enforced on every route of the install. Extend it, lift it, or move it to the allowlist from the same row.

WAF, tuning and learning, in the studio​

The WAF page has three tabs. Config picks and edits the rule engine this workspace runs. Tuning is the assistant — the rules that fired on traffic somebody thinks is legitimate, and for each one the exclusions it generated, every one already run so the verdict is measured rather than described. Learning measures a window of real traffic and reports what arming would cost, with the verified exclusions ready to apply.

The WAF tuning assistant: a false-positive rule, and the exclusions generated for it with their measured verdict

Each proposal shows the SecLang it would write, whether it stops the rule firing, and what it would stop catching — so the narrowest safe one is the obvious pick. None of this leaves the studio.

The analytics​

This is the half the studio is really for, and it needs the user-analytics exporter — see the security console.

The platform's own analytics filters carry a single route_id, which is the right shape for a dashboard about one route and the wrong one for a question asked of a set of them. Every query of the extension therefore takes a route_ids parameter, and an empty list means the whole fleet — so the same widgets serve a workspace and the install.

Beside the twelve queries the console already had, the studio adds the ones a security console is actually read for:

Enforcementenforced versus observed over time (the dry-run gap as a trend), actions over time, threat score distribution, decisions by hour and weekday
Sourcesdistinct sources over time, sources by spread — how many routes they touched — and sources by threat score rather than by volume
Detectorsevery signal with the share of decisions it was acted on: the question actually asked of a feed
Routesper route, decided against enforced: configuration says what a route should do, this says what it did
Incidentsincidents over time, and the largest ones with the caller they were opened on
Consumersapi keys and users decided against — an attack from a valid key is the one a perimeter view never shows
WAFinspected / blocked / would have blocked on one axis, the rules behind the blocks, block statuses, body-limit pressure
Clusterdecisions by node, which is how an unshared shared state shows up

All of them are declared through the same analyticsQueries() point as the platform's own, so they also appear in the widget wizard and compose into your own dashboards.

The Activity page: decisions, enforced versus observed, actions over time, the action and outcome donuts, the score distribution and the hour-by-weekday heatmap

Every number is asked of the routes this workspace governs, here over the past hour: how many decisions, how many actually acted, and the graded response as it moves.

The Activity tabs​

Sources — breadth over time, who the fabric decided against most, who walks the surface, and who is the most dangerous rather than the noisiest.

The Sources tab: distinct sources over time, the sources most decided against, sources ranked by the routes they touched and by threat score

Geography — where the decisions come from, on a world map. The country is the one a caller's network is registered in, as the ASN databases know it: the same lookup that puts a flag next to every address in the studio. It is not stored with the events, so the map is drawn from the most active sources of the period and says how much of it they account for. Colour the countries by decisions, enforced decisions, sources or highest score.

The Geography tab: countries, top country, the share of decisions placed, a world map coloured by decisions, the ranking by country and the networks behind the sources

Clicking a country — on the map or in the table — lists its sources and their networks. The map also turns into a globe, which can be left rotating on a wall screen: the view, the metric, the selected country and the rotation are all kept in the address, so a link opens on exactly what was shared.

The Geography tab with France selected: its outline on the map, and its sources with their network

The Geography tab as a globe

Detectors — which component decided, the signals that fired, and whether each of them ever changes an outcome. A feed that fires constantly and never enforces is noise being paid for.

The Detectors tab: decisions by component, top signals, each signal with the share it was acted on, incidents over time and the largest incidents

Routes — where decisions are taken, and what each route actually enforced next to what the workspace is configured to do.

The Routes tab: decisions per route, what each route enforced, and the coverage of the workspace

WAF — inspected, blocked and would-have-blocked on one axis, the rules that fire and the ones behind the blocks, what a blocked caller was answered, and how often a body was inspected whole.

The WAF tab: inspected, blocked and would have blocked over time, top triggered rules, the rules behind the blocks, block statuses and body inspection limits

Consumers — api keys and users decided against, and the spread of decisions across the nodes of a cluster.

The Consumers tab: api keys and users decided against, and decisions by node

The rows themselves​

Two more queries return the events rather than an aggregate, paged on the timestamp: the security decisions log and the WAF trail. Opening a row shows the whole event — including its signals, which is the attribution that answers why a caller was judged. A console that cannot drill into that can only ever show that something happened.

The Logs page: security decisions one per row, filterable by detector, action, outcome and source

The aggregates say what is happening; this says what happened to one caller. Opening a row shows the signals behind the verdict.

The filters narrow the log to a detector, an action, a source address, or to what actually acted:

The Logs page filtered on enforced decisions: bans, and the signals behind each

Opening a row shows where the caller comes from — its country and network — what the decision did, the signals and their weight, and the whole event:

A security decision opened: source, country, network, detector, action, score, incident, the signals behind it and the raw event

The WAF trail is the same for the WAF: every inspected request, its mode, its verdict and the rules that matched.

A rule id is always shown with what it means — its message, or, for the many rules that have none, what the rule is: a CRS setup rule, a paranoia level gate, the anomaly scoring. The meaning comes from the rulesets the install actually runs (the bundled CRS and your own), parsed once. The setup and scoring rules run on every request and would drown the detections, so they are folded into a count everywhere — in the trail, in its detail, and in the rule rankings of the Activity page — and shown on demand.

The WAF trail: every inspected request with its mode, verdict, the rules that matched and whether the body was inspected whole

Filtered on would have blocked, it is the list of real requests a monitoring ruleset would have refused — the honest measure of what arming it will cost — and each one opens on the rules that got it there.

The WAF trail filtered on the requests a monitoring ruleset would have blocked

A WAF trail opened: a request that would have been blocked, and the rules that matched it

Creating and editing​

Every entity of the suite is created, edited and deleted from the studio — WAF configs and rulesets, threat policies, bot policies, challenge providers, honeypots, threat feeds, CrowdSec bouncers and ASN databases.

Creation and edition are the same form. "New" opens the editor on a seed rather than asking for a name and leaving the rest to be found later, so what you fill in at creation is what you will see when you come back. Nothing is written until you confirm.

The entity editor: a threat policy open in the drawer, with Delete and Full form beside Save

The same drawer creates and edits. The fields are the ones that decide behaviour, in the order they are reasoned about; Full form in the footer goes to the complete backoffice form, and Delete removes the entity.

That seed always comes from the entity's own _template: it is what the extension considers a sane empty entity, and it moves when the entity gains a field. The studio overrides it in exactly two places, both in the same direction — a thing that can refuse traffic starts by observing:

  • a WAF config is seeded in monitoring mode, whatever rules it carries, because arming a ruleset that has never seen this traffic is the one move worth doing in the other order;
  • a vendor challenge provider is seeded disabled, because one without its keys would serve a challenge nobody can pass.

Two of them are seeded from something the extension already knows how to build, so the studio asks one question first and then opens the same editor on the result: a threat feed from the catalog — url, parser, refresh interval, weight and signal tag included — and a challenge provider from a vendor preset.

A WAF config carries a live badge saying whether its rules compile, which rulesets it references that do not exist, and whether its CRS dials are being ignored for want of a CRS import.

An edited view of the whole entity

The fields the studio shows are the ones that decide behaviour, in the order they are reasoned about, with help text that says what a number actually does. Everything is edited here — the studio does not send you back to the backoffice for anything, and there is no outward "open in Otoroshi" link on an entity.

The Fleet page: every route of the install, its status, and where its protection comes from

Under the workspaces, a section for what belongs to the install. The Fleet page walks every route the router knows and says whether it is protected by its own slots, by a workspace of the table, or by nothing at all.

Permissions​

Reading needs a backoffice session. Editing the table needs a super admin, because the table lives on the global configuration: that is the danger zone by another name. Everything else — the entities, the bans, the allowlist — follows the usual tenant and team rights of the admin API.