- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thursday
Hi there!
I have a flow where I'm having the error "The requested flow operation was prohibited by security rules." in an Update Record action when I try to execute it with a user that doesn't have write permission in the table. As I wrote in the subject, the flow is running as System User. I have a similar issue in a Send Email action: Access denied to create new email.
It looks my flow isn't running with System User even it should. Any ideas?
P.S.: I've already checked this KB: https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0861124
Thank you!
Solved! Go to Solution.
- Labels:
-
Flow Designer
-
System User
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Friday
Hi there!
Thank you for all your answer. I just solved it creating a copy of the flow (already with flag run as "System User"). I deactivate the original and used the copy. Everything worked fine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Friday
Can you check the link I shared as it explains the same resolution of creating a copy of the flow and disable original flow to fix the issue.
As per community guidelines, you can accept more than one answer as accepted solution. If my response helped to answer your query, please mark it helpful & accept the solution.
Thanks,
Bhuvan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Friday
ServiceNow – Now Assist Reporting: Access to sys_generative_ai_log, skill-level counting, KPIs & risks
Context
You’re building custom reporting/PA on Now Assist using:
- sys_gen_ai_usage_log (high-level usage/billing)
- sys_generative_ai_log (granular events/steps)
You’re seeing “Security restricted access … rows removed by Security constraints” on sys_generative_ai_log and want to:
1) Know what access is required and how to grant it safely.
2) Confirm if the table lets you count skills/use cases per ticket.
3) Get KPI ideas and understand risks.
------------------------------------------------------------
1) Access to sys_generative_ai_log (why blocked & how to enable)
------------------------------------------------------------
Why you see “Security constraints”:
- That message is raised by row-level “Security Constraints” / Contextual Security rules or restrictive ACLs on the table. Now Assist logs can contain prompts/responses and are intentionally locked down.
How to find the exact requirement in *your* instance:
A. Check ACLs
- System Security → Access Control (ACL)
- Filter Name = sys_generative_ai_log, Type = record, Operation = read
- Inspect “Requires role” and the Script. Also check table.* and parent table ACLs.
- If a role is required (e.g., a specific Now Assist/GenAI admin/viewer role), assign/bundle that role to your reporting role.
- If there’s a script that denies unless a property/role is present, follow its guidance or clone/extend via a separate read ACL that narrows access (e.g., to a specific group).
B. Check “Security constraints” (Contextual Security / Row-level)
- Look for “Security Constraints” modules (if Contextual Security – Advanced is installed).
- Review constraint rules for sys_generative_ai_log that remove rows at list time.
- If present, create a targeted allow rule for a specific group/role (e.g., reporting_analytics), scoping to non-sensitive rows or to time ranges. Avoid blanket allow-all.
C. glide.ui.permitted_tables is not sufficient
- That property only bypasses list-view UI restrictions. It won’t override ACLs or Security Constraints on sys_generative_ai_log.
D. Safer alternative (recommended for analytics)
- Build a read-only **reporting view** or a scheduled **extraction job** that copies a reduced set of columns (e.g., created_on, document, capability/skill, outcome, duration, user, table, record) into a custom log table (u_gen_ai_event_fact).
- Grant report_on/read to that fact table (not the raw log). Mask or drop prompt/response text to avoid PII/exposure.
------------------------------------------------------------
2) Can sys_generative_ai_log support “skills per ticket”?
------------------------------------------------------------
Yes—in most deployments, sys_generative_ai_log holds granular events, such as capability/skill executed (e.g., summarize, suggest_resolution, draft_comment), the target record (table + sys_id), timestamp, actor, and outcome.
Common fields/patterns you may leverage:
- table/document/document_sys_id (target)
- capability/skill/type (the feature invoked)
- user/session/channel (who/how)
- created_on / duration / status (timing & results)
Approach to compute “skills per ticket”:
- Join sys_generative_ai_log to tickets via (table, document/document_sys_id).
- For each ticket (e.g., incident), do COUNT DISTINCT(capability) to get the number of unique use cases executed on that ticket.
- For “average number of use cases per ticket,” aggregate: AVG( distinct_capabilities_per_ticket ).
If you cannot query the table due to constraints, populate u_gen_ai_event_fact nightly with just (ticket, capability, timestamp) and report from there.
------------------------------------------------------------
3) KPI ideas (Adoption, Value, Quality) and PA notes
------------------------------------------------------------
Adoption KPIs
- % Tickets with ≥1 AI use case
- % Agents who used AI this week (DAU/WAU)
- Use case mix: share of summarize / suggest_resolution / draft_comment
Value/Outcome KPIs
- Avg use cases per AI-enabled ticket
- % AI-enabled tickets resolved within SLA vs non-AI tickets
- MTTR delta for AI-enabled vs control group
- Deflection rate (cases resolved without escalation after AI)
- Time saved proxy: sum(duration_saved_estimate) if available, or benchmark-based proxy per skill
Quality/Experience KPIs
- % “Accepted” suggestions vs total suggestions
- Feedback score (thumbs up/down) per skill, per group
- Re-open rate for AI-enabled tickets vs baseline
- Hallucination/flag rate (if tracked)
- Supervisor review adjustments after AI draft usage
Operational KPIs
- Top agents by effective AI usage (accepted ratio, SLA compliance)
- Skills effectiveness by assignment group / domain
- Error/timeout rate per capability and per channel (workspace, portal)
Performance Analytics model
- Indicator sources: use u_gen_ai_event_fact (or sys_* logs if permitted) filtered by table=incident/request/etc.
- Automated Indicators:
- Daily count of tickets with ≥1 AI event
- Daily count of AI events per capability
- Distinct capability count per ticket (rollup to avg)
- Breakdowns: Assignment group, Agent, Capability, Channel, Priority, Category
- Targets/Thresholds: set adoption and quality thresholds per release wave
------------------------------------------------------------
4) Data risks & governance
------------------------------------------------------------
Security/Privacy
- Prompts and responses may include PII or sensitive business context.
- Do NOT grant blanket read access to sys_generative_ai_log.
- Prefer a curated fact table with minimized columns (drop prompt/response text; keep only IDs/metrics).
- Use Data Classification tags and field-level ACLs for any residual text fields.
- Consider column encryption or the Vault if you must keep text.
Performance
- Logs can be high-volume; large ad-hoc queries will be expensive.
- Index by (table, document/document_sys_id, created_on, capability) on analytics table.
- Feed PA from scheduled extracts (daily), not direct live queries on raw logs.
- Implement data retention/archival policies for the raw log table(s).
Auditability
- Maintain a data lineage: source → transformation → analytics fact, with a dictionary entry documenting fields and any masking logic.
------------------------------------------------------------
Actionable checklist
------------------------------------------------------------
[ ] Review ACLs on sys_generative_ai_log (record and table.*) and required roles
[ ] Check for row-level Security Constraints and add a specific allow for your reporting role/group
[ ] If access remains sensitive, build a scheduled extract to u_gen_ai_event_fact with safe columns
[ ] Create PA indicator sources from the fact table; define Adoption, Value, Quality indicators
[ ] Add indexes and retention on the fact table; avoid querying raw logs for dashboards
[ ] Document governance: who can access raw logs, for how long, and why
TL;DR
- Access: blocked by ACL/Contextual Security. Identify required role and/or add a targeted constraint allow; permitted_tables won’t override.
- Skills per ticket: the granular log typically has capability-level events—use it (or a safe extract) to compute distinct skills per ticket and related KPIs.
- Governance: avoid broad read to the raw log; extract only safe fields to a dedicated analytics table and drive PA from there.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Friday
ServiceNow – Flow Designer says “Run as System User” but Update/Email fail with security errors
Symptom
- Update Record action → “The requested flow operation was prohibited by security rules.”
- Send Email action → “Access denied to create new email.”
- Flow property is set to Run As = System User.
Why this happens
1) Enforce security on the step
Many data actions have an **Advanced → Enforce security** toggle. If enabled, the step evaluates **user ACLs** (the triggering user), even when the Flow property is “Run as System User.” Result: write/insert is blocked.
2) Cross‑scope protection
If the Flow (scope A) updates a table owned by scope B, and scope B’s table **Application Access** does not grant “Can create/update from other application scopes,” the platform blocks it with “prohibited by security rules,” even for System User.
3) Domain separation
System User runs in a given **domain context**. If your record is in another domain and the engine/user domain doesn’t have access, the update is denied.
4) Table‑level protections (sys_email, restricted tables)
Some tables (e.g., **sys_email**) are protected by ACLs and cross‑scope restrictions. “Send Email” creates a sys_email record; with “Enforce security” on (or cross‑scope denied), you’ll see Access denied.
5) Action/subflow overrides
Subflows or specific actions can **override Run As** (e.g., spokes/actions that run “as current”). One secured action in a chain can throw the error.
What to check & how to fix (ordered)
1) Step-level security
- Open the failing **Update Record** (and **Send Email**) step → Advanced.
- **Uncheck “Enforce security.”** Re‑test.
- If this is a Subflow, open the subflow step configuration as well.
2) Cross‑scope application access
- Identify the target table’s **Application scope** (dictionary record).
- In the table definition (in owning app), set **Application access**:
• “Accessible from: All application scopes”
• Check **Can read / Can create / Can update** as needed
- Alternatively, move the Flow into the **same application scope** as the target table.
3) Domain context
- If domain separation is enabled, confirm the Flow Context runs in the correct domain:
• Flow property “Run in the same domain as the trigger” (if available in your release) or
• Add a “Set Flow Context” / domain change step before the update (or run the flow from a BR/event within the correct domain).
- Test with a record in the **same domain** as the executing Flow.
4) Email specifics
- Prefer **Notification → Trigger Event** + OOB Notification, or **Notification → Send Notification** action, rather than writing sys_email yourself.
- If you must use **Send Email (core)**, open step Advanced and **disable Enforce security**.
- Ensure **glide.email.active = true** and SMTP settings are valid in sub‑prod/prod.
- Cross‑scope: sys_email is in Global; your scoped app needs create permission via application access or turn the step to run in a scope that’s allowed.
5) Subflows & spokes
- Open each subflow and action used by the failing step; verify they **don’t override Run As** or have Enforce security toggled on.
- Some spokes run as a **Connection user** (e.g., IntegrationHub). Those do not inherit System User and may require permissions on the remote system, not the instance.
6) Last-resort patterns
- Wrap the change in a **Script step** (server) with a GlideRecord update, executed when the Flow Context is confirmed to be in the right scope/domain.
- Use a lightweight **Business Rule** or **Script Action** (runs as system) triggered by an Event your Flow fires.
Quick diagnostic checklist
- Reproduce in a tiny Flow with just: Trigger → Update Record (same table) → Enforce security OFF.
- From **System Logs → All**, filter by **Source = Flow Engine** and check the exact security message.
- Verify the table’s Application Access and your Flow’s application scope.
- If domain separated, check **current domain** in the execution log (set a temporary Script step: gs.info(gs.getCurrentDomainID())).
- Confirm there’s no Data Policy blocking the insert/update.
Template fixes you can apply now
- Update Record step → Advanced → **uncheck Enforce security**.
- Move Flow to the **owning scope** of the target table (Application picker at top).
- For email, swap to **Trigger Event** + Notification or **Send Notification** (Notification action), not direct sys_email insert.
Summary
- “Run as System User” applies to the **Flow context**, but step‑level **Enforce security**, **cross‑scope**, and **domain** protections still apply.
- Disable Enforce security where appropriate, align application scope, and ensure domain context is correct. For emails, use Notification actions or event‑driven notifications.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Friday
ServiceNow Flow Designer – “The requested flow operation was prohibited by security rules.”
===========================================================================================
Problem
-------
A Flow with **Run As = System user** fails for certain steps:
- **Update Record** → “The requested flow operation was prohibited by security rules.”
- **Send Email** → “Access denied to create new email.”
When the same Flow is executed by a user without write permissions, it appears the Flow does **not** actually run in system context.
Why this happens
----------------
In Flow Designer, **Run As** is influenced by several layers. Even if the Flow is set to run as **System user**, a step may still enforce ACLs or other security rules due to:
1) **Per‑step security enforcement**
Some core actions (Update, Create, Delete, Look Up, Email) honor a platform property or action‑level setting to **enforce security**. If enforced, the step evaluates ACLs/roles of the **effective user** (which might not be 'system' depending on inheritance).
2) **Run‑as inheritance across Subflows & Actions**
A **Subflow** or **Action** can override the parent Flow’s context:
- Subflow property **“Run As”** may be set to **Caller** instead of **Flow**/**System**.
- Spoke Actions often run **as session user** by default (especially connectors).
3) **Application scope & Protected APIs**
If the Flow or Action resides in a **scoped app with “Enforce Security”**, the engine can still check ACLs even under System. Some tables also have special constraints (scripted ACLs, read‑only states, domain rules).
4) **Domain separation**
With domains enabled, a System context still respects domain visibility. If the target record lives in a different domain (and the Flow runs with a user/domain context that lacks visibility), the Update fails.
5) **Email creation constraints**
The **Send Email** action (writes to `sys_email`) can be restricted by ACLs/props. If a step enforces ACLs and the effective user lacks rights, “Access denied to create new email” is thrown.
How to fix – Checklist
----------------------
A. Confirm run context
1. Open the Flow → **Flow properties** → **Run As: System user** (not “User who triggered”).
2. If calling **Subflows**, open each Subflow:
- Set **Run As** to **System user** or **Use flow caller** (verify which is desired). Prefer **System user** for privileged updates.
3. For **Actions** (custom or spoke), check the **Action properties**:
- Ensure it doesn’t force **“Enforce security”** unless strictly needed.
- If it does, switch to a Script step (see E) for privileged writes.
B. Per‑step security behavior
- In the **Update Record** step, expand **Advanced** and look for any **“Enforce access controls / security”** toggle. Turn it **off** if your governance allows and you truly want system‑level bypass.
- If no toggle exists, replace with a **Script** step (E) to run in true system context.
C. Domain separation
- Confirm the record’s **Domain** vs the Flow’s effective domain.
- If needed, in a Script step: `gs.getSession().setDomainID('<target_domain_sys_id>');` (use with caution).
- Or trigger/run the Flow from a record within the same domain.
- Check properties affecting domain ACLs and whether the **System user** has cross‑domain visibility.
D. Email specifics
- Prefer **Notifications** (sys_notification) and fire them via **Events** (`gs.eventQueue`) instead of raw **Send Email** action when security is tight.
- If you must use **Send Email**, run the action from a **Subflow with Run As = System user**, or replace with a **Script** step that inserts into `sys_email` in system context.
- Verify no ACLs on `sys_email` (or related tables) block creation.
E. Use a Script step (reliable system context)
If governance allows, replace the failing actions with a **Script** step in the same Flow (still Run As System):
```javascript
(function execute(inputs, outputs) {
// Example: update a record with true system context (bypasses ACLs)
var gr = new GlideRecord('target_table');
if (gr.get(inputs.sys_id)) {
gr.setValue('some_field', inputs.new_value);
gr.update(); // uses GlideRecord (not GlideRecordSecure) in system context
}
// Example: queue a notification event instead of Send Email
// gs.eventQueue('my.notification.event', gr, 'parm1', 'parm2');
})(inputs, outputs);
```
Notes:
- In Flow script steps, **GlideRecord** runs as the Flow’s **Run As** principal (System if configured).
- If your organization requires ACL enforcement even in scripts, use **GlideRecordSecure** and ensure the security context has the right roles.
F. Subflow/action inheritance rules
- Ensure **every** layer (Flow → Subflow → Action) has the intended **Run As**. A Subflow set to **Caller** will execute under the **triggering user**, not System.
- Some Spoke steps (e.g., connectors) honor their own **Connection & Credential** and **Use session user** options—configure appropriately.
G. Platform properties to review (names may vary by release)
- Flow Engine security enforcement (global): whether actions enforce ACLs regardless of Run As.
- Email sending restrictions: properties that restrict non‑system inserts into `sys_email`.
- Domain enforcement: ensure the System principal can see/write to the target domain.
H. Prove the context (diagnostics)
- Add a **Script** step before the failing action:
```javascript
(function execute(inputs, outputs) {
gs.info('FLOW DEBUG - user=' + gs.getUserName() + ', role_admin=' + gs.hasRole('admin'));
outputs.ctx_user = gs.getUserName();
})(inputs, outputs);
```
- If you see a non‑system principal, fix Run As inheritance.
Recommended patterns
--------------------
1) **Privileged updates:** Use **Script steps** under **Run As = System user**.
2) **Email:** Prefer **Events + Notifications**; use **Send Email** only if needed and running under a confirmed System context.
3) **Subflows:** Standardize **Run As = System user** for all reusable privileged Subflows.
4) **Least privilege:** If business requires ACL enforcement, keep **Enforce security** ON and grant a **technical role** only to the Flow engine’s context.
Summary
-------
Your error indicates that a step in the Flow is still enforcing ACLs under a non‑system effective user or a restricted domain. Make sure **Run As** is correctly inherited across **Flow/Subflow/Action**, disable per‑step security enforcement (or switch to a **Script step**), and prefer **Events + Notifications** for email. Validate by logging `gs.getUserName()` in a Script step before the failing action.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Friday
Hi there!
Thank you for all your answer. I just solved it creating a copy of the flow (already with flag run as "System User"). I deactivate the original and used the copy. Everything worked fine.
