Training module · Draft
Ticket-to-Machine, Module 1: The Loop and the Typed Task
Where the kit sits in Book 13’s five-step loop, and how to check the identity finding before it reaches ServiceNow
Status — Draft
This page is still being written. Expect gaps and changes; it is not part of the workbook's production guidance. Last reviewed 2026-11-09.
Learning path: Ticket-to-Machine on ServiceNow and SailPoint · Module 1 of 7 · 50 minutes · Guide Gate 4 · Workbook Chapter 01
Watch: the narrated deck for this module: Deck · ▶ Watch (about 14 minutes, captions) · MP4 · Script · Captions.
Unit 1: Introduction
3 minutes, with the objectives and prerequisites
Your agency’s service desk closes an access ticket when a technician types “done.” Nobody can say who owned the drift, when it fell due, or what the account should look like afterward. Book 13’s answer is a typed task: one record with a class, a severity, an owner, a clock and an intended state that a later re-read can check. Every step of the loop writes or reads that record, so you start with it.
The federal requirement. Gate 4 turns findings and requests into documented, owned, clocked records. The guide’s Gate 4 requirements and evidence table maps it to NIST SP 800-53 CM-3, RA-7, CA-7 and AC-5, and the chapter’s federal requirements and evidence says what the contract check proves and who keeps it. Each table’s KSI column names the FedRAMP 20x Key Security Indicators to line your evidence up with; your cloud providers report against them, the agency doesn’t.
Learning objectives
In this module, you’ll:
- Explain the loop’s five steps and name the kit file for each step that has one, and the step that has none.
- Describe the fields of the identity finding’s data contract and what each one is for.
- Validate a finding payload on a laptop and predict whether ServiceNow accepts, rejects or de-duplicates it, and when it falls due.
- Recognize an intended state that gives the re-read nothing to check.
Prerequisites
- The path’s prerequisites, and the Lab 1 tools.
- No ServiceNow instance or SailPoint tenant until Lab 2.
Unit 2: The loop, and where the kit sits
8 minutes
The loop has five steps: test, detect drift, raise a typed task, actuate on the native surface, and close with evidence. The kit has three builds in Pass 1 that cover four of them and leaves actuation to a later pass. Read these, in order:
- Book 13, Appendix B: the coordination loop, for the five steps.
- Chapter 01: the loop, and where the kit sits, for the table that maps each step to a kit file and a chapter.
- The guide’s loop at a glance, for the products that do each step, and the four gaps between the products and the loop.
As you read, note which step has no code in Pass 1. You’ll meet it again in Module 6.
Unit 3: The identity finding and its contract
10 minutes
The Scripted REST resource inside ServiceNow enforces the finding’s contract: it validates the payload, maps severity to a priority and a due date on the program’s tempo, de-duplicates against an active finding, and derives an intended state when the payload has none. Until Chapter 01, nothing outside ServiceNow applied the same rules, so a client learned a payload was wrong only from a 400 on a live instance.
finding_contract.py applies those rules on a laptop, and a test keeps its constants in step with the script. Read:
- Chapter 01: what exists and what this chapter adds, especially
is_checkable. - The contract’s fields in the kit’s README, and where they land in Book 13’s evidence record in the implementation example’s table.
- Book 13, Appendix B: severity and tempo, for the windows the due dates come from.
Unit 4: Exercise: Lab 1 (fixtures, no tenant)
22 minutes
Every command in this lab, in order, from examples/servicenow-sailpoint. Each step below says what it does and what to look for.
# Step 1
python -m pytest tests/python/test_finding_contract.py -q
# Step 2
python clients/python/finding_contract.py --validate tests/fixtures/payloads/samples.json --now 2026-11-01T12:00:00Z
# Step 3
node --test tests/servicenow/servicenow_scripts.test.js
# Step 4
python clients/python/identity_drift.py --hr-csv tests/fixtures/hr_extract.csv --config tests/fixtures/config.fixtures.json --graph-users-json tests/fixtures/graph_users.json --isc-identities-json tests/fixtures/isc_identities.json --isc-accounts-json tests/fixtures/isc_uncorrelated_accounts.json --entra-audit-json tests/fixtures/entra_audit.json --out-json out/day1.json --out-csv out/day1.csv
python clients/python/finding_contract.py --from-drift out/day1.json --now 2026-11-01T12:00:00Z
# Step 5
rm -rf outYou check payloads the way the Scripted REST resource would, then check every payload the drift client would post. Work in examples/servicenow-sailpoint. The chapter’s Lab 1 explains each result.
Run the chapter’s tests.
python -m pytest tests/python/test_finding_contract.py -qExpected:
26 passed.Check five sample payloads.
python clients/python/finding_contract.py --validate tests/fixtures/payloads/samples.json --now 2026-11-01T12:00:00ZExpected output (the command exits 1, because two payloads would be rejected):
sample-1-good: ok stale_access P2 priority 2 due 2026-11-01T13:00:00Z system entra_user sample-2-typo: 400 drift_class must be one of missing_identity, stale_access, orphan_account, attribute_drift, unauthorized_write, credential_drift, schema_drift sample-3-empty-intent: ok unauthorized_write P2 priority 2 due 2026-11-01T13:00:00Z system isc_account sample-3-empty-intent: warning: intended_state names nothing a re-read can check (expected: Book 13 routes this class to a person, who sets it) sample-4-bad-severity: 400 severity must be P1, P2, P3 or P4 sample-5-closure: ok closure_signal (moves matches to Awaiting verification; never closes) 3 accepted, 2 rejected, 0 would de-duplicateRun the ServiceNow script’s own tests, the rules the Python mirrors.
node --test tests/servicenow/servicenow_scripts.test.jsExpected:
tests 15,pass 15,fail 0.Run the drift reconciliation over the fixtures, then check the payloads it would post.
python clients/python/identity_drift.py --hr-csv tests/fixtures/hr_extract.csv --config tests/fixtures/config.fixtures.json --graph-users-json tests/fixtures/graph_users.json --isc-identities-json tests/fixtures/isc_identities.json --isc-accounts-json tests/fixtures/isc_uncorrelated_accounts.json --entra-audit-json tests/fixtures/entra_audit.json --out-json out/day1.json --out-csv out/day1.csv python clients/python/finding_contract.py --from-drift out/day1.json --now 2026-11-01T12:00:00ZExpected: twelve lines start
ok, three carry the warning (two missing identities and the unauthorized write), and the last line is12 accepted, 0 rejected, 0 would de-duplicate.Delete the
outfolder.rm -rf out
Check your work: for any payload, you can say what the Scripted REST resource will do with it.
Unit 5: Exercise: Lab 2 (your test instance)
Not timed. Not run by the authors.
In a ServiceNow Personal Developer Instance, never production, you build the finding table and the Scripted REST resource, lock it down with a REST_Endpoint ACL, post a payload you checked in Lab 1, and confirm the de-duplication and the 400. Follow Chapter 01, Lab 2.
- You need: a Personal Developer Instance, and the
web_service_adminrole to create the Scripted REST API. - Back it out: step 5 of the chapter’s Lab 2 deletes the test records, the ACL, the role, the API and the scoped application.
Unit 6: Knowledge check
5 minutes
- A payload has
drift_classset tostale_accessand noseverity. What does the Scripted REST resource do?- Rejects it with a 400, because severity is required.
- Accepts it as P4, with a 72-hour window.
- Accepts it with the class default, P2, and a one-hour window.
- An intended state is
{"attributes": {}, "entitlements_absent": []}. Why doesfinding_contract.pywarn about it?- ServiceNow rejects an empty object with a 400.
- It looks present, but a re-read finds no difference against it and would close the record on nothing.
- It makes the finding de-duplicate against every other finding for the subject.
- What does a
closure_signalpayload do to matching findings?- Closes them.
- Moves them to Awaiting verification; it never closes them.
- Reopens them for the owner to review.
- Which loop step has no code in the kit’s Pass 1?
- Raise a typed task.
- Actuate on the native surface.
- Close with evidence.
- c. The script defaults severity by class, and sample 1 got P2 with a one-hour window. See Chapter 01, Lab 1.
- b. A non-empty object can still name nothing checkable. See
is_checkablein what this chapter adds. - b. A signal moves matches to Awaiting verification; only a re-read closes. See sample 5 in Chapter 01, Lab 1.
- b. No Pass 1 code writes to Entra ID, Active Directory or ISC. See the loop, and where the kit sits.
Unit 7: Summary
2 minutes
You mapped the kit to the loop, read the finding’s contract, and checked payloads on a laptop the way ServiceNow will, including every payload the drift client would post.
Evidence an ISSO keeps from this module: the ServiceNow finding records and the contract tests in the repository; each record’s due date, which Module 7 measures. The chapter’s federal requirements and evidence lists them; before shipping, work through its checklist.