Skip to main content

Entity Type Classification — CISO

Role: CISO, SecurityV0 Automation-Analysis Team (Round 5) Date: 2026-02-13 Classification: Internal — Security and Compliance Advisory Scope: What entity type should Business Rules, Script Includes, REST Messages, OAuth Profiles, Flow Designer Flows, and Scheduled Jobs actually be? Analysis from the perspective of a CISO who needs to govern non-human identities, monitor automations, protect resources, rotate credentials, and review external connections. Proposes a security taxonomy that reflects how CISOs actually think about their environment.


Executive Summary

The founder is right. Classifying all automation artifacts as entity_type: "identity" is semantically wrong, and the consequences are not academic. They are operational.

When I open SecurityV0 as a CISO, I expect the "Identities" view to show me things that CAN AUTHENTICATE — Service Principals, OAuth Apps, machine accounts, integration users. These are the entities I need to govern under identity lifecycle management. Instead, I see Script Includes (which are code libraries), REST Message templates (which are connection configurations), and Business Rules (which are event handlers). These are not identities. They cannot authenticate. They do not hold credentials. They do not appear in my identity provider. Including them in my identity inventory inflates my NHI count by 5-10x and makes every identity governance metric meaningless.

This is not a modeling preference. It is a compliance problem, a forensic investigation problem, and a risk assessment problem. This analysis walks through each of these impacts, proposes a security taxonomy based on how CISOs actually categorize their environment, and maps every ServiceNow automation artifact to its correct entity type.

Bottom line: SecurityV0 needs five entity types for security governance, not one. The current model collapses five fundamentally different categories — identity, automation logic, connection configuration, credential material, and data resource — into a single "identity" bucket. This makes the CISO's job harder, not easier.

The five categories are:

CategoryWhat belongsCISO governance action
IdentityService Principals, OAuth Apps, machine accounts, integration usersLifecycle management, access reviews, ownership assignment
Automation ComponentBusiness Rules, Script Includes, Flow Designer Flows, Scheduled JobsExecution monitoring, change detection, blast radius analysis
ConnectionREST Messages, REST Endpoints, SOAP Messages, HTTP connectionsExternal connectivity review, egress inventory, vendor risk
CredentialOAuth Profiles, Client Secrets, Certificates, API Keys, TokensRotation management, expiry monitoring, secret hygiene
ResourceTables, APIs, Repositories, Cloud StorageData classification, access control, sensitivity assessment

These map to five distinct governance programs that every mature security organization runs. Collapsing them into one entity type makes all five programs harder to execute.


1. The CISO's Mental Model

1.1 How CISOs Think About Their Environment

A CISO does not think in terms of "entities." A CISO thinks in terms of governance categories — buckets of things that require distinct management processes, distinct review cadences, and distinct response procedures.

In every security program I have operated or assessed, the governance taxonomy has five categories. These are not SecurityV0 inventions — they are how the security industry organizes its work:

Category 1: "Identities I Need to Govern"

What this is: Anything that CAN AUTHENTICATE to a system and execute actions. The authentication capability is the defining characteristic. If it cannot authenticate, it is not an identity.

What belongs here:

ArtifactWhy it is an identityAuthentication mechanism
Azure Service PrincipalHas an appId, can obtain tokens via client_credentialsOAuth 2.0 client credentials, certificate
ServiceNow Integration User (sys_user)Has a user_name, can authenticate via basic auth, OAuth, SAMLMultiple — session-based or token-based
GitHub AppHas an installation ID, can obtain installation tokensJWT + installation token exchange
AWS IAM RoleHas an ARN, can be assumed via STSSTS AssumeRole, OIDC federation
Machine Account (svc-*)Has credentials (password, key), can authenticate directlyPassword, API key, certificate
OAuth App RegistrationHas a client_id, can obtain tokensOAuth 2.0 grant types

What does NOT belong here:

ArtifactWhy it is NOT an identity
Business RuleCannot authenticate to anything. It is code that fires on a database event. It does not hold credentials. It does not have a user_name. It does not appear in any identity provider.
Script IncludeCannot authenticate. It is a JavaScript library stored in a sys_script_include record. It is called by other code, not by authentication.
REST Message (sys_rest_message)Cannot authenticate. It is a template that DESCRIBES how to call an external API. The template itself does not authenticate — the credential configured on it does.
Flow Designer FlowDebatable — see Section 1.6 below. Flows execute, but they authenticate via the identity configured in their run_as field, not on their own behalf.
Scheduled JobDebatable — similar to Flow Designer. Scheduled Jobs execute on a timer, but they authenticate via their configured run-as identity.

CISO governance process: Identity lifecycle management. Access reviews. Ownership assignment. Credential rotation. Deprovisioning when no longer needed. This process assumes every item in the inventory CAN AUTHENTICATE — because the governance actions (rotate credential, revoke access, disable account) only make sense for things that authenticate.

When Script Includes and REST Message templates appear in my identity inventory, my governance process breaks:

  • "Rotate the credential for Script Include AzureGraphRouter" — it does not have a credential.
  • "Disable the account for REST Message graph.microsoft.com" — it does not have an account.
  • "Review access for Business Rule Auto-route identity tickets" — it does not have its own access; it inherits from whatever identity it runs as.

The test: Can I disable this entity in an identity provider and prevent it from authenticating? If yes, it is an identity. If no, it is not.

Category 2: "Automations I Need to Monitor"

What this is: Code and configuration that EXECUTES LOGIC — transforms data, makes decisions, routes workflows, triggers actions. Automations are the "what happens" layer. They are not identities (they cannot authenticate on their own), but they are execution vehicles that use identities to do their work.

What belongs here:

ArtifactWhy it is an automation componentWhat it does
Business RuleFires on database events (insert, update, delete on a table). Executes JavaScript server-side.Event handler — "when X happens in the database, do Y"
Script IncludeServer-side JavaScript library. Called by Business Rules, Flows, or other Script Includes.Code library — "here is reusable logic that other automations call"
Flow Designer FlowVisual workflow that chains actions together. Has a trigger, a sequence of steps, and outputs.Workflow — "execute this sequence of steps when triggered"
Scheduled Job (sys_trigger)Cron-style execution. Runs on a timer regardless of any triggering event.Timer job — "do this every N hours/days"
MID Server ScriptScript that executes on the MID Server (outside ServiceNow).Remote execution — "run this code on the local network"

CISO governance process: Change detection. Code review (for high-risk automations). Execution monitoring. Blast radius analysis. Trigger review (what activates this automation, and is that trigger appropriate?).

These governance actions are fundamentally different from identity governance. I do not "rotate the credential" of a Business Rule. I review its code, its trigger condition, its execution history, and its blast radius. I ask: "Is this automation still needed? Has its code changed? Is its trigger condition appropriate? What data does it touch?"

Category 3: "Resources I Need to Protect"

What this is: Data stores, APIs, repositories, cloud infrastructure — things that contain or process data that has business value. Resources are the targets of access control. Identities access them; automations operate on them; permissions govern what operations are allowed.

What belongs here:

ArtifactWhy it is a resource
ServiceNow table (incident, hr_case, sys_user)Contains business data. Subject to access control via ACLs. Has sensitivity classification.
API endpoint (graph.microsoft.com/v1.0/users)External data source. Contains identity/directory data. Subject to OAuth scoping.
GitHub repositoryContains code. Subject to branch protection and access control.
AWS S3 bucketContains data objects. Subject to IAM policies and bucket policies.
ServiceNow module or application scopeContains configuration and customization. Subject to scope-based access control.

CISO governance process: Data classification. Sensitivity labeling. Access control review. Data loss prevention. PII tracking. Business domain assignment.

Category 4: "Credentials I Need to Rotate"

What this is: Authentication material — the secrets, certificates, tokens, and keys that enable identities to prove themselves. Credentials have lifecycles (creation, expiry, rotation) and their state is a primary security signal.

What belongs here:

ArtifactWhy it is a credentialLifecycle concern
OAuth Client SecretThe shared secret that an SP presents to obtain tokens.Rotation schedule, expiry date, last used date.
OAuth Profile (sys_auth_profile_oauth)ServiceNow-side configuration that stores the client_id, client_secret, token endpoint. This IS credential material wrapped in configuration.Secret rotation, token refresh, endpoint validity.
X.509 CertificateCertificate used for mutual TLS or certificate-based authentication.Expiry date, CA trust chain, revocation status.
Personal Access TokenLong-lived token scoped to a user or application.Age, scope, last used, creator status.
API KeyStatic key used for API authentication.Rotation schedule, scope, exposure risk.
Federation Trust (OIDC)Trust relationship that allows one system to obtain tokens from another without a shared secret.Trust configuration, claim mapping, scope.

CISO governance process: Secret rotation. Expiry monitoring. Vault hygiene. Credential exposure detection. Emergency rotation procedures. This process is credential-specific — you rotate secrets, you renew certificates, you revoke tokens. You do not "rotate" a Business Rule or "revoke" a Script Include.

The critical distinction — OAuth Profile vs. OAuth App:

The current model classifies both OAuth Profiles (ServiceNow configuration) and OAuth Apps (Entra ID registrations) as identities. They are fundamentally different:

AttributeOAuth App (Entra ID)OAuth Profile (ServiceNow)
Can authenticate?YES — has client_id, can obtain tokensNO — it is a configuration record that stores credentials for USE by an identity
Where does it live?Identity provider (Entra ID)Target system (ServiceNow)
What does it represent?An application registration — a first-class identityA credential configuration — how ServiceNow connects to a token endpoint
CISO governanceIdentity lifecycleCredential rotation
Disable it?Yes — disable the app registration in EntraNo — disabling the profile breaks the connection but does not disable any identity

An OAuth Profile is the ServiceNow-side mirror of a credential. It stores the client_id, client_secret, token endpoint URL, and grant type. It is how ServiceNow knows how to authenticate outbound. It is credential material, not an identity.

Category 5: "Connections to External Systems I Need to Review"

What this is: Configuration that defines HOW a system communicates with another system — the endpoints, protocols, message formats, and integration patterns. Connections are the "plumbing" layer. They are not identities (they cannot authenticate), not credentials (they are not secrets), and not automations (they do not execute logic). They are connection templates.

What belongs here:

ArtifactWhy it is a connectionWhat it defines
REST Message (sys_rest_message)Template for calling an external REST API. Defines URL, method, headers, body template."When something needs to call graph.microsoft.com, here is how"
REST Message Function (sys_rest_message_fn)A specific operation within a REST Message (e.g., GET /users, POST /groups)."Here is the specific API operation to call"
SOAP Message (sys_soap_message)Template for calling an external SOAP service."Here is how to call this WSDL endpoint"
HTTP Connection (sys_connection)Connection configuration with endpoint URL and authentication profile reference."Here is the base URL and auth method for this external system"
Import Set / Data Source (sys_data_source)Configuration for pulling data from an external source."Here is where to get data and how to connect"

CISO governance process: External connectivity review. Vendor risk assessment. Egress inventory. Firewall rule correlation. Third-party dependency tracking. Data flow mapping.

This is where the founder's insight is sharpest. When I review external connections, I want to see every REST Message, every SOAP endpoint, every HTTP connection that reaches outside my perimeter. These are my egress points. They are not identities — but they ARE security-critical configuration that I need to inventory, review, and approve.

If REST Messages are classified as identities, they pollute my identity inventory. If they are not tracked at all, I have no egress inventory. The correct classification — connection — puts them in the right governance bucket with the right review process.

1.2 The Five-Category Taxonomy Mapped to the AzureGraphRouter Chain

Let me walk through the AzureGraphRouter chain and classify each component:

Trigger: incident table INSERT
|
v
Business Rule: "Auto-route identity tickets" → AUTOMATION COMPONENT
| (event handler, not an identity)
v
Script Include: "AzureGraphRouter" → AUTOMATION COMPONENT
| (code library, not an identity)
v
REST Message: "graph.microsoft.com" → CONNECTION
| (external endpoint template, not an identity)
v
OAuth Profile: "AzureAD-GraphAPI-OAuth" → CREDENTIAL
| (client_id + secret config, not an identity)
v
Service Principal: "sn-ticket-router" → IDENTITY
| (CAN authenticate, HAS credentials, IS in Entra ID)
v
Target: incident table (write assignment_group) → RESOURCE

In the current model, FIVE of these six components are classified as entity_type: "identity". Only the incident table is correctly classified as a resource. The OAuth Profile, which is a credential, is an identity. The REST Message, which is a connection template, is an identity. The Business Rule and Script Include, which are code, are identities.

This is like classifying a car's engine, transmission, fuel line, ignition key, and the road it drives on all as "drivers." Only one thing in the car is the driver. Everything else is a different category of thing that the driver uses.

1.3 What the Taxonomy Means for the SecurityV0 Data Model

The current NormalizedNodeType enum has 7 values:

type NormalizedNodeType =
| "autonomous_identity" // SP, OAuth App, machine account, AND BR, SI, Flow, Job, REST Message
| "human_identity" // Human owner
| "role" // Role
| "permission" // Permission
| "resource" // Table, API, repo
| "credential" // OAuth secret, cert, PAT
| "execution_evidence" // Proof of execution

The problem is clear: autonomous_identity is doing the work of three distinct categories. It contains:

  • Actual identities (SP, OAuth App, machine account) that CAN authenticate
  • Automation components (BR, SI, Flow, Scheduled Job) that execute logic
  • Connections (REST Message) that define external communication

And some things that should be in the credential category (OAuth Profiles) are also in autonomous_identity.

The proposed taxonomy would expand NormalizedNodeType:

type NormalizedNodeType =
| "identity" // Things that CAN AUTHENTICATE: SP, OAuth App, machine account, integration user
| "automation_component" // Things that EXECUTE LOGIC: BR, SI, Flow, Scheduled Job
| "connection" // Things that DEFINE EXTERNAL COMMUNICATION: REST Message, SOAP, HTTP Connection
| "credential" // Things that ARE AUTHENTICATION MATERIAL: OAuth Profile, Client Secret, Cert, PAT, API Key
| "resource" // Things that CONTAIN DATA: table, API, repo, cloud storage
| "role" // Named permission grouping
| "permission" // Atomic capability
| "human_identity" // Human owner (unchanged)
| "execution_evidence" // Proof of execution (unchanged)

This gives the CISO five distinct inventories:

  1. Identity inventory — "How many NHIs do I have?" Answer: 3 (SP, integration user, OAuth App). Not 15.
  2. Automation inventory — "How many automations can execute?" Answer: 4 (BR, SI, Flow, Job).
  3. Connection inventory — "How many external connections exist?" Answer: 2 (REST Message, HTTP Connection).
  4. Credential inventory — "How many secrets need rotation?" Answer: 3 (OAuth Profile, client secret, certificate).
  5. Resource inventory — "How many data stores are in the blast radius?" Answer: 4 (incident, hr_case, sys_user, entra_users).

1.4 Why "Identity Subtype" Is Not Sufficient

The current model uses identity_subtype (e.g., business_rule, script_include, flow_designer_flow, rest_message) to distinguish within the identity category. The argument is: "They are all identities, but we can filter by subtype."

This fails for three reasons:

Reason 1: Every query must know the subtypes to filter.

Every API consumer, every UI component, every report, every SCIM export, and every OAA export must maintain a list of "real" identity subtypes vs. "automation component" subtypes vs. "connection" subtypes. If the list changes (e.g., we add a new automation type from a new connector), every consumer must update its filter. This is the same problem Round 3 identified for Option D (virtual entity in entities collection) — "every new feature that queries the entities collection must remember to filter chains."

Reason 2: NHI counts are inflated.

The most important metric a CISO tracks is "How many non-human identities do I have?" If the answer includes Script Includes and REST Messages, it is inflated by 5-10x. An organization with 10 Service Principals and 80 automation artifacts appears to have 90 NHIs. This is false. The organization has 10 NHIs and 80 automation components.

If I report to the board "We have 90 non-human identities accessing sensitive data," and the actual number is 10, I have either:

  • Overstated the risk (if the automation artifacts do not actually have independent access), undermining my credibility.
  • Created a remediation burden 9x larger than necessary (because the governance team must review 90 "identities" instead of 10).

Reason 3: Governance processes cannot be unified.

Identity governance and automation governance are different processes with different inputs, different outputs, and different cadences:

Governance dimensionIdentity governanceAutomation governance
Primary question"Should this identity still have this access?""Is this automation still needed and correctly configured?"
Review inputRoles, permissions, last activity, owner statusCode content, trigger condition, execution history, blast radius
Remediation actionRevoke role, disable account, rotate credentialModify code, change trigger, disable automation, update run-as
Review cadenceQuarterly (per SOC2/ISO)On change + periodic (per CC8.1)
ReviewerIdentity governance teamApplication team + security review

Forcing both processes through a single "identity" category means either:

  • The identity governance team reviews automation artifacts they do not understand, producing rubber-stamp approvals.
  • The automation governance process must filter out "real" identities, duplicating the identity governance team's work.

Neither outcome is acceptable.

1.5 The Subtype Filter Problem in Practice

Consider the API query: "Return all non-human identities that need access review."

Current model (everything is identity):

GET /api/v1/entities?entity_type=identity

Returns: 15 entities including BRs, SIs, REST Messages, OAuth Profiles, Flows, and SPs.

The CISO's response: "I need to review access for 15 identities."

But only 3 of those 15 CAN AUTHENTICATE. The other 12 do not have "access" in the identity governance sense — they are code, configuration, and credential material. Reviewing their "access" is meaningless because they do not have independent access. Their access is derived from the identity they run as.

To get the correct count, the consumer must know to add:

GET /api/v1/entities?entity_type=identity&identity_subtype=service_principal,oauth_app,machine_account,integration_user

This filter must be maintained everywhere. Miss it once, and the NHI count is wrong.

Proposed model (proper entity types):

GET /api/v1/entities?entity_type=identity

Returns: 3 entities (SP, integration user, OAuth App). Correct by default. No filter required.

GET /api/v1/entities?entity_type=automation_component

Returns: 4 entities (BR, SI, Flow, Job). Correct by default.

The taxonomy ensures correctness without requiring consumers to maintain exclusion lists.

1.6 The Borderline Cases: Flows and Scheduled Jobs

Flow Designer Flows and Scheduled Jobs are the hardest to classify because they have properties of both identities and automation components:

PropertyFlow Designer FlowScheduled Job
Can authenticate?Not directly — authenticates via run_as identityNot directly — authenticates via run_as identity
Has its own credentials?No — uses the run_as identity's credentialsNo — uses the run_as identity's credentials
Executes autonomously?Yes — triggered by events, schedules, or API callsYes — triggered by schedule
Has execution evidence?Yes — sys_flow_context recordsYes — sys_trigger records
Has its own roles?No — inherits from run_as identityNo — inherits from run_as identity
Appears in identity provider?NoNo

The CISO's test: Can I disable this entity in an identity provider?

  • Flow: No. I cannot disable a Flow Designer Flow in Entra ID. I can deactivate it in ServiceNow, but that is deactivating an automation, not disabling an identity.
  • Scheduled Job: No. Same reasoning.

Verdict: Automation Components. Flows and Scheduled Jobs are automation components that USE identities to execute. They are not identities themselves. The fact that they execute autonomously makes them important — but importance does not make them identities. A cron job on a Linux server executes autonomously, but nobody classifies it as a "user account."

The execution authority of a Flow or Scheduled Job comes from its RUNS_AS relationship to an identity, not from any authentication capability of its own. The RUNS_AS relationship is the critical link — it says "this automation component borrows this identity's authority when it executes." The identity is what we govern. The automation component is what we monitor.

1.7 Summary: The CISO's Taxonomy

CISO governance questionEntity typeServiceNow artifactsGovernance action
"How many NHIs do I have?"identityService Principals, OAuth Apps, integration users, machine accountsLifecycle management, access review, ownership
"What automations are running?"automation_componentBusiness Rules, Script Includes, Flow Designer Flows, Scheduled JobsExecution monitoring, change detection, code review
"What external connections exist?"connectionREST Messages, SOAP Messages, HTTP Connections, Import SetsEgress review, vendor risk, firewall correlation
"What credentials need rotation?"credentialOAuth Profiles, Client Secrets, Certificates, API Keys, PATsRotation schedule, expiry monitoring, vault hygiene
"What data is at risk?"resourceTables, APIs, repos, cloud storage, modulesClassification, sensitivity labeling, DLP

2. Compliance Impact

2.1 Does Classification Matter for SOC2?

Yes — materially.

SOC2 Trust Service Criteria draw sharp distinctions between identity governance (CC6.1-CC6.3), change management (CC8.1), and system monitoring (CC7.1). These map to different entity types:

SOC2 ControlRelevant Entity TypeWhat the Auditor AsksImpact of Misclassification
CC6.1 (Logical Access)Identity"Show me all non-human identities with access to in-scope systems"If BRs and SIs are identities, the identity inventory is inflated 5-10x. The auditor must manually determine which "identities" are real.
CC6.2 (Access Reviews)Identity"Show evidence of periodic access reviews for all NHIs"If BRs are identities, the access review must cover them. But BRs do not have "access" — they have code. Reviewing BR "access" is meaningless and wastes governance resources.
CC6.3 (Access Revocation)Identity"When an owner departs, how quickly is access revoked?"If a Script Include is an "identity" owned by a departed employee, the access revocation process must "revoke" it. But you cannot "revoke access" for a Script Include — you can only deactivate it. The remediation action is wrong.
CC7.1 (Monitoring)Automation Component"How do you detect unauthorized changes to automated processes?"Automation monitoring is a CC7.1 concern, not a CC6.1 concern. Classifying automations as identities puts them in the wrong control domain.
CC8.1 (Change Management)Automation Component"How are changes to automations authorized, tested, and approved?"Change management for code (BRs, SIs) is fundamentally different from access management for identities (SPs). Merging them into one category confuses which control applies.

The audit impact:

An auditor performing a SOC2 Type II examination will request the NHI inventory. If SecurityV0 reports 90 NHIs when the actual count is 10, one of two things happens:

  1. The auditor accepts the inflated count. The organization must now perform access reviews for 90 "identities," 80 of which are not actually identities. This wastes 8x the governance resources.

  2. The auditor challenges the count. "Why are Business Rules in your identity inventory?" The organization must explain that SecurityV0 classifies automation artifacts as identities. The auditor notes this as a classification weakness and may require the organization to maintain a separate, correctly classified inventory alongside SecurityV0's output.

Neither outcome is desirable. Correct classification avoids both.

2.2 Does Classification Matter for ISO 27001?

Yes — ISO 27001:2022 explicitly separates identity management from change management.

ISO 27001 ControlCategoryEntity Type
A.5.15 (Access Control)Identity"Rules to control physical and logical access to information shall be established and implemented based on business and information security requirements"
A.5.16 (Identity Management)Identity"The full life cycle of identities shall be managed"
A.5.17 (Authentication)Credential"Authentication information shall be controlled by a management process"
A.5.18 (Access Rights)Identity"Access rights to information and other associated assets shall be provisioned, reviewed, revised, and removed"
A.8.9 (Configuration Management)Automation Component, Connection"Configurations, including security configurations, of hardware, software, services, and networks shall be established, documented, implemented, monitored, and reviewed"
A.8.32 (Change Management)Automation Component"Changes to information processing facilities and information systems shall be subject to change management procedures"

ISO 27001 distinguishes between:

  • Identity management (A.5.16) — the lifecycle of things that authenticate.
  • Authentication information (A.5.17) — credential material like passwords, keys, certificates.
  • Configuration management (A.8.9) — the state of software configurations, including automation configurations.
  • Change management (A.8.32) — controlled changes to code, scripts, and automated processes.

These are four distinct control families. SecurityV0's current model collapses all four into a single "identity" bucket. An ISO 27001 auditor would identify this as a control mapping failure — the platform cannot demonstrate which artifacts fall under which control because they are all classified identically.

2.3 Does Classification Matter for SOX ITGC?

Yes — SOX ITGC access management and change management are distinct audit streams.

SOX ITGC has two primary audit streams relevant to automation:

  1. Access Management: "Who has access to financial systems, and is that access authorized?" This applies to IDENTITIES — things that authenticate and execute actions on financial data.

  2. Program Change Management: "What changes were made to automated processes, and were they authorized?" This applies to AUTOMATION COMPONENTS — code and configuration that processes financial data.

When a Business Rule is classified as an identity:

  • The access management audit stream must assess its "access" — but it does not have access in the identity sense.
  • The program change audit stream may not cover it — because it is not classified as a "program" (automation component).

The result is that the Business Rule falls between two audit streams, potentially reviewed by the wrong team using the wrong criteria.

Correct classification ensures:

  • The Service Principal (identity) is reviewed by the access management audit team for appropriate roles and permissions.
  • The Business Rule (automation component) is reviewed by the program change audit team for authorized modifications and appropriate business logic.
  • The OAuth Profile (credential) is reviewed by the access management team for rotation compliance and secret hygiene.

2.4 Identity Count Inflation — The Numbers

Let me quantify the inflation problem using the current Entra-ServiceNow connector data:

Current model (all automation artifacts as identity):

identity_subtypeCountActually an identity?
service_principal2YES
oauth_app1YES
machine_account1YES
integration_user1YES
business_rule12NO — automation component
script_include8NO — automation component
flow_designer_flow45NO — automation component
scheduled_job15NO — automation component
system_execution2Borderline — platform-level identity
rest_message3NO — connection
oauth_profile2NO — credential
Total "identities"925-7 actual identities

NHI count reported to the board: 92. Actual NHI count: 5-7. Inflation factor: 13-18x.

An organization reporting 92 NHIs when it has 5-7 is not providing "evidence-grade, deterministic" output. It is providing a misleading metric that will be challenged by the first auditor who cross-references it against the identity provider.

Proposed model (correct entity types):

Entity typeCountCISO governance action
identity5-7Access review, lifecycle management
automation_component80Execution monitoring, change detection
connection3Egress review, vendor risk
credential2Rotation management
resource~20Data classification
Total entities~110Each type has its own governance

The NHI count is now 5-7 — accurate, defensible, and cross-referenceable with the identity provider.

2.5 Compliance Reporting Clarity

Consider the compliance report a CISO presents to the audit committee:

With current classification:

"SecurityV0 has identified 92 non-human identities across our Entra ID and ServiceNow environment. Of these, 3 have orphaned ownership, 5 show scope drift, and 12 have dormant authority."

Audit committee question: "92 non-human identities? That seems high. Our identity team says we have 7 service accounts."

CISO response: "Well, 85 of those are actually automation configurations, not identities per se. They are Business Rules, Script Includes, and Flow Designer Flows."

Audit committee response: "Then why are they in the identity count?"

With correct classification:

"SecurityV0 has identified 7 non-human identities, 80 automation components, 3 external connections, and 2 credential configurations across our Entra ID and ServiceNow environment. Of the 7 NHIs, 3 have orphaned ownership and 2 show scope drift. Of the 80 automations, 12 have dormant authority and 45 have never executed."

The second report is immediately actionable. The board understands the scope. The numbers are defensible. The governance actions are clear.


3. Forensic Investigation Impact

3.1 The Day 0-91 Breach Scenario Revisited

From Round 3 and Round 4, the scenario:

  • Day 0: AzureGraphRouter chain runs normally.
  • Day 30: Someone adds hr_admin role to SP sn-ticket-router.
  • Day 60: Chain now reads HR cases (PII) via the expanded role.
  • Day 90: Data breach discovered.
  • Day 91: CISO opens SecurityV0.

The CISO's investigation path:

The CISO needs to trace the breach from impact to root cause. The trace follows a chain of different entity types:

1. IMPACT:     hr_case table (RESOURCE) — PII exfiltrated

2. ACCESS: hr_admin role (ROLE) → hr_case.read permission (PERMISSION) → hr_case (RESOURCE)

3. IDENTITY: SP sn-ticket-router (IDENTITY) — holds the hr_admin role

4. CREDENTIAL: OAuth Profile AzureAD-GraphAPI-OAuth (CREDENTIAL) — authenticates the SP

5. CONNECTION: REST Message graph.microsoft.com (CONNECTION) — defines the external endpoint

6. CODE: Script Include AzureGraphRouter (AUTOMATION COMPONENT) — executes the logic

7. TRIGGER: Business Rule Auto-route (AUTOMATION COMPONENT) — fires on incident insert

8. DATA: incident table (RESOURCE) — the triggering event

Each step in this investigation involves a DIFFERENT ENTITY TYPE. The CISO is not tracing through 8 identities — they are tracing through 2 resources, 1 identity, 1 credential, 1 connection, 2 automation components, 1 role, and 1 permission.

3.2 How Correct Typing Clarifies the Investigation

With current classification (all identity):

The investigation graph shows 8 "identities" connected by various edges. The CISO must mentally classify each node to understand the trace:

identity (BR) → identity (SI) → identity (REST) → identity (OAuth) → identity (SP) → role → permission → resource

The first five nodes are all "identities." The CISO asks: "Which of these identities was compromised?" The answer: "Only one is actually an identity — the SP. The rest are code, config, and credentials." But the graph does not make this distinction visible. The CISO must know the subtypes to interpret the graph.

With correct classification:

automation_component (BR) → automation_component (SI) → connection (REST) → credential (OAuth) → identity (SP) → role → permission → resource

Now the investigation path is self-documenting:

  • The trigger is an automation component (Business Rule fires on event).
  • The logic is an automation component (Script Include processes the data).
  • The connection is a connection template (REST Message defines the external endpoint).
  • The credential is authentication material (OAuth Profile provides the client secret).
  • The identity is the entity that authenticated (SP sn-ticket-router).

The CISO can immediately see:

  • The point of authentication (where the SP authenticates).
  • The point of code execution (where the SI runs logic).
  • The point of external communication (where the REST Message defines the endpoint).
  • The credential chain (how the OAuth Profile enables authentication).

Each entity type implies a different forensic question:

  • For the identity: "Who changed its roles? When? Was it authorized?"
  • For the automation component: "Was its code modified? When was it last changed? By whom?"
  • For the connection: "Was the endpoint URL changed? Does it still point to the legitimate destination?"
  • For the credential: "When was the secret last rotated? Is it compromised? Has it been used from unexpected IPs?"

3.3 The "What Was Compromised?" Question

In any breach investigation, the CISO must determine WHAT was compromised. The answer depends on entity type:

If compromised...Entity typeWhat it meansImmediate action
The SP's credentials were stolenIdentityAttacker can authenticate as the SP from anywhereRotate credentials, disable SP, check sign-in logs
The BR's code was modifiedAutomation ComponentAttacker injected malicious logic into the event handlerRevert code change, review sys_audit for the BR record, check who modified it
The REST Message URL was changedConnectionAutomation is sending data to an attacker-controlled endpointRevert URL, check all requests made to the modified URL, review connection audit trail
The OAuth Profile's secret was exposedCredentialAttacker can obtain tokens using the same client_id/secretRotate the secret in Entra ID AND the OAuth Profile in ServiceNow, check token issuance logs

Each entity type implies a different attack vector, a different investigation path, and a different remediation action. Classifying them all as "identity" obscures these distinctions.

3.4 The Investigation Timeline Reconstruction

At Day 91, the CISO needs to reconstruct what happened over 90 days. With correct typing, the timeline is organized by entity type:

Identity events (what changed about who can authenticate):

  • Day 0: SP sn-ticket-router has roles [itil, task_assign]. Owner: Sarah Chen (active).
  • Day 30: SP sn-ticket-router gains role hr_admin. Added by bob.chen@corp.com.
  • Day 60: No identity changes — but access scope expanded because hr_admin grants hr_case.read.

Automation events (what changed about what code runs):

  • Day 0: BR Auto-route unchanged. SI AzureGraphRouter unchanged.
  • Day 0-90: No code changes detected. The automation logic was not modified.

Connection events (what changed about where data flows):

  • Day 0: REST Message points to graph.microsoft.com.
  • Day 0-90: No connection changes. The endpoint URL was not modified.

Credential events (what changed about authentication material):

  • Day 0: OAuth Profile has client_secret issued 2025-06-15, expires 2026-06-15.
  • Day 0-90: No credential rotation. Secret is 8 months old.

This per-type timeline immediately reveals that the breach resulted from an identity change (role addition), not from a code change, connection change, or credential compromise. The investigation focuses on Day 30 — who added hr_admin, why, and whether it was authorized.

With the current classification (all identity), this timeline is a flat list of "identity events" where the role addition is mixed with code audits and credential checks. The CISO cannot quickly determine which category of change caused the breach.


4. Risk Assessment Impact

4.1 "How Many Non-Human Identities Do I Have?"

This is the single most important question a CISO asks about their NHI posture. The answer drives:

  • Board reporting ("We have X NHIs, Y% are governed, Z% have orphaned ownership").
  • Audit scope ("The NHI inventory for this examination period includes X identities").
  • Remediation planning ("We need to review X identities this quarter").
  • Benchmarking ("Industry average is Y NHIs per 1000 employees; we have X").

If the answer includes automation artifacts, it is wrong.

The CIS Benchmark for Non-Human Identity Management (hypothetical but representative of emerging standards) would define NHI as "any identity that can authenticate to a system without human interaction at the point of authentication." Script Includes cannot authenticate. Business Rules cannot authenticate. REST Messages cannot authenticate. They are not NHIs.

Including them in the NHI count:

  • Inflates the metric by 13-18x (based on current data).
  • Makes benchmarking against industry averages meaningless.
  • Creates a remediation backlog 13-18x larger than necessary.
  • Undermines the credibility of the platform's output when cross-referenced with the identity provider.

4.2 "Which Credentials Have Access to Sensitive Data?"

This question asks about CREDENTIAL risk — which secrets, if compromised, would grant access to sensitive data.

Current model: Credentials are a separate entity type, which is correct. But OAuth Profiles (which ARE credential material) are classified as identities. This means the credential inventory is incomplete — it misses the ServiceNow-side credential configurations.

Impact:

  • "How many credentials need rotation?" — undercounted by the OAuth Profiles classified as identities.
  • "Which credentials access HR data?" — must search both the credential inventory AND the identity inventory to find OAuth Profiles.
  • "When was the last credential rotation for the AzureGraphRouter chain?" — requires querying the identity collection for the OAuth Profile, not the credential collection.

With correct classification: OAuth Profiles are credentials. The credential inventory is complete. The rotation report covers all credential material without requiring cross-collection queries.

4.3 "What Automations Can Reach External Systems?"

This question asks about EGRESS risk — which automations have the capability to send data outside the organization.

Current model: REST Messages (connection templates to external systems) are classified as identities. To find external connections, the CISO must:

  1. Query identities with identity_subtype: rest_message.
  2. From each REST Message identity, examine the endpoint URL to determine if it is external.
  3. Cross-reference with automation components (BRs, SIs) that reference this REST Message.

With correct classification (connection entity type):

  1. Query connections directly: GET /api/v1/entities?entity_type=connection.
  2. All external endpoints are immediately visible.
  3. Cross-reference with automations via the USES or CALLS relationship.

The egress inventory becomes a first-class query rather than a filtered subquery of the identity inventory.

4.4 "What Is the Blast Radius of This Automation?"

Blast radius analysis requires traversing from an automation through its identity binding to its reachable resources:

Automation Component (BR/Flow) -[RUNS_AS]-> Identity (SP) -[HAS_ROLE]-> Role -[GRANTS]-> Permission -[APPLIES_TO]-> Resource

With correct classification, the blast radius path is typed:

StepEntity typeWhat it reveals
Startautomation_componentWhat code executes
RUNS_ASidentityWhat identity it borrows
HAS_ROLEroleWhat roles the identity holds
GRANTSpermissionWhat operations are allowed
APPLIES_TOresourceWhat data is reachable

The CISO reads this as: "This automation runs as SP X, which holds roles Y and Z, granting read/write on tables A, B, and C." Each step is a different entity type, and the entity type tells the CISO what governance action applies at that step.

With current classification, the blast radius path is:

StepEntity typeWhat it reveals
Startidentity (subtype: business_rule)??? — is this an identity or code?
RUNS_ASidentity (subtype: service_principal)This is the actual identity
HAS_ROLEroleRoles
GRANTSpermissionPermissions
APPLIES_TOresourceResources

The first two steps are both "identity." The CISO must inspect the subtype to understand that the first is code and the second is an authenticating entity. The graph structure is ambiguous at the type level.

4.5 Risk Prioritization Impact

When the CISO prioritizes remediation, they prioritize by risk category:

PriorityRisk categoryWhy it is urgent
1Orphaned identity with active credentialsCan authenticate with no oversight
2Credential nearing expiry on active integrationService disruption if not rotated
3Automation with code change and external egressPotential code injection / exfiltration
4Connection to deprecated/compromised endpointData flowing to unintended destination
5Resource with sensitivity reclassificationAccess controls may no longer be appropriate

Each priority maps to a DIFFERENT entity type. With correct classification, the CISO can sort findings by entity type and address each risk category systematically. With current classification, all findings are on "identities," and the CISO must decode the subtype to determine which risk category applies.


5. Proposed Security Taxonomy

5.1 Entity Type Definitions

identity

Definition: An autonomous entity that CAN AUTHENTICATE to a system and execute actions. The authentication capability is the defining characteristic.

Discriminating test: Can this entity obtain a session, token, or authenticated connection to a system? Does it appear in an identity provider?

Subtypes (identity_subtype):

SubtypeExampleAuthentication method
service_principalEntra ID SP, AWS IAM RoleOAuth, OIDC, certificate, role assumption
oauth_appEntra ID App RegistrationOAuth 2.0 grant types
machine_accountServiceNow svc-* userPassword, API key
integration_userServiceNow integration userBasic auth, OAuth, SAML
system_executionServiceNow "System" identityPlatform-level, no explicit credentials
github_appGitHub App InstallationJWT + installation token
pat_identityIdentity behind a PATPersonal access token

Properties preserved: execution_mode, security_relevance, status, last_activity_at, source_system. All current identity properties remain — the change is about which artifacts carry them.

Relationships: OWNED_BY, HAS_ROLE, AUTHENTICATES_VIA, AUTHENTICATES_TO, EXECUTES_ON. These relationships make sense for identities. An identity HAS roles. An identity AUTHENTICATES via a credential. An identity AUTHENTICATES TO another identity. These are identity-specific verbs.

automation_component

Definition: Code or configuration that EXECUTES LOGIC when triggered. Automation components are the "what happens" layer. They do not authenticate on their own — they use identities (via RUNS_AS) to execute.

Discriminating test: Does this entity execute code or workflow logic? Does it have a trigger condition? Does it operate via a borrowed identity (RUNS_AS)?

Subtypes (component_subtype):

SubtypeExampleTrigger mechanism
business_ruleServiceNow BR on incident tableDatabase event (insert, update, delete)
script_includeServiceNow SI called by BR or FlowFunction call (no independent trigger)
flow_designer_flowServiceNow Flow Designer FlowEvent, schedule, API, or manual trigger
scheduled_jobServiceNow sys_trigger / cron jobSchedule (time-based)
mid_server_scriptMID Server discovery scriptMID Server scheduler
workflowServiceNow legacy WorkflowDatabase event, schedule, manual

Properties specific to automation_component:

PropertyTypePurpose
trigger_typeenumWhat activates this component (event, schedule, api_call, manual, function_call)
trigger_conditionstringSpecific trigger (e.g., "incident INSERT", "daily 03:00 UTC")
execution_modeenumautonomous, operator_assisted, human_triggered, unknown
execution_count_30dnumberHow many times it executed recently
has_external_egressbooleanWhether it can reach external systems
code_hashstringSHA256 of the automation's code (change detection)
last_code_change_atdatetimeWhen the code was last modified
last_code_change_bystringWho modified the code

Relationships:

RelationshipFrom → ToMeaning
RUNS_ASautomation_component → identity"This automation executes as this identity"
TRIGGERS_ONautomation_component → resource"This automation is triggered by this resource/event"
CALLSautomation_component → automation_component"This component invokes this other component"
CALLSautomation_component → connection"This component uses this connection template"
OWNED_BYautomation_component → human_identity"This person/team is accountable for this automation"
CREATED_BYautomation_component → human_identity"This person created this automation"

Note on RUNS_AS: This is the critical relationship that connects automation components to the identity graph. The blast radius of an automation component is determined by traversing RUNS_AS to its identity, then following the identity's HAS_ROLE → GRANTS → APPLIES_TO path. The automation component does not have its own roles or permissions — it inherits them from the identity it runs as.

connection

Definition: Configuration that defines HOW a system communicates with another system — the endpoint, protocol, message format, and integration pattern. Connections are templates, not executors.

Discriminating test: Does this entity define an external communication endpoint? Does it specify a URL, protocol, or message format? Is it a template that other entities use to communicate?

Subtypes (connection_subtype):

SubtypeExampleProtocol
rest_messageServiceNow sys_rest_messageHTTP/HTTPS REST
rest_endpointServiceNow sys_rest_message_fnHTTP/HTTPS REST (specific operation)
soap_messageServiceNow sys_soap_messageSOAP/XML
http_connectionServiceNow sys_connectionHTTP/HTTPS (generic)
data_sourceServiceNow sys_data_sourceVarious (JDBC, LDAP, REST, file)

Properties specific to connection:

PropertyTypePurpose
endpoint_urlstringWhere this connection points
protocolenumrest, soap, http, jdbc, ldap
is_externalbooleanWhether the endpoint is outside the organization
destination_systemstringWhat system the endpoint belongs to (e.g., "graph.microsoft.com" → "entra_id")
auth_profile_refstringReference to the credential used for authentication
tls_requiredbooleanWhether the connection requires TLS

Relationships:

RelationshipFrom → ToMeaning
AUTHENTICATES_VIAconnection → credential"This connection uses this credential to authenticate"
CONNECTS_TOconnection → resource"This connection reaches this external resource"
USED_BYconnection ← automation_component"This automation uses this connection" (inverse of CALLS)

Why this matters for the CISO: The connection inventory is the egress inventory. Every connection entity is a potential data exfiltration path. By making connections a first-class entity type, the CISO can query "show me all external connections" without filtering through the identity inventory. This is the vendor risk and third-party dependency view.

credential (already exists, needs expansion)

The current model already has a credential entity type. The change is to ensure OAuth Profiles are classified here, not as identities.

What moves from identity to credential:

ArtifactCurrent classificationProposed classificationRationale
OAuth Profile (sys_auth_profile_oauth)identitycredentialStores client_id + client_secret — this IS credential material
OAuth Entity Token (oauth_entity_token)Not currently modeledcredentialActive token instance

Everything else in credential remains unchanged: Client Secrets, Certificates, PATs, API Keys, Federation Trusts.

resource (already exists, no changes needed)

Tables, APIs, repositories, cloud storage. Already correctly classified in the current model.

5.2 The Complete Entity Graph with Correct Types

                              ┌──────────────────┐
│ human_identity │
│ (Owner: Sarah) │
└────────┬──────────┘
│ OWNED_BY
┌─────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────────┐ ┌──────────────────┐
│automation_compo-│ │ identity │ │ credential │
│nent │ │ (SP: sn-ticket- │ │ (OAuth Profile: │
│(BR: Auto-route) │ │ router) │ │ AzureAD-Graph) │
└────────┬────────┘ └──────────┬───────────┘ └────────┬─────────┘
│ │ │
CALLS HAS_ROLE AUTHENTICATES_VIA
│ │ │
▼ ▼ │
┌─────────────────┐ ┌─────────────────┐ │
│automation_compo-│ │ role │ │
│nent │ │ (hr_admin) │ │
│(SI: AzureGraph- │ └────────┬────────┘ │
│ Router) │ │ │
└────────┬────────┘ GRANTS │
│ │ │
CALLS ▼ │
│ ┌──────────────┐ │
▼ │ permission │ │
┌─────────────────┐ │ (hr_case.read)│ │
│ connection │ └───────┬──────┘ │
│ (REST Message: │ │ │
│ graph.ms.com) │ APPLIES_TO │
└────────┬────────┘ │ │
│ ▼ │
AUTHENTICATES_VIA ┌──────────────┐ │
│ │ resource │ │
└──────────▶ │ (hr_case tbl) │ │
└──────────────┘ │

┌──────────────────────────────────────────────────────┘
│ identity AUTHENTICATES_VIA credential

SP sn-ticket-router authenticates using OAuth Profile AzureAD-Graph

Each entity type is visually distinct. Each implies a different governance action:

  • automation_component nodes: Review code, check trigger, monitor execution.
  • identity nodes: Review access, check ownership, rotate credentials.
  • connection nodes: Review endpoint, check vendor status, verify TLS.
  • credential nodes: Check expiry, rotation schedule, compromise indicators.
  • resource nodes: Check classification, sensitivity, access controls.
  • role/permission nodes: Check appropriateness, scope, privilege level.

5.3 How This Affects the NormalizedGraph

The NormalizedNodeType enum changes:

// BEFORE (current)
type NormalizedNodeType =
| "autonomous_identity" // Everything that executes
| "human_identity"
| "role"
| "permission"
| "resource"
| "credential"
| "execution_evidence";

// AFTER (proposed)
type NormalizedNodeType =
| "identity" // Things that CAN AUTHENTICATE
| "automation_component" // Things that EXECUTE LOGIC
| "connection" // Things that DEFINE EXTERNAL COMMUNICATION
| "human_identity" // Human owners (unchanged)
| "role" // Role groupings (unchanged)
| "permission" // Atomic capabilities (unchanged)
| "resource" // Data stores (unchanged)
| "credential" // Auth material (unchanged, but expanded)
| "execution_evidence" // Proof of execution (unchanged)

Net change: autonomous_identity is split into identity, automation_component, and connection. Everything else is unchanged.

5.4 Granularity Assessment — Is This the Right Level?

The proposed taxonomy has 9 node types. Is this too many? Too few?

Too many? Only if distinct governance actions do not exist for each type. But they do:

  • Identity → lifecycle management, access review
  • Automation Component → code review, execution monitoring, change detection
  • Connection → egress review, vendor risk
  • Credential → rotation, expiry monitoring
  • Resource → classification, sensitivity, DLP
  • Role → privilege review, appropriateness
  • Permission → scope audit
  • Human Identity → ownership tracking
  • Execution Evidence → forensic record

Each type has a distinct governance process. None can be collapsed without losing governance clarity.

Too few? Potentially — within the automation_component type, Business Rules (event-driven code) and Script Includes (callable libraries) have different risk profiles. A BR fires on its own; a SI is called by others. But this distinction is captured by the component_subtype discriminator, not by separate node types. The node type level captures the governance category; the subtype captures the technical variation within that category.

The right granularity is: node types map to governance categories, subtypes map to technical variations. Five governance categories (identity, automation, connection, credential, resource) plus four supporting types (role, permission, human_identity, execution_evidence) = 9 node types. This is the minimum set that gives the CISO distinct views for distinct governance processes.


6. Artifact-by-Artifact Classification

6.1 Business Rule

DimensionAssessment
Can authenticate?No. A BR does not hold credentials. It does not have a user_name. It does not appear in any identity provider.
Does it execute?Yes. BRs execute JavaScript server-side when their trigger condition is met (table insert, update, delete).
Does it define a connection?No. A BR may CALL a REST Message, but it does not define the connection itself.
Is it credential material?No.
Is it a data store?No.
Classification:automation_component (subtype: business_rule)
CISO governance:Code review, trigger review, change detection, execution monitoring

Key relationships:

  • RUNS_AS → identity (the BR executes as the configured run-as user or "system")
  • TRIGGERS_ON → resource (the table whose events activate the BR)
  • CALLS → automation_component (Script Includes it invokes)
  • CALLS → connection (REST Messages it uses)
  • CREATED_BY → human_identity (sys_created_by)
  • OWNED_BY → human_identity (accountability)

6.2 Script Include

DimensionAssessment
Can authenticate?No. A Script Include is a JavaScript class/function stored in sys_script_include. It cannot authenticate to anything.
Does it execute?Yes — but only when called by another component (BR, Flow, another SI). It has no independent trigger.
Does it define a connection?No. It may contain code that constructs HTTP requests, but the connection configuration (URL, auth) is typically in a REST Message.
Is it credential material?No. (If it hardcodes credentials in its code, that is a security finding, not a classification.)
Is it a data store?No.
Classification:automation_component (subtype: script_include)
CISO governance:Code review (especially for external HTTP calls, GlideRecord queries on sensitive tables), change detection

Special note: Script Includes are the most "library-like" of all automation artifacts. They have NO independent trigger — they only execute when called. This makes them the weakest candidate for "identity" classification. A JavaScript library is not an identity by any definition.

Key relationships:

  • CALLED_BY ← automation_component (BRs, Flows, other SIs that invoke it)
  • CALLS → connection (REST Messages it uses)
  • CALLS → automation_component (other SIs it invokes)
  • CREATED_BY → human_identity

6.3 REST Message

DimensionAssessment
Can authenticate?No. A REST Message is a template (sys_rest_message). It defines a URL, HTTP method, and headers. It does not authenticate — the OAuth Profile or basic auth credential configured on it does.
Does it execute?No. It is a configuration template that is USED by automations.
Does it define a connection?YES. This is exactly what it does — it defines how to communicate with an external system.
Is it credential material?No. It REFERENCES credential material (via auth profile), but it is not the credential itself.
Is it a data store?No.
Classification:connection (subtype: rest_message)
CISO governance:Egress review, endpoint verification, vendor risk assessment, TLS enforcement

Why this matters: REST Messages are the CISO's egress inventory. Every REST Message that points to an external URL is a potential data exfiltration path. Making them a connection entity type means the CISO can query "show me all connections to external systems" and get a complete list without filtering through the identity inventory.

Key relationships:

  • AUTHENTICATES_VIA → credential (the OAuth Profile or auth config used for the connection)
  • CONNECTS_TO → resource (the external API endpoint as a resource)
  • USED_BY ← automation_component (BRs, SIs that call this REST Message)

6.4 OAuth Profile

DimensionAssessment
Can authenticate?No — the OAuth Profile STORES credentials (client_id, client_secret). It is not an identity — it is the credential configuration that an identity uses. The identity is the Service Principal in Entra ID; the OAuth Profile is ServiceNow's local configuration for using that SP's credentials.
Does it execute?No.
Does it define a connection?Partially — it defines the token endpoint URL. But primarily, it stores the credential material.
Is it credential material?YES. It contains client_id, client_secret (or reference), token_endpoint_url, and grant_type. This is authentication material.
Is it a data store?No.
Classification:credential (subtype: oauth_profile)
CISO governance:Secret rotation, expiry monitoring, grant type review, scope review

The critical insight: The OAuth Profile is the ServiceNow-side mirror of the Entra ID credential. The AUTHENTICATES_TO relationship (SP → integration user) is enabled by TWO credential entities:

  1. The Entra-side client secret (credential, already correctly classified)
  2. The ServiceNow-side OAuth Profile (currently misclassified as identity, should be credential)

Both are credential material. Both need rotation governance. Both should appear in the credential inventory.

Key relationships:

  • AUTHENTICATES_VIA ← identity (the SP uses this credential)
  • AUTHENTICATES_VIA ← connection (REST Messages use this credential for auth)
  • PROVES → identity (this credential proves identity X to system Y)

6.5 Flow Designer Flow

DimensionAssessment
Can authenticate?Not independently. Flows execute as the identity configured in their run_as field. The Flow itself does not hold credentials and does not appear in any identity provider.
Does it execute?Yes — Flows execute autonomously on triggers (events, schedules, API calls). They have execution evidence (sys_flow_context).
Does it define a connection?No. Flows may use Actions that call REST Messages, but the Flow itself is an orchestration layer.
Is it credential material?No.
Is it a data store?No.
Classification:automation_component (subtype: flow_designer_flow)
CISO governance:Execution monitoring, trigger review, action review, change detection, run-as review

The strongest argument for keeping Flows as identity: Flows have execution evidence, trigger types, and can be individually activated/deactivated. They "behave like" identities in that they execute autonomously.

The counter-argument (which I find more compelling): Execution is not authentication. A cron job executes autonomously, but it is not a user account. A Jenkins pipeline executes autonomously, but it is not an identity — it runs as a service account (the identity) that has credentials. The pipeline is the automation; the service account is the identity.

Flows BORROW identity through RUNS_AS. They do not HAVE identity. This distinction matters for governance: the access review is on the identity (the run-as user), not on the Flow. The code review is on the Flow, not on the identity.

6.6 Scheduled Job

DimensionAssessment
Can authenticate?Not independently. Scheduled Jobs run as a configured identity or "system."
Does it execute?Yes — on a timer/schedule. Has execution evidence (sys_trigger).
Does it define a connection?No.
Is it credential material?No.
Is it a data store?No.
Classification:automation_component (subtype: scheduled_job)
CISO governance:Schedule review, execution monitoring, change detection, run-as review

Identical reasoning to Flow Designer Flows. Scheduled Jobs are automation components that borrow identity through their run-as configuration.

6.7 Classification Summary Table

ArtifactCurrent typeProposed typeProposed subtypeRationale
Service Principalautonomous_identityidentityservice_principalCAN authenticate
OAuth App Registrationautonomous_identityidentityoauth_appCAN authenticate
Machine Account (svc-*)autonomous_identityidentitymachine_accountCAN authenticate
Integration Userautonomous_identityidentityintegration_userCAN authenticate
System Execution identityautonomous_identityidentitysystem_executionPlatform-level authenticator
Business Ruleautonomous_identityautomation_componentbusiness_ruleExecutes code, CANNOT authenticate
Script Includeautonomous_identityautomation_componentscript_includeCode library, CANNOT authenticate
Flow Designer Flowautonomous_identityautomation_componentflow_designer_flowWorkflow, authenticates via RUNS_AS
Scheduled Jobautonomous_identityautomation_componentscheduled_jobTimer job, authenticates via RUNS_AS
REST Messageautonomous_identityconnectionrest_messageConnection template, CANNOT authenticate
OAuth Profileautonomous_identitycredentialoauth_profileStores client_id + secret = credential material
Tables, APIsresourceresource(various)Unchanged
Client Secrets, Certscredentialcredential(various)Unchanged
Rolesrolerole(various)Unchanged
Permissionspermissionpermission(various)Unchanged

7. Impact on Execution Chain Modeling

7.1 Compatibility with Round 3/4 execution_chains

The proposed taxonomy is fully compatible with the execution_chains collection recommended in Rounds 3 and 4. A chain is a composite entity that includes members of MULTIPLE entity types:

{
_id: "chain-azuregraphrouter-001",
chain_name: "AzureGraphRouter — Incident Routing",
member_entities: [
{ entity_id: "uuid-br", entity_type: "automation_component", subtype: "business_rule", role_in_chain: "trigger" },
{ entity_id: "uuid-si", entity_type: "automation_component", subtype: "script_include", role_in_chain: "executor" },
{ entity_id: "uuid-rest", entity_type: "connection", subtype: "rest_message", role_in_chain: "external_endpoint" },
{ entity_id: "uuid-oauth", entity_type: "credential", subtype: "oauth_profile", role_in_chain: "auth" },
{ entity_id: "uuid-sp", entity_type: "identity", subtype: "service_principal", role_in_chain: "authenticating_identity" }
]
}

The chain's members are now typed, which provides two benefits:

  1. The chain's blast radius is derived from its identity members. Only identity type members have HAS_ROLE → GRANTS → APPLIES_TO paths. Automation components, connections, and credentials do not have independent access. This simplifies blast radius computation — follow RUNS_AS from automation_component to identity, then traverse the identity's execution path.

  2. The chain's risk profile is multi-dimensional. A chain with a modified automation_component is a code change risk. A chain with a connection pointing to a new endpoint is an egress risk. A chain with an expired credential is a service disruption risk. A chain with an orphaned identity is an access governance risk. Correct typing enables these distinct risk assessments.

7.2 Impact on the OAA Export

Round 4 recommended exporting chains as OAA Applications. The typed taxonomy improves this export:

{
"name": "AzureGraphRouter — Incident Routing",
"application_type": "automation_chain",

// Only IDENTITY type members become OAA local_users
"local_users": [
{ "name": "sn-ticket-router", "user_type": "service_principal" }
],

// RESOURCE type members + resources reachable via identity's permissions
"resources": [
{ "name": "incident_table", "resource_type": "table" },
{ "name": "entra_users", "resource_type": "api_endpoint" }
],

// CONNECTION type members become custom properties on the Application
"custom_properties": {
"sv0_external_connections": [
{ "name": "graph.microsoft.com", "protocol": "rest", "is_external": true }
],
// AUTOMATION_COMPONENT type members become custom properties
"sv0_automation_components": [
{ "name": "Auto-route identity tickets", "subtype": "business_rule", "trigger": "incident INSERT" },
{ "name": "AzureGraphRouter", "subtype": "script_include" }
],
// CREDENTIAL type members become custom properties
"sv0_credentials": [
{ "name": "AzureAD-GraphAPI-OAuth", "subtype": "oauth_profile", "expires_at": "2026-06-15" }
]
}
}

The OAA export is cleaner because:

  • Only actual identities become local_users (correct in OAA semantics).
  • Automation components, connections, and credentials are custom properties (correctly extended).
  • The Application's permission bindings (identity_to_permissions) only reference real identities, not code or config.

7.3 Impact on Chain-Level Findings

Chain-level findings from Round 3 become richer with typed members:

FindingCurrent (untyped)Proposed (typed)
chain_blast_radius_expanded"Chain gained access to hr_case""Identity sn-ticket-router gained role hr_admin; chain blast radius expanded to include hr_case (confidential)"
chain_ownership_degraded"3 of 5 chain members have orphaned ownership""Identity sn-ticket-router (the authenticating entity) has orphaned ownership; 2 automation components also orphaned"
chain_code_modifiedN/A (cannot distinguish code from config)"Automation component AzureGraphRouter (script_include) was modified on 2026-02-10 by admin@corp.com"
chain_connection_changedN/A"Connection graph.microsoft.com endpoint URL was modified from graph.microsoft.com/v1.0 to graph.microsoft.com/beta"
chain_credential_expiringN/A"Credential AzureAD-GraphAPI-OAuth expires in 14 days; chain will lose external connectivity"

Correct typing enables finding types that are impossible with the current model. Code modification findings require knowing which chain members are code. Connection change findings require knowing which members are connections. Credential expiry findings require knowing which members are credentials.


8. Addressing Potential Objections

8.1 "This Breaks the Execution Path Traversal"

Objection: The current execution path traversal follows: Identity → HAS_ROLE → Role → GRANTS → Permission → APPLIES_TO → Resource. If Business Rules are not identities, they cannot participate in this path.

Response: Business Rules should NOT participate in the HAS_ROLE path. They do not have their own roles. Their authority comes from the identity they run as. The execution path for an automation is:

automation_component -[RUNS_AS]-> identity -[HAS_ROLE]-> role -[GRANTS]-> permission -[APPLIES_TO]-> resource

The RUNS_AS edge is the bridge between the automation world and the identity world. This is already how the path materializer works — it follows RUNS_AS edges to "borrow" the target identity's execution paths. Correct typing makes this traversal explicit rather than implicit.

8.2 "This Adds Complexity to the Data Model"

Objection: Going from 1 entity type (autonomous_identity) to 3 types (identity, automation_component, connection) plus expanding credential adds complexity.

Response: It adds 2 node types to the NormalizedNodeType enum. But it REMOVES complexity from every consumer:

  • No more subtype exclusion lists.
  • No more "is this a real identity?" checks.
  • No more NHI count inflation.
  • No more mixed governance processes.

The complexity moves from every consumer (N consumers, each maintaining subtype filters) to one place (the type system). This is a net reduction in system-wide complexity.

8.3 "Automation Components Still Need Identity-Like Properties"

Objection: Automation components need execution_mode, security_relevance, status, last_activity_at — properties that are currently on identity. If they are not identities, they lose these properties.

Response: These properties are not identity-specific. They are properties of anything that CAN EXECUTE:

  • execution_mode — how the component triggers (autonomous, scheduled, manual).
  • security_relevance — the security tier (active_external, dormant_authority, internal_inventory).
  • status — active, disabled, deleted.
  • last_activity_at — when the component last executed.

These properties belong on the automation_component entity type. They describe the automation's execution characteristics, not its authentication characteristics. Moving them to automation_component is semantically more correct — execution_mode describes how code executes, not how an identity authenticates.

8.4 "Connectors Would Need to Know the Correct Type"

Objection: Connectors currently emit everything as autonomous_identity. Changing the type system requires connector changes.

Response: Yes. The connector's transformer must classify artifacts into the correct entity type. But the classification logic is straightforward:

def classify_node_type(artifact):
if artifact.can_authenticate: # SP, OAuth App, machine account
return "identity"
elif artifact.is_code or artifact.has_trigger: # BR, SI, Flow, Job
return "automation_component"
elif artifact.defines_endpoint: # REST Message, SOAP Message
return "connection"
elif artifact.stores_credentials: # OAuth Profile
return "credential"
else:
return "resource"

The decision tree has 4 branches. Each branch tests a single property of the source system artifact. This is simpler than the current approach of classifying everything as identity and then using subtypes to distinguish.

8.5 "This Might Break the Execution Chain Derivation"

Objection: The chain derivation algorithm in Round 3 starts from identity entities with trigger automation subtypes. If BRs are not identities, the algorithm must change.

Response: The algorithm changes minimally. Instead of:

Start from identity entities WHERE identity_subtype IN (business_rule, scheduled_job, flow_designer_flow)

It becomes:

Start from automation_component entities WHERE component_subtype IN (business_rule, scheduled_job, flow_designer_flow)

The traversal logic is identical. The starting collection changes from entities WHERE entity_type = autonomous_identity AND subtype IN (...) to entities WHERE entity_type = automation_component AND subtype IN (...). This is a query filter change, not an algorithm change.


9. What This Means for the CISO's Daily Workflow

9.1 Morning Dashboard

Current model (everything is identity):

Dashboard: Non-Human Identities
Total: 92 NHIs
With orphaned ownership: 15
With scope drift: 8
Dormant: 45
Active: 47

[The CISO sees 92 items and knows most are not identities]

Proposed model (correct types):

Dashboard: Security Posture

Identities: 7 NHIs
Orphaned: 3 | Scope drift: 2 | Active: 5 | Dormant: 2

Automations: 80 components
Active executing: 12 | Dormant: 45 | Disabled: 23
External egress: 3 | Sensitive data: 8

Connections: 3 external
Active: 2 | Unused: 1
Destinations: graph.microsoft.com, api.openai.com, vault.corp.com

Credentials: 5 active
Expiring <30d: 1 | Not rotated >180d: 2

Resources: 20 in blast radius
Confidential: 4 | Contains PII: 2

The second dashboard gives the CISO five actionable sections, each with governance-specific metrics. The first dashboard gives one inflated number with no governance clarity.

9.2 Access Review Campaign

Current model: "Review access for 92 NHIs this quarter."

  • 85 of 92 are not identities and cannot have their "access" meaningfully reviewed.
  • Reviewers rubber-stamp automation artifacts because they do not understand the governance action.
  • Actual identity access (7 SPs/accounts) may get lost in the noise.

Proposed model: "Review access for 7 NHIs this quarter. Review automation configuration for 12 high-priority components."

  • Identity access review focuses on 7 actual identities — their roles, permissions, and ownership.
  • Automation review focuses on code, triggers, and execution patterns — appropriate governance for code.
  • No rubber-stamping. No wasted effort. Each review is meaningful for its entity type.

9.3 Incident Response

Current model: "Identity Business Rule Auto-route was involved in the breach."

  • "Identity?" — the IR team asks which account was compromised.
  • "Business Rule Auto-route" — that is code, not an account. What account did it run as?
  • Confusion. Misdirection. Lost time.

Proposed model: "Automation component Business Rule Auto-route was involved in the breach. It runs as identity SP sn-ticket-router."

  • The IR team immediately knows: the code (BR) executed using the credentials of an identity (SP).
  • They focus credential rotation on the SP.
  • They review the BR's code for modifications.
  • They check the REST Message's endpoint URL for tampering.
  • Each entity type suggests a different forensic action. No confusion.

10. Recommendations

10.1 Primary Recommendation: Implement the Five-Category Taxonomy

Split autonomous_identity into three entity types:

  • identity — things that CAN AUTHENTICATE
  • automation_component — things that EXECUTE LOGIC
  • connection — things that DEFINE EXTERNAL COMMUNICATION

Expand credential to include OAuth Profiles.

Keep resource, role, permission, human_identity, and execution_evidence unchanged.

10.2 Implementation Priority

ChangePriorityEffort estimateImpact
Add automation_component to NormalizedNodeTypeP04h (type + schema)Separates code from identities
Add connection to NormalizedNodeTypeP04h (type + schema)Separates connection config from identities
Reclassify OAuth Profiles as credentialP12h (connector change)Complete credential inventory
Update connector transformer to emit correct typesP18h (classification logic)Source-of-truth correction
Update platform ingestion to accept new typesP14h (validation + storage)Platform compatibility
Update API filters to type-based queriesP14h (query changes)Correct default views
Update UI to show type-specific viewsP216h (dashboard + entity pages)CISO-ready presentation
Update execution chain derivation to start from automation_componentP12h (query filter change)Chain compatibility
Update OAA export to map types correctlyP28h (export layer)Correct OAA output

Total P0+P1 effort: ~28 hours. This is a one-time cost that permanently fixes the entity classification.

10.3 What This Does NOT Change

  • execution_chains — the Round 3/4 recommendation stands. Chains are composites of multiple entity types.
  • Relationships — RUNS_AS, TRIGGERS_ON, CALLS, AUTHENTICATES_TO all remain. The edges are the same; the node types are corrected.
  • Findings — all five current finding types work on identity entities. New finding types (chain-level) work on chains. Automation-specific findings (code_modified, trigger_changed) work on automation_component.
  • Execution evidence — links to the entity that executed, whether identity or automation_component. A Flow's execution evidence links to the Flow (automation_component); a SP's sign-in evidence links to the SP (identity).
  • Temporal tracking — entity_versions, baselines, and events work for all entity types, not just identities.

10.4 The Decisive Test

Ask the CISO these five questions about the current model. If any answer causes confusion, the model is wrong:

  1. "How many NHIs do you have?" — Current answer: 92. Correct answer: 5-7. CONFUSION.
  2. "Which NHIs have orphaned ownership?" — Current answer includes BRs and SIs. A BR cannot have its "access revoked" like an identity. CONFUSION.
  3. "What credentials need rotation?" — Current answer misses OAuth Profiles (classified as identities). INCOMPLETE.
  4. "What external connections exist?" — Must filter identity inventory by subtype to find REST Messages. REQUIRES WORKAROUND.
  5. "What automations are running?" — Must filter identity inventory by multiple subtypes. REQUIRES WORKAROUND.

With the proposed taxonomy, all five questions are direct queries on the correct entity type. No filtering. No workarounds. No confusion.


11. Dissenting Considerations

11.1 "The Industry Uses 'NHI' Broadly"

Counterargument: Some industry definitions of Non-Human Identity include automation artifacts. Gartner's emerging NHI framework includes "service accounts, bots, automations, and API keys."

Response: Even broad NHI definitions distinguish between the identity (the account or principal) and the automation (the code or workflow that uses it). Gartner's framework lists "automations" as things that HAVE NHIs, not things that ARE NHIs. A GitHub Actions workflow has a GITHUB_TOKEN (an NHI); the workflow itself is the automation that uses it.

The distinction is: NHIs are the authentication principals. Automations are the code that uses those principals. Both need governance, but they need DIFFERENT governance.

11.2 "Subtypes Were Working Fine"

Counterargument: The subtype system (identity_subtype: business_rule, script_include, etc.) provides sufficient discrimination. API consumers can filter by subtype.

Response: Subtypes work for API consumers who know the subtypes to filter. They fail for:

  • Aggregate metrics (NHI count) where the filter is not applied.
  • New consumers who do not know the convention.
  • SCIM/OAA exports that must be configured to exclude non-identity subtypes.
  • Board-level reporting where subtypes are too technical.
  • Cross-references with identity providers that list actual identities.

The subtype approach is opt-in filtering (consumers must remember to filter). The entity type approach is correct-by-default (the type system enforces the distinction).

11.3 "This Is a Migration with Real Cost"

Counterargument: Changing entity types requires updates to the connector, platform, API, UI, and all consumers. The migration risk is not zero.

Response: The prompt explicitly says "Do NOT consider migration cost. Focus on what gives the CISO the clearest, most actionable view." From a pure security governance perspective, the correct types are essential. The migration cost is real but is a one-time investment that permanently fixes the model.


12. Summary Position

The founder is right. Classifying all automation artifacts as identities is semantically wrong, and the consequences are operational, not academic.

When I open SecurityV0 as a CISO, I need five views:

  1. Identities — things that authenticate. Show me SPs, OAuth Apps, machine accounts. Not code.
  2. Automations — things that execute. Show me BRs, Flows, Scheduled Jobs. Not credentials.
  3. Connections — things that point outside. Show me REST Messages, HTTP connections. Not identities.
  4. Credentials — things that need rotation. Show me OAuth Profiles, secrets, certificates. Not workflows.
  5. Resources — things that hold data. Show me tables, APIs, repos. Not business rules.

These five views map to five governance programs that every mature security organization runs. Collapsing them into one "identity" view makes all five programs harder to execute, inflates NHI counts by 13-18x, confuses forensic investigations, and complicates compliance reporting.

The proposed taxonomy — identity, automation_component, connection, credential, resource (plus the existing role, permission, human_identity, execution_evidence) — gives the CISO the clearest, most actionable view of their environment. Each entity type implies a distinct governance action. Each type maps to specific compliance controls. Each type supports different forensic questions.

Build the types. Classify correctly. Govern distinctly.


This analysis was prepared from the CISO perspective for the SecurityV0 automation-analysis team, Round 5. It addresses the specific question "What entity type should Business Rules, Script Includes, REST Messages, OAuth Profiles, Flow Designer Flows, and Scheduled Jobs actually be?" and concludes that the current "everything is identity" model is operationally harmful. The proposed five-category taxonomy (identity, automation_component, connection, credential, resource) provides the governance clarity, compliance accuracy, and forensic precision that a CISO requires.