What SDF still can't automate

You can build a fully automated NetSuite deployment pipeline today. Here's what it covers, and the two things that still require a human in the account.

Certificate-based OAuth 2.0 Client Credentials (M2M) auth, no stored passwords, suitecloud project:deploy pushing script files, script records, deployment records, and custom objects straight from source control on every merge. That part of the problem is solved — see the working GitHub Actions and Azure Pipelines templates in the NetSuiteBytes org.

What it doesn't solve is everything that isn't a project artifact.

What project:deploy actually covers

SDF (SuiteCloud Development Framework) deploys whatever is described under your project's src/Objects and src/FileCabinet folders, driven by deploy.xml. That includes:

If it's a customization object with a script ID, SDF can almost certainly express it, version it, and deploy it repeatably. That's most of what makes a NetSuite release feel dangerous in a manual workflow, and automating it is a real, measurable improvement.

What doesn't travel with a deploy

Two categories of account configuration sit outside the project entirely. Neither is a bug in SDF — they're account state, not project state, and SDF was never designed to own them. But they're exactly the kind of thing that turns "the pipeline succeeded" into "production is subtly wrong."

1. Secret Manager access lists

NetSuite's secret object type in SDF captures the secret's script ID. It does not capture the Accessible From restriction list — the setting that actually determines which scripts, roles, or SuiteApps are allowed to read that secret's value at runtime.

That list is set by hand, in the account UI, per environment. It isn't in your project XML. It isn't in your deploy log. There's no suitecloud command that will tell you sandbox and production have drifted on it.

The failure mode is the sharp part. A script that isn't on a secret's access list doesn't get a clear "access denied" error. It gets an empty or null value back where the secret should be, and whatever your code does with that — usually a downstream auth failure — looks exactly like a bad credential. You end up debugging the wrong layer.

Mitigation: treat secret access lists as a manual checklist item on every environment promotion, not a "set it once and forget it" account setting. If you're standing up a new sandbox refresh or a new environment, re-verify every secret's access list before you trust anything that reads from it.

2. Role and integration permissions

The role your CI pipeline's SDF certificate authenticates as — and everything that role can and can't touch — is account configuration, not a deployable artifact. NetSuite does have a role customization object type in SDF, so some role definitions can be source controlled. But the certificate-to-role binding itself, and the actual permission grant your pipeline runs under, are set up once, by hand, per account, and don't get re-verified by a deploy.

That's fine for a stable pipeline that never changes what it touches. It's a real gap the moment scope grows — a new script type, a new record type, a new SuiteApp dependency — and nothing in the deploy pipeline tells you the CI role's permissions haven't kept pace.

Mitigation: document the CI integration role's permission set the same way you'd document infrastructure-as-code — outside NetSuite, in your repo, even though NetSuite itself won't enforce it as source of truth. Re-review it deliberately whenever the project's object types expand, not reactively when a deploy fails with a vague permission error.

Why this matters more than it sounds like it should

Both of these fail quietly. Neither produces the error message you'd expect. A missing secret access grant looks like a credential problem three layers downstream. A stale integration role permission looks like a random, hard-to-reproduce deploy failure that only shows up for one object type.

The practical result: teams with excellent CI/CD still budget time before every production release to click through the account by hand and eyeball the things the pipeline can't see. That's not a sign the pipeline is bad. It's an accurate read of what SDF actually manages versus what it doesn't.

Where this is headed

This is the exact gap NetSuiteBytes' Account Diff and Deploy roadmap items are aimed at — not just diffing and deploying script files and objects, which SDF already does reasonably well, but surfacing the account-level state (access lists, role/permission drift, deployment audience) that currently has no tooling at all.


Written by Kevin Kurkowski · Built by Literal Data LLC