Close the loop between detection and training. When a Cisco XDR incident names an
employee — the person who clicked the link, submitted credentials, or ran the
attachment — this assigns them a short remedial lesson in
RansomLeak without the analyst leaving their
investigation.
It reads the email observables off an incident and creates one assignment per
person through RansomLeak's partner integration API, returning a deep link
straight to the lesson.
$ python assign_training.py --incident-file incident.json
OK jane.doe@example.com -> assigned (7c2c3d3e-1234-5678-9abc-1234567890ab)
https://acme.ransomleak.com/a/eyJhbGciOi...
OK sam.patel@example.com -> assigned (9f1b7a20-4321-8765-cba9-0987654321fe)
https://acme.ransomleak.com/a/eyJhbGciOi...
Security awareness training is usually scheduled annually and disconnected from
what actually happens on the network. The incident that proves someone needs
training is the one moment they will remember it. Assigning the lesson while the
incident is still open turns a detection into a teaching moment, and gives the
security team a record that they responded to the human side of the incident,
not just the technical one.
email / user observablesintegration scope, created by a RansomLeakgit clone <this-repo> cd cisco-xdr pip install -r requirements.txt cp .env.example .env # then fill it in set -a; . ./.env; set +a
All configuration is environment variables. Nothing is stored in the repo.
| Variable | Required | Description |
|---|---|---|
RANSOMLEAK_BASE_URL |
yes | Your tenant URL, e.g. https://acme.ransomleak.com |
RANSOMLEAK_API_TOKEN |
yes | Partner API token with the integration scope |
RANSOMLEAK_EXERCISE_SLUG |
yes | Lesson to assign, e.g. phishing-introduction |
RANSOMLEAK_CALLBACK_URL |
no | RansomLeak POSTs here when the lesson is completed |
RANSOMLEAK_API_TOKEN can assign training to anyone in your tenant. Store it the
way you store any other API credential.
Assign to everyone named in an incident:
python assign_training.py --incident-file incident.json
Assign a single address, which is what a pivot-menu trigger on an email
observable gives you:
python assign_training.py --email jane.doe@example.com --incident-id INC-2049
Read the incident from stdin, for piping out of another tool:
cat incident.json | python assign_training.py --incident-file -See exactly what would be sent, without sending it:
python assign_training.py --incident-file incident.json --dry-run
| Exit code | Meaning |
|---|---|
0 |
Every assignment succeeded, or --dry-run, or the incident named nobody |
1 |
Configuration or input error; nothing was sent |
2 |
At least one assignment failed; the rest were still attempted |
Point a workflow at this script and it runs wherever your workflow runner
executes. The two triggers that fit:
email or user observable, which puts "assign training"The idempotency key is derived from the incident, the person, and the lesson:
cisco-xdr:<incident-id>:<email>:<exercise-slug>
Re-running on the same incident replays the original assignment and reissues its
deep link rather than assigning the same lesson twice. That is what makes this
safe to attach to an automatic trigger, and it means you can re-run after fixing a
configuration mistake without spamming your employees.
user observables only when they contain an email address. A bareBSD 3-Clause. See LICENSE.
Provided as sample code to demonstrate the integration. It is not a supported
Cisco product. Test it against a non-production RansomLeak tenant before wiring it
to an automatic trigger, and confirm the lesson you assign is proportionate to the
incident that triggered it.
Code Exchange Community
Get help, share code, and collaborate with other developers in the Code Exchange community.View Community