Skip to content

IRMA for developers: recipes

Four recipes. Each says which door it uses and what comes later. The concepts behind them are in Concepts.

Through /agent/v1 (service token). Your SIEM, monitoring or service desk reports incidents into the Incidenten (incidents) register, without duplicates.

You need: a service token with the incidents:write scope (see Quickstart).

1. Decide the fields per report.

FieldFrom your systemTip
titleThe name of the rule or ticket.Short and recognizable; the first report keeps the title.
descriptionWhat happened.At metadata level: kind of failure, system, time. No personal data or case contents.
severityThe severity from your system.Map to laag, middel, hoog or kritiek (low, medium, high, critical).
sourcekind + name + reference.reference = the link to your alert or ticket, so you can click back from IRMA.
fingerprintRule + object.For example siem-rule-4711:fw-01. No timestamp.
occurredAtTime of the report.ISO 8601 with time zone.

Optional: impact, remediation (what has been done already), resolvedAt, links to an asset, vendor, information system or risk already in IRMA ({ "entityType": "asset", "entityId": "<uuid>" }), and metadata (free JSON, at most 8 KB).

2. Why the fingerprint matters. IRMA recognizes an incident by its fingerprint within your organization. When the same fingerprint comes back, IRMA does not create a new incident: the occurrence count goes up, the last-seen time moves on, and the severity goes up with it if the new report is more severe (never down). The title and description of the first report stay. Your register shows one clear incident instead of a hundred alerts.

3. Report and act on the outcome. An example for a webhook or cron job with the CLI:

#!/usr/bin/env bash
# Run per alert. RULE and OBJECT come from your SIEM.
irma incident create --json --no-dry-run --yes \
--title "$TITLE" --severity "$SEVERITY" --description "$DESCRIPTION" \
--source-kind agent --source-name siem --source-ref "$ALERT_URL" \
--fingerprint "$RULE:$OBJECT" > /tmp/irma-incident.json
case $? in
0) ;; # created, or counted on an existing incident
2) echo "refused or misconfigured: fix it, do not repeat" >&2; exit 2 ;;
*) echo "unknown outcome: try again on the next alert" >&2 ;;
esac

Without the CLI it is one POST https://api.irma.prudai.com/agent/v1/incidents; 201 is new, 200 counted. Repeating a call with the same fingerprint is safe: at most it adds one to the count.

4. Check. irma incident list --status nieuw (scope incidents:read) or look in IRMA under Incidenten.

Through /v1 (user token).

You have two Monte Carlo runs, say from before and after a new control, and want to know what differs.

Terminal window
irma simulations list # runs, newest first, with 'still current?'
irma simulations compare <run-a> <run-b>

The comparison does not recalculate: it puts the two stored results side by side. You get the percentiles of A and B with the difference, which risks took part only in A or only in B, which risks moved most, and a short explanation. Check sameSeed, sameIterations and sameScope first: if the seed, the number of iterations or the selection differ, part of the difference comes from there and not from your register.

A new run with the same seed makes the result reproducible:

Terminal window
irma simulations run --iterations 10000 --seed 42 # dry run: shows which risks take part
irma simulations run --iterations 10000 --seed 42 --no-dry-run --yes

Risks without a financial estimate do not take part; the dry run and the envelope (completeness.excluded) count them separately.

Through /v1 (user token).

You imported your risk register from Excel and want to know what has changed since: for a management review, or because an auditor asks.

Terminal window
irma risk-profile compare --from import
irma risk-profile compare --from 2026-07-01 --to 2026-10-01

You get the risks that were added, removed and changed, with the old and new value per field. --from import is the moment of the first risk import; if there never was one, you get 422. A date means the end of that day (UTC). To see who made a change, ask for that risk’s history:

Terminal window
irma risks history <risk-id>

Partly later. Reading works with /v1, including the audit checks; writing drafts back into IRMA comes later.

The audit checks are fixed rules over your register (does every control have an owner, evidence that meets the norm, is there an open nonconformity) per control, risk, requirement and organization, with a completeness score whose formula and weights are in the answer. They only read, store nothing, and need full read access:

Terminal window
irma audit summary # score, formula and count per check (default iso27001-2022)
irma audit checks --outcome fout # only what fails, per subject

A coding agent such as Claude Code, with the IRMA skill, can prepare an internal audit: it gathers the state of play and writes a proposal for a person to review. A task could read:

Prepare the internal ISO 27001 audit. Start with `irma context --json`.
Get the coverage with `irma compliance coverage <framework>` and the audit checks with `irma audit summary` and `irma audit checks --outcome fout,waarschuwing`, and list the open requirements.
For each open requirement find the related risks and their history.
Write a preparation note with, per requirement: status, what is missing, and which call you used.
State the provenance of every number and say so if the read scope is limited. Change nothing in IRMA.

The agent follows the envelope: it pages until nextOffset is empty, uses notIncluded and next to ask further, and invents no numbers that no run or record produced. The result is a note for the auditor or CISO, not a change in your registers. Once drafts are possible through the API, the agent prepares its proposals as drafts in IRMA.