How to Resolve the “Cross‑Scope Access Policy: Security Restriction” Issue in ServiceNow
- nathanlee142
- Mar 19
- 11 min read
Updated: Mar 30

ServiceNow’s application scoping is a powerful security mechanism that isolates applications and their data. However, if you’re a ServiceNow developer or admin, you might encounter the error “Cross-scope access policy: Security restriction” when trying to have one application interact with another. This article will explain why this error occurs and how to fix it. We’ll discuss the purpose of cross-scope access policies, why these security restrictions are in place, and walk through solutions step by step. By the end, you’ll know how to configure your ServiceNow instance to allow safe cross-application interactions while maintaining security. This conversational yet technical guide is geared to ServiceNow users looking to resolve cross-scope access issues and understand the underlying principles.
What Does the “Cross‑Scope Access Policy: Security Restriction” Error Mean?
In ServiceNow, each application (especially custom scoped apps) runs in its own scope – a separate namespace – to prevent unintended interference with other apps. The error message “cross-scope access policy: security restriction” indicates that code from one application scope attempted to access a resource (like a table or script) in another scope, but was blocked by ServiceNow’s security rules. In other words, the platform refused the action because it violated the target application’s cross-scope access settings. This is an application-to-application security mechanism, independent of user roles. Even if you are an administrator, a scoped app cannot bypass another app’s restrictions unless explicitly permitted.
When this error occurs, your script or integration will not complete the desired action. For example, if a business rule in a scoped app tries to create a record in a global table without proper access, ServiceNow will throw a security restriction error and prevent the insert. These restrictions are in place for good reason: they ensure one application can’t inadvertently modify another application’s data or code unless allowed, preserving stability and data integrity across the platform. However, as a developer you often do need cross-application interactions – so how can we enable them safely?
Common Causes of Cross-Scope Access Errors
Understanding why the error occurs is the first step to resolving it. Common causes include:
Application Scope Restrictions: The target resource (table, Script Include, etc.) is set to only be accessible within its own scope. If the resource’s definition specifies it is for “This application scope only,” other scopes will be blocked by default.
Missing Cross-Scope Privileges: ServiceNow uses Cross-Scope Privilege records (also known as Application Cross-Scope Access records) to manage exceptions to scope rules. If your app tries to call into another app and no privilege record exists (or it’s not set to Allowed), the call might be denied.
Runtime Access Tracking Settings: Each application in ServiceNow has a Runtime Access Tracking level (None, Tracking, or Enforcing) that determines how strictly cross-scope calls are controlled. In Enforcing mode, cross-scope calls require explicit approval; if not authorized, the system will log a security restriction and block the operation.
User Roles and Permissions: Although the cross-scope error is not directly caused by user roles, it’s important to ensure the user or integration account performing the action has the proper roles. After you solve the scope issue, a lack of the correct role (e.g., trying to write to a table without the required role) could still prevent access. Roles and ACLs won’t throw a “cross-scope” error message, but they might cause a similar failure scenario (just without the specific error text). Thus it’s wise to double-check that both scope access and user permissions are in order.
Now that we know the possible reasons, let’s go through how to fix the issue step by step.
Step-by-Step Solutions
Check the Application Access settings of the target resource – Start by inspecting the table or script include that your code is trying to access. Open the definition of that object (for a table, find it in System Definition > Tables, and for a Script Include, open it in System Definition > Script Includes). Locate the Application Access section or tab:
Ensure the Accessible from field is set to “All application scopes.” If it is set to “This application scope only,” no other app can access it. Changing it to All scopes permits external applications to interact with it.
Verify the specific operation permissions: for tables, you’ll see checkboxes like Can read, Can create, Can update, Can delete. Enable the actions that your scoped app needs. For example, if your app needs to insert records into that table, make sure Can create is checked. These settings define what other scopes are allowed to do on this table. If any required operation is unchecked, cross-scope attempts for that action will be refused.
(Note: You might need the security_admin role to modify these settings, as they are security-related.)
Add explicit Cross-Scope Privileges if needed – When your app (source scope) calls a resource in another scope (target), ServiceNow can create a Cross-Scope Privilege record to track and manage this access. This record lives in the Application Cross-Scope Access list (you can find it under System Applications > Application Cross-Scope Access, or by searching for “Cross-Scope Privileges”). If runtime access tracking is enabled, an entry may already exist for the attempted operation:
Find the privilege record corresponding to your source and target. For example, it might say Source = YourAppScope, Target = Global (or another app scope), with details like the table name or script name and the operation (read, write, execute).
Check the Status of that privilege. If it’s “Requested” or “Blocked/Refused,” you will need to change it to Allowed to permit the operation. Typically, when Runtime Access Tracking is in Enforcing mode, the first time you run the code it will create a privilege record in a Requested state and stop the execution. You then go in and set it to Allowed and re-run your code.
If no record exists, you can manually create one. Click New and fill in the Source Scope (your application), Target Scope (the application containing the resource, e.g. global), Target Type (Table, Script, etc.), the specific Target Name (e.g. the table name), and the Operation (such as “read” or “write” for a table, or “execute” for a script include). Set the Status to Allowed. This whitelists that particular cross-scope interaction.
Save the record and test your functionality again. With the privilege in place, ServiceNow should allow the cross-scope call provided the target’s Application Access settings (from step 1) also permit it. It’s important to note that cross-scope privilege records work in tandem with the resource’s own settings – you need both in alignment for success.
Understand and adjust Runtime Access Tracking – Every custom application has a runtime access tracking level that influences cross-scope behavior:
Enforcing: The strictest setting. Cross-scope access requires explicit authorization. When a script in your app tries to access another app’s resource, the platform automatically creates a privilege record in “Requested” status and blocks the operation until an admin approves it. Use this in development to catch unauthorized access and explicitly allow what’s needed.
Tracking: A middle-ground setting. The system will log cross-scope access attempts by creating privilege records, but it will also allow the operation to proceed (assuming the target’s Application Access allows it). Essentially, it tracks what would require privileges without breaking your functionality. This can be useful during development to see what cross-scope calls are happening and then pre-authorize them before moving to a stricter mode.
None: No tracking or special enforcement. In this mode, ServiceNow does not create cross-scope privilege records at all, and any cross-scope call is allowed as long as the basic table/script access settings permit it. This is the least restrictive mode (closer to how global applications behaved in older versions), but it sacrifices the safety net of tracking unauthorized access.
To check or change your application’s setting, open your application record (in Studio, this is under Application Settings, or in the normal interface, find your app in System Applications > Applications). Look for the Runtime Access Tracking field. During development, you might set this to Tracking to avoid interruptions, or Enforcing to test the approval process. In a published application, Enforcing ensures that any new cross-scope calls are caught.
The key is to use these settings appropriately: for troubleshooting in a dev instance, you might temporarily relax to “Tracking” or even “None” (if you control all sides) to confirm the operation can work. But ultimately, for a secure configuration, define the needed cross-scope privileges and then use Enforcing to lock it down so that unexpected cross-scope calls won’t slip by unnoticed.
Ensure proper user roles and permissions – After configuring the above, double-check that the user or integration account performing the action has the necessary roles on the target application’s data. Cross-scope policies are about application boundaries, not user access, but if your script runs as a user without the right permissions, it could fail silently or throw a different error. For example, if you are inserting into the Incident table from a scoped app, your user will still need the itil role (or whatever is required by that table’s ACLs) in addition to the cross-scope access being allowed. Make sure to test with an appropriately privileged account. If you adjust roles, test the operation again to see if it succeeds. Remember, you might get no more cross-scope error message, but the operation could still be blocked by an ACL if roles are missing. Verifying both aspects (scope access and user access) covers all bases.
Practical Examples and Use Cases
It helps to see where this issue commonly arises. Here are a few scenarios ServiceNow developers often run into the cross-scope access policy:
Scoped App Writing to a Global Table: Suppose you built a custom scoped app that needs to create or update records in a global table (for instance, creating a Catalog Item or a variable set in the global scope). By default, many global tables are restricted. In our example, a business rule in a scoped app attempted to create a Variable Set record in a global table and hit the “refused due to cross-scope access policy” error. The solution was to go to that table’s definition (in this case item_option_new_set table for variable sets) and enable cross-scope access by checking Allow access for create operations on that table. Once the table allowed access from other scopes, the error was resolved and the scoped app could create records successfully. Always identify which table or resource is being blocked and adjust its Application Access if possible.
Calling Script Includes Across Scopes: You might have a utility Script Include in one application (say in the global scope or another plugin scope) that you want to use from your scoped app. If you call it directly, ServiceNow could block it unless that Script Include is set to allow access. For example, if you call an HR Core Script Include from a custom app, you may find nothing happens and see a ScopeAccessNotGrantedException in logs. The fix is to edit that Script Include: set Accessible from: All application scopes, and decide on the Caller Access level (None, Tracking, or Restriction) as needed. If set to Caller Restriction, the first call will be denied and logged in the Restricted Caller Access table, where an admin must mark it Allowed. If set to Caller Tracking, the call will be allowed and automatically recorded as Allowed. In either case, once the Script Include’s settings are open and any necessary cross-scope privilege record is Allowed, your scoped app can successfully call the script. This use case often appears when using out-of-box APIs from other ServiceNow applications (like HR or Customer Service) in your own app.
Integrations and APIs: Cross-scope issues aren’t limited to internal scripts. If you have a scoped app providing an API (Scripted REST, for instance) that another app or global code is calling (or vice versa), similar access rules apply. You may need to allow one scope to call another’s Scripted REST resource. The process is analogous: adjust the resource’s scope settings and possibly authorize the privilege. A common example is a custom app trying to read or write to a table in a ServiceNow Store app – you might not be allowed to change the Store app’s settings, so you’d instead create a privilege record to permit your scope to perform the needed operation on the Store app’s table (if the Store app’s design allows it).
Alternative Workarounds
In some situations, you might not be able or willing to modify the cross-scope access settings (for example, if the target is a ServiceNow Store application or a locked plugin where you cannot change its tables’ access settings). Here are a few workarounds to consider:
Use an intermediary (Facade Script): Create a script (such as a Script Include) in a scope that both sides can work with (often the global scope) as a bridge. For instance, if your scoped app cannot directly delete a record on a global table, create a global Script Include that has a function to perform the deletion (and ensure this Script Include’s Application Access allows all scopes to execute it). Then, from your scoped app’s business rule or script, call this global function. This way, the cross-scope call occurs on the Script Include (which you can allow via a cross-scope privilege for the “execute” operation), and the actual deletion happens in global where it’s permitted. This technique essentially proxies the operation through a scope that has access, and is a common pattern to avoid opening up an entire table’s direct access.
Leverage Restricted Caller Access approvals: If you cannot alter the target app’s settings to All scopes, see if the target resource has a Caller Access = Caller Restriction setting. In that case, your attempt will generate a Restricted Caller Access request (visible in System Applications > Application Restricted Caller Access). A system admin in the target scope (or global) can go to that list and mark the request as Allowed, granting your calling application permission. Once approved, the platform will allow future calls from your app to that resource. This is effectively another way to add a cross-scope privilege via the UI approval mechanism.
Enable “Track in Update Sets” on the target table: A less obvious trick that has helped in some cases (as reported by the community) is to mark the target table to Track in Update Sets. In one scenario, a global table was refusing cross-scope writes even after all the usual settings were open. The issue was resolved by editing the table definition and checking the Track in Update Sets option. This setting is normally about capturing changes for updates, but for certain global tables, not having it checked can sometimes cause unusual behavior with scoped writes. If you’re still stuck, it’s worth a try – just be cautious and ensure you understand the implications (it means any schema changes to that table will be tracked in update sets).
Re-evaluate design approach: If none of the above are feasible, you may need to reconsider how the two scopes interact. Could the target application offer an API or integration point? For example, instead of directly inserting into the other app’s table, perhaps use a Scripted REST API or Import Set API of that app, which might be designed for external input. Or, schedule a job in the target scope that picks up data from a safe shared location (like a staging table or an integration queue) rather than having the source app write directly. These workarounds might be more involved but can maintain the integrity of a store or restricted app while achieving your goal.
Conclusion:
Cross-scope access errors in ServiceNow can be frustrating, but they are there to protect applications from unintended interference. In this article, we covered how the “cross-scope access policy: security restriction” error arises due to ServiceNow’s scoped security model. Key takeaways are to always check the target resource’s Application Access settings first (making sure other scopes are allowed and the needed operations are enabled), and then handle cross-scope privileges and runtime access tracking to explicitly permit the interaction. We also discussed ensuring user roles are set appropriately, saw real-world examples of the error and its fixes, and explored alternative solutions when direct changes aren’t possible.
As a next step, ServiceNow developers and administrators should apply these solutions in a development environment. Try adjusting the Application Access on a sample table and using cross-scope privilege records to allow a scoped script to access it. Observe how the error disappears once the proper permissions are in place. Becoming comfortable with scoped security settings will empower you to integrate applications safely. Remember, the goal is to open up just enough access to get the job done – no more, no less – to keep your platform secure. With the strategies outlined here, you can confidently resolve cross-scope access policy issues and build applications that interact harmoniously within the ServiceNow ecosystem. Happy developing!