Skip to main content
This is not an official U.S. federal government website. The Federal Modernization Workbook is independent technical analysis. It does not represent the position of, and has not been reviewed or endorsed by, any federal agency.

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

Research draft: Module 2 of the Ticket-to-Machine learning path. You confirm the authorization boundary and the integration identities, then use the kit’s call list and kit_calls.py to compare ServiceNow roles, ISC scopes and Graph permissions with what each task needs. Guide Gate 1; workbook Chapters 02 and 03.
Modified

November 1, 2026

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

Unit 2: The authorization boundary

8 minutes

Gate 1 records and decides; it builds nothing. You confirm each product’s FedRAMP status on the Marketplace, ask the vendor in writing what’s inside the authorization, record which actions run from a vendor’s cloud as data flows, and register the integration identities (the two connections and the seven the kit runs) with a certificate or federated credential, never a long-lived secret. Read:

  • The guide’s Gate 1: its steps, its availability table and its interim path.
  • The guide’s prerequisites, for the integration identities.
  • The guide’s Validate (G1 Boundary) step, which names the validation-kit checks and the manual record.

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:

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:

Unit 5: Exercise: Lab 1 (fixtures, no tenant)

22 minutes

NoteEvery command in Lab 1

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)

  1. Prove every call is declared.

    python -m pytest tests/python/test_kit_calls.py -q

    Expected: 9 passed.

  2. List what the re-read client needs on ServiceNow.

    python clients/python/kit_calls.py --task reread --system servicenow

    Expected 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.verifier
  3. Catch a grant that is too wide: an administrator gave the verifier itil as well.

    python clients/python/kit_calls.py --task reread --system servicenow --granted "x_example_idkit.verifier,itil"

    Expected: the listing, then missing: none, extra: itil and Least privilege does not hold: fix the grant. The command exits 1.

  4. 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.

  5. 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)

  1. Run the ISC client tests.

    python -m pytest tests/python/test_kit_common.py -q -k isc

    Expected: 4 passed, 15 deselected.

  2. List what the drift client needs from ISC.

    python clients/python/kit_calls.py --task drift --system isc

    Expected 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:read
  3. Catch 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.

  4. 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.

  5. 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.All and exits 1; the second reports Least 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

  1. kit_calls.py --task reread --system servicenow --granted "x_example_idkit.verifier,itil" reports extra: itil. What does that mean?
    1. The grant is fine; extra roles are ignored.
    2. Least privilege doesn’t hold: the grant is wider than the task needs, and the command exits 1.
    3. The verifier role is missing.
  2. Why does the evidence export get its own x_example_idkit.evidence_reader role instead of reusing the verifier’s?
    1. The verifier role can’t read u_identity_finding.
    2. With the verifier’s role, the export could also close findings; the reader can’t change a record it’s about to hash.
    3. ServiceNow allows only one integration user per role.
  3. Which ISC scope belongs on a separate client that is used once and then removed?
    1. sp:search:read
    2. idn:accounts:read
    3. sp:workflow:manage
  4. Gate 1 asks you to record which actions run from a vendor’s cloud. Why?
    1. Book 15 prefers execution through a connector inside the boundary, so each vendor-cloud action is a recorded data flow.
    2. Vendor-cloud actions can’t be used at FedRAMP Moderate.
    3. The FedRAMP Marketplace requires the agency to list them.
  1. b. --granted exits 1 on anything missing or extra. See Chapter 02, Lab 1.
  2. b. Roles are split by task so the reader can’t change what it hashes. See Chapter 02: what this chapter adds.
  3. c. No client in the kit creates workflows, so that scope gets its own client. See Chapter 03: what this chapter adds.
  4. 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.

Back to top