Community pools
A pool gives several communities — one per team — exactly the same content: the same logs on the same technologies, the same OCSF inventories, the same grafted threat, the same scenarios launched on the fly. It is made for Capture The Flag sessions, where each team works in its own Sekoia space and none may receive more, less or something else than the others.
/pools lists the pools; each one opens on its template, its teams, their delivery and their
alignment.
Shared, and each team's own
The pool shares what is produced; each team keeps where it is delivered.
| Part | What it covers | Where it lives |
|---|---|---|
| Production | Population, company profile, time zone, weekend, the set of technologies, threat, compromised hosts, archetype assignments | Shared — set on the template or any team, technologies on the pool page |
| Delivery | Name, description, destination, API base, intake keys, Sekoia API key, asset connectors | Each team's own — the pool page; the template has none |
| State | Started or stopped, technologies cut off, consecutive failures | Each team's own; the template is always stopped |
There is no “pool settings” screen to keep in step with the teams: a production setting saved on the template's page or a team's page is written on all of them, in one transaction. A team's page says so with a banner, “Team of the pool”, on every tab; the template's page with its own, “Template of the pool”.
The set of technologies is the exception: it is chosen on the pool page (see below), and a team's Technologies tab only lists the pool's technologies, each with this team's intake key — “Save the keys” writes the keys and nothing else. A team page left open can therefore not undo a choice made on the pool page in the meantime.
Manual assignment corrections are production too: correcting the archetype of a user on one team corrects it everywhere.
Creating a pool
A pool is born from a community already set up and checked: “Create a pool from it” at the top
of its page, or “New pool” on /pools.
| Field | What it decides |
|---|---|
| Pool name | Unique |
| Model community | The production the teams copy; it becomes the pool's template and stops sending. A community already in a pool is not offered |
| Teams to add | The template is not a team: it sends nothing — 30 teams at most |
| Team name pattern | {n} is replaced by the team number, on two digits; left empty, <model> – Team {n} |
The model becomes the pool's template (below): its identifier becomes the seed of the whole pool, so the teams receive, bit for bit, the day it would have produced. They copy its production — never its keys nor its connectors — and are born stopped. A team name already taken refuses the creation, naming it, and nothing is created.
The template
The community the pool is born from becomes its template — the Template card, at the top of the pool page, leads to its page. It holds the production the teams receive and sends nothing: neither logs nor inventories. It is not a team: it is not counted, it is neither in the Teams table nor in the delivery grid, and starting the pool does not judge it — it has no key to carry.
- It is stopped when the pool is created, if it was running, and its page no longer offers to start it.
- Its page keeps everything that is produced — population, time zone, weekend, threat, assignments — under the “Template of the pool” banner: a setting saved there applies to every team.
- Nothing that delivers is there: no destination nor Sekoia API key in Settings; no key in Technologies, which lists the pool's technologies without fields; no connector or “Send now” in Assets, where only the Preview stays — it shows what the teams will receive; no launch in Threats, which points to the pool page instead.
- Its previous keys and connectors stay in the database, hidden and unused.
- On
/communautes, its row reads “Template” rather than “Stopped”.
Technologies: chosen once, for every team
The Technologies card holds one box per technology, and nothing else: a key says where one team receives, so it does not belong to the pool. “Save the technologies” writes the set on every team at once.
- A technology added is born without a key at every team: the Delivery card then asks each team for one, and the Teams table names it on every row until it is entered.
- A technology removed clears its key at every team.
- With no technology at all, each block of the Delivery card says so, instead of an empty list of keys.
Delivery: one form for every team
The Delivery card holds one block per team — the template has none: destination, API base, the team's Sekoia API key — its only Sekoia key, which sends its inventories and creates its intakes and connectors —, one intake key per technology of the pool, and the configuration UUID of each asset connector. A block opens on its own while its team lacks a key — which is the case of every team of a pool just created.
- A saved key is never shown again, only its mask (
••••1a2b). Leaving a field empty keeps the key; clearing it takes the explicit “clear” box. - Only what changes is sent. Writing a destination makes the team rebuild its day plan, even when the value is the same; saving the grid for one key must not do that to twenty teams.
- A team without a key for a technology receives a subset of the content. The Teams table names the missing technologies on its row.
- Each intake key carries a Create in Sekoia button: the intake is created in the team's Sekoia space with the team's Sekoia API key, and its key set, exactly as on a community. Every team is its own Sekoia space — its key and its entity are never copied to another one. The key can also be set on the team's own page, in the Settings tab: it is the same field.
- Each empty asset connector UUID also carries a Create in Sekoia button: the connector is created in the team's Sekoia space with the team's Sekoia API key, and its UUID set, exactly as on a community. The field shows the UUID without a reload, and saving the grid afterwards keeps it.
Creating every intake in one gesture
Two buttons spare the 870 clicks of a thirty-team pool on twenty-nine formats.
- Create the intakes of every team, at the top of the card, creates every possible intake of every team.
- Create all its intakes, next to a team's intake keys, does the same for that team only.
An intake is possible when the unit button would be offered: a supported technology, without a key. A team without an API base or without a Sekoia API key is skipped, and named. The batch runs in the background, three teams at a time and one technology after another within a team.
- The click returns at once. The Intake batch card shows the progress, then team by team what was created, what failed and why, and what was skipped. The masks appear in the grid as keys are set. Without JavaScript, reload the page to follow it.
- One intake batch at a time per pool: the buttons are disabled while one runs, and a button with nothing to create says why. An asset connector batch does not block it.
- A refusal that would repeat — the key's account, the entity — stops its team. A refused intake stops only its technology, so that one format missing from a space does not block the others.
- If api-asset restarts during a batch, the batch is interrupted, never replayed. Starting it again is safe: only the technologies still without a key are attempted.
Creating every asset connector in one gesture
The pool has no set of connector formats of its own — each team sets its connectors in the grid — so the batch creates the formats ticked at launch. Six boxes sit at the top of the card, all unticked: creating things in Sekoia is ticked on purpose.
- Create the connectors of every team creates, for every team, each ticked format it has no connector for yet.
- Create its checked connectors, next to a team's connector UUIDs, does the same for that team only.
- Nothing ticked: refused, and said, before anything leaves.
Each connector is created exactly as the unit button would — module configuration, connector, UUID set, collection stopped — with the team's Sekoia API key. A team without an API base or without that key is skipped, and named. The batch runs in the background, like the intake batch:
- the Asset connector batch card shows the progress, then team by team what was created — with its UUID —, what failed and why, and what was skipped; the UUIDs appear in the grid as they are set, and saving the grid afterwards keeps them;
- one asset connector batch at a time per pool — an intake batch running at the same time does not block it: each kind uses its own key;
- a refused account stops its team, since the key is the same for all its formats; a refused connector stops only its format;
- a connector set in the meantime — by hand, or with the unit button — is skipped, never replaced;
- if api-asset restarts, the batch is interrupted, never replayed: starting it again only attempts the formats still without a connector.
Starting every team in one gesture
“Start the pool” starts every team — never the template — and plans their day on one single instant: they emit from the same minute, and the morning they skip is the same for all. If one team cannot leave — none of its technologies has a key, or no user plays an archetype —, the whole pool is refused, naming each team and why: a half-started pool is not a fair session. “Stop the pool” stops them all.
Today's inventories leave with the logs: starting the pool queues each team's run of the day, under one single instant too, without waiting for the scheduler's next pass nor for 08:00.
A team restarted later — after the cut-off at a hundred failures, or from its own page — resumes at the current minute: a morning is never replayed. The Alignment card names such a team, whatever the cause:
- no day today, or a failed day;
- started late, and by how many minutes;
- skipped minutes that differ from the others';
- technologies cut off at this team only.
Following today’s emissions
The Today’s emissions card says what each team has received today, in the population’s time zone. Four tiles add up the teams that have a day — Messages planned (and how many were discarded, already past when the pool started), Sent, Failed and Left to send today —, then one row per team:
| Column | What it shows |
|---|---|
| Team | Links to the team’s page, which details each technology. |
| Day | The day’s status, and the minute it is up to — No day if the team is not running. |
| Sent | What actually left, out of what could still leave when the day was planned, with a bar. |
| Failed | Messages whose batch was finally refused or lost. |
| Left | What remains to be sent today. |
The figures are counted on the batches actually sent, never on a counter kept beside them. The page follows them live: each batch a team sends refreshes it — the card, the Alignment card and the teams’ state —, while the batches of other communities and of trials do not. Without JavaScript, the page shows the figures as they were when it loaded; reloading it moves them.
Threats and inventories, on the whole pool
Launching a scenario on every team
The Launch a scenario card of the pool page plays a scenario now on every team — never on the template —, under the same seed, the same start minute and the same targets, for a bounded duration. Its fields are those of a community's Threats tab (see Attacker background noise):
- Preview shows the first team, and names it above its messages: the content is identical at every team, only their keys differ. The download replays that team.
- Launch now writes one run per team, and the result lists what each one receives. A team that cannot receive — a destination without a URL, for instance — refuses the whole launch, named: nothing leaves for any team.
- A pool without a team shows a note instead of the form.
Launching from the Threats tab of any team does the same: the tab says so before you click, and links to the pool page. The template's tab launches nothing, and links there too.
Following the launches
The Pool launches card lists the latest launches, one row per launch, whether it left from this page or from a team's tab:
| Column | What it shows |
|---|---|
| Scenario | Links to the scenario in the library. |
| Start | The first minute played — the same at every team. |
| Duration | How long the launch lasts. |
| Targets | The hosts the scenario plays on — the same at every team. |
| Sent / planned | Summed over the teams; failed messages are named beside it. |
| State | Running as long as one team still has messages waiting. |
| Teams | “2 teams”, unfolding onto each one: its progress, its state, a link to its threats. |
Progress is read on the batches sent, never stored, and follows them live, like the emissions above. A detached team leaves this list; its runs stay on its own page.
Inventories
- “Send now” on an asset connector sends the inventory for every team that has a connector of that format, all describing the same instant; those without one are named, and the template is not among them. The daily inventory does the same: the teams share a time zone, so they are due on the same pass — or leave together when the pool is started.
Divergences
The Divergences card only appears when teams no longer share the same production. The pool's single write path cannot cause that; only a write beside it — directly in the database — can. The card names the field and the teams that differ from the template: until it is corrected, the session is not fair.
Detaching, deleting
- “Detach” turns a team back into a plain community. It keeps its configuration and its seed, so it keeps producing the pool's content — harmless, and worth knowing.
- The template cannot be detached: it holds the teams' production.
- Deleting a pool detaches its teams and its template, which becomes a plain community again, stopped, with its previous keys and connectors. Ticking “Also delete its teams, their keys and their history (after the CTF)” removes them with the pool instead — the clean-up after a session.
What it costs
- Volume × N. A hundred users make about 130,000 messages a day per team; the queue payloads and the messages kept 24 hours grow accordingly. Teams receive the same content a few seconds apart: the sender posts five batches at a time.
- Inventories. A software inventory of a pool takes about ⌈N / 3⌉ × 2 minutes — three runs at a time, spaced per connector. A CVE refresh can fall between two teams: the shared instant fixes the time described, not the vulnerability catalogue.
- One process. The planner lock and the day-plan cache live in api-activity's memory: replicas would need a database lock.