Training module · Draft
Ticket-to-Machine, Module 2: The Boundary and Least Privilege
Confirm what runs where, then prove every integration identity holds exactly what its calls need
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-07.
Learning path: Ticket-to-Machine on ServiceNow and SailPoint · Module 2 of 7 · 60 minutes · Guide Gate 1 · Workbook Chapter 02 and Chapter 03
Watch: the narrated deck for this module: Deck · ▶ Watch (about 13 minutes, captions) · MP4 · Script · Captions.
Unit 1: Introduction
3 minutes, with the objectives and prerequisites
Before any call is made, you need to know which actions run from a vendor’s cloud, and which non-person identities make them. Then each identity must hold exactly what its calls need. An administrator who grants itil “to make it work” has given the integration every ITSM table; an API client with a manage scope can change accounts if its token is stolen. In this module you confirm the boundary on paper and make privilege something a test can check.
The federal requirement. The guide’s Gate 1 requirements and evidence table maps the boundary to NIST SP 800-53 SA-9, CA-3, IA-5 and AC-6 and to FedRAMP authorization. The chapters’ tables map the call list to AC-6, AC-2, AC-5 and CM-3: see Chapter 02 and Chapter 03. 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 what Gate 1 records about each product’s authorization and each vendor-cloud action.
- Describe the ServiceNow roles the kit uses, and why they are split by task.
- Describe the ISC scopes and Graph permissions each task needs, and why the workflow scope gets its own client.
- Verify a grant against the call list, and catch a grant that is too wide.
Prerequisites
- Module 1.
- For the Graph rows, Microsoft Automation, Module 1: permissions.
Unit 3: ServiceNow roles, split by task
10 minutes
config/calls.json lists every HTTP call a Python client makes, the task that makes it, the least privilege it needs and the vendor page that says so. A test runs the clients against a fake HTTP session and fails on any call the file doesn’t declare. The ServiceNow roles are custom roles split by task: a finding writer, a verifier and an evidence reader. Read:
- Chapter 02: what exists, for the token order, paging and retries.
- Chapter 02: what this chapter adds, for the call list and why each role exists.
- Chapter 02: dangers.
Unit 4: ISC scopes and Graph permissions
10 minutes
The drift and re-read clients need read scopes only. Creating the ISC workflows needs a manage scope that no client in the kit uses, so it belongs to a separate client used once. The Graph app registration needs User.Read.All, and AuditLog.Read.All only if the run reads the audit. Read:
- Chapter 03: what exists, including what a client-credentials token can’t do in ISC.
- Chapter 03: what this chapter adds, for the ISC and Graph rows and
--required-only. - The implementation example’s permissions.
Unit 5: 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_kit_calls.py -q
# Step 2
python clients/python/kit_calls.py --task reread --system servicenow
# Step 3
python clients/python/kit_calls.py --task reread --system servicenow --granted "x_example_idkit.verifier,itil"
# Step 4
python clients/python/kit_calls.py --task evidence --system servicenow --granted "x_example_idkit.verifier"
# Step 5
python -m pytest tests/python/test_kit_common.py -q -k "sn_ or retry or paging or base_urls"
# Step 6
python -m pytest tests/python/test_kit_common.py -q -k isc
# Step 7
python clients/python/kit_calls.py --task drift --system isc
# Step 8
python clients/python/kit_calls.py --task drift --system isc --granted "sp:search:read,idn:accounts:read,idn:accounts:manage"
# Step 9
python clients/python/kit_calls.py --task workflows --system isc --granted "sp:search:read,idn:accounts:read"
# Step 10
python clients/python/kit_calls.py --task drift --system graph --granted "User.Read.All"
python clients/python/kit_calls.py --task drift --system graph --required-only --granted "User.Read.All"You prove every call is declared, then compare grants with the call list for ServiceNow, ISC and Graph. Work in examples/servicenow-sailpoint. Chapter 02, Lab 1 and Chapter 03, Lab 1 explain each result.
Part A: ServiceNow (Chapter 02)
Prove every call is declared.
python -m pytest tests/python/test_kit_calls.py -qExpected:
9 passed.List what the re-read client needs on ServiceNow.
python clients/python/kit_calls.py --task reread --system servicenowExpected output:
Task reread: reread_verification.py: list waiting findings, re-read each subject, close or reopen with evidence servicenow POST /oauth_token.do an inbound OAuth client (client credentials) with its own integration user GET /api/now/table/u_identity_finding x_example_idkit.verifier (read on u_identity_finding) PATCH /api/now/table/u_identity_finding/{sys_id} x_example_idkit.verifier (write on u_identity_finding) POST /api/now/attachment/file x_example_idkit.verifier (create on sys_attachment) needs: x_example_idkit.verifierCatch a grant that is too wide: an administrator gave the verifier
itilas well.python clients/python/kit_calls.py --task reread --system servicenow --granted "x_example_idkit.verifier,itil"Expected: the listing, then
missing: none,extra: itilandLeast privilege does not hold: fix the grant.The command exits 1.Catch the evidence export reusing the verifier’s role.
python clients/python/kit_calls.py --task evidence --system servicenow --granted "x_example_idkit.verifier"Expected:
missing: x_example_idkit.evidence_reader,extra: x_example_idkit.verifier, exit 1.Run the original ServiceNow client tests.
python -m pytest tests/python/test_kit_common.py -q -k "sn_ or retry or paging or base_urls"Expected:
7 passed, 12 deselected.
Part B: ISC and Graph (Chapter 03)
Run the ISC client tests.
python -m pytest tests/python/test_kit_common.py -q -k iscExpected:
4 passed, 15 deselected.List what the drift client needs from ISC.
python clients/python/kit_calls.py --task drift --system iscExpected output:
Task drift: identity_drift.py: read Graph users, the Entra audit, ISC identities and uncorrelated accounts isc POST /oauth/token API client (client credentials) or a personal access token POST /v3/search sp:search:read GET /v3/accounts idn:accounts:read needs: idn:accounts:read, sp:search:readCatch a manage scope on a read client.
python clients/python/kit_calls.py --task drift --system isc --granted "sp:search:read,idn:accounts:read,idn:accounts:manage"Expected:
missing: none,extra: idn:accounts:manage,Least privilege does not hold: fix the grant., exit 1.Check the drift client’s scopes against the workflow task.
python clients/python/kit_calls.py --task workflows --system isc --granted "sp:search:read,idn:accounts:read"Expected:
missing: sp:workflow:manage,extra: idn:accounts:read, sp:search:read, exit 1. The two jobs need two clients.Check the Graph app registration, first for a drift run that reads the audit, then for one that doesn’t.
python clients/python/kit_calls.py --task drift --system graph --granted "User.Read.All" python clients/python/kit_calls.py --task drift --system graph --required-only --granted "User.Read.All"Expected: the first reports
missing: AuditLog.Read.Alland exits 1; the second reportsLeast privilege holds.and exits 0.
Check your work: for any kit task, you can list the permissions it needs on each system and show whether a grant matches.
Unit 6: Exercise: Lab 2 (your test instance)
Not timed. Not run by the authors.
- ServiceNow: in your Personal Developer Instance, create the three custom roles, one integration user and one OAuth client-credentials integration per role, compare each user’s roles with the kit’s call list, and confirm the evidence reader can’t patch a record. Follow Chapter 02, Lab 2. Back it out with its step 5: delete the OAuth integrations, users and roles, and revoke any saved token.
- SailPoint: in an ISC sandbox tenant, create a reader API client and a separate workflow client, compare each with the call list, and try the reader. Follow Chapter 03, Lab 2. Back it out with its step 5: delete both API clients (or the personal access tokens and the dedicated user) and anything under
out. - You need: the developer instance from Module 1’s Lab 2 and a SailPoint sandbox tenant.
Unit 7: Knowledge check
5 minutes
kit_calls.py --task reread --system servicenow --granted "x_example_idkit.verifier,itil"reportsextra: itil. What does that mean?- The grant is fine; extra roles are ignored.
- Least privilege doesn’t hold: the grant is wider than the task needs, and the command exits 1.
- The verifier role is missing.
- Why does the evidence export get its own
x_example_idkit.evidence_readerrole instead of reusing the verifier’s?- The verifier role can’t read
u_identity_finding. - With the verifier’s role, the export could also close findings; the reader can’t change a record it’s about to hash.
- ServiceNow allows only one integration user per role.
- The verifier role can’t read
- Which ISC scope belongs on a separate client that is used once and then removed?
sp:search:readidn:accounts:readsp:workflow:manage
- Gate 1 asks you to record which actions run from a vendor’s cloud. Why?
- Book 15 prefers execution through a connector inside the boundary, so each vendor-cloud action is a recorded data flow.
- Vendor-cloud actions can’t be used at FedRAMP Moderate.
- The FedRAMP Marketplace requires the agency to list them.
- b.
--grantedexits 1 on anything missing or extra. See Chapter 02, Lab 1. - b. Roles are split by task so the reader can’t change what it hashes. See Chapter 02: what this chapter adds.
- c. No client in the kit creates workflows, so that scope gets its own client. See Chapter 03: what this chapter adds.
- a. Each vendor-cloud action becomes a recorded data flow. See step 4 of the guide’s Gate 1.
Unit 8: Summary
2 minutes
You confirmed what Gate 1 records, learned the roles, scopes and permissions each kit task needs, and caught three kinds of over-wide grant on a laptop.
Evidence an ISSO keeps from this module: the Marketplace listings with the date read, the vendor’s written answers, the data-flow record and the identity register (Gate 1); config/calls.json and its test, and the kit_calls.py --granted output kept with each access approval (Chapters 02 and 03). Before shipping, work through the Chapter 02 checklist and the Chapter 03 checklist.