SDF
June 16, 2024

Creating a Restricted NetSuite Role for SDF

Why you might want to do this, how it could be done, and findings from conducting an in-depth, role-building exercise in one of my test accounts.

Creating a Restricted NetSuite Role for SDF

The following post will detail my experience creating a restricted SuiteCloud Development Framework (SDF) role for pulling every object type exposed by the platform, while keeping the permission scope as narrow as possible. The use case here is for setting up periodic NetSuite-to-Git backups, which from an SDF perspective is a read-only exercise, hence the desire to create a suitable role for the task at hand, respecting the Least Privilege principle.

Process

My process for creating this restricted role for SDF was to be as follows:

  • Start with the only other non-Administrator role that NetSuite recommends for use with SDF, the Developer role
  • Set every permission to View (some permissions only have one selectable value which is 'Full', and so these were either removed or kept for good reason)
  • Perform a full account sync
  • Inspect objects which failed
  • Modify Role until failing objects became available again
  • Repeat the process until all errors were solved.

This strategy in theory should work since we are only performing Read operations in SDF to pull all objects from the account. The reality though is somewhat more challenging.

Administrator vs Custom Developer Role

First, here’s a table with some numbers comparing a full fetch on my test account, first using Administrator, and then my Custom Developer role (created using the process above).

The columns show the total amount of objects pulled in each case, along with how many were read successfully, how many failed, and which ones were reported as being locked (mostly belonging to Bundles/SuiteApps).

As you would expect, there were a lot more failures with the Custom Developer Role.

Administrator Role Errors

Most of the 15 that failed with the Administrator role were saved searches with the following error messages:

  • "record does not exist" - the majority of them
  • "the feature 'requisitions' required to access this page is not enabled in this account."
  • "invalid custom object being loaded"

Strangely enough, all the searches which failed with the “record does not exist” error, were visible in the UI, set to Public and had Administrator set in the Audience list.  Stranger yet, is that when I modified the script id for these searches to something else, and then back to the original id, they were successfully fetched.

The second error message is self-explanatory, and I didn’t bother with the "invalid custom object being loaded" error for one of the searches, as it wasn’t an important search and is a known issue.

So in general, using Administrator I was able to fetch the entire account no issues.

Now for the more interesting failures with the Custom Developer Role.

Custom Developer Role - Errors, Challenges and... Caveat

Here's a breakdown of the failures by object type when I ran a full fetch with the restricted role. For each group, I will explain which permissions had to be altered to fix the errors.

Failed objects by SDF record type

Entry Forms

Here, the most common errors were the following:

  • “an unexpected error has occurred”
  • “invalid custom object being loaded”

Forms are pesky little (or maybe not so little) objects and always seem to cause issues.  It’s no surprise though, as these objects are made up of many other objects of differing types (that’s really what a form is, an object of objects), causing them to have a long list of dependencies.  And since we’re trying to keep our permission set as narrow as possible, then you could see why we would run into issues.

Still though, our Custom Developer Role has the ‘View’ permission for virtually every custom object type out there, so despite our brief moment of solidarity with the complex nature of Form objects in NetSuite, I don’t see why things should fail in this case.

Here, the solution was to enable the ‘Edit’ or ‘Full’ access level for the following permission: Custom Record Types

Intuition would say 'View' on the permission Custom Entry Forms which my role had would suffice, however Entry Forms also encompass those forms you use to customise the layout of your custom record types. So this relation kind of makes sense.

NB:- Without the above permission, entryForms attached to custom record types will fail regardless of the Access Type permission set on the custom record itself. (ie No Permission | Use Permission List | Require Custom Record Entries Permission).

It would be really nice if ‘View’ would be accepted for all List:Object operations in SDF, after all, we are only reading the objects and not making any deployments.

NB:- The permission SuiteApp Marketplace baked into Developer role is particularly important from an SDF perspective, as this makes it possible to read 3rd party objects, even if they end up being locked, without it the objects would fail.

Transaction Forms

The only error I received for all 51 failed transaction forms was: 

  • “an unexpected error has occurred.”

The fix in this case, was to set the Custom Transaction Forms permission on my Custom Developer Role to ‘Edit’.  This instantly unlocked the failing forms when importing them in SDF again.

Saved Search

The errors here were consistent with the ones encountered with the Administrator role so I won’t go into them.

Center Link

The center link objects failed with the following error message:

  • “permission violation: you need  the 'custom center link' permission to access this page. please contact your account administrator.”

Here the solution was to ADD the permission Custom Center Link (singular) which was not present in the base Developer role. The Developer role already includes a permission called Custom Center Links (plural), but the one we need to add is different. Not at all confusing.

So far, the amount of changes we had to make to resolve most of the errors was very reasonable. With a few small tweaks we were able to overcome the majority of the failures.

Now for the caveat

Workflows

The biggest challenge arose when trying to resolve the errors for Workflows.

After a little back and forth I realised that the record type or subtype on which the workflow is operating needs to be added as a permission.  So let’s say you have a workflow which is manipulating Sales Orders, the Sales Order permission needs to be listed under Transactions, and worse still, the only access level which makes it work is ‘Full’. This did not sit well with the Privilege Police.

Given that you surely have many workflows in the account, all operating on various subtypes, to pull all workflows without issues you would need to drastically increase the permission scope of the role, by adding a permission for every record type Workflows can run on. Either that, or you would need maintain the role with explicit transaction / list record permissions for every new Workflow being created. This in my opinion defeats the purpose of using a restricted role in the first place.

A little reading of these NetSuite SuiteFlow docs in advance could have shed some light and hinted at what was in store regarding the unfortunate reality of interfacing with Workflows via a role with reduced rights.

Calling all SDF product owners...

Of all the possible issues / enhancements that could be filed as a result of going through this exercise, this one would be top of the list. 'View' on the Workflow permission should be enough to read Workflow XMLs and (if what follows is unavoidable), at most 'View' on the underlying subtypes.

Removing Workflows from the scope of our full account sync would be the one major trade-off in settling on this Custom Developer read-only role for SDF. We could surely find a way to process Workflows in a separate, more controlled context with elevated permissions.

Summary

All in all, I would consider the exercise a success. The role I have settled on is able to pull the majority of the account objects, and with a few more tweaks it could definitely work for our intended backup routines.

Here's just a snippet of the Role differences between the base Developer role and the new Custom Developer role I've created. If you didn't know about this cool NetSuite feature, now you know.

Contact us if you'd like to receive the full role XML which you can upload into your own account.