Skip to content
Dashboard

How do sandboxes help secure enterprise applications?

Content Engineer

Sandboxes help secure enterprise applications by separating untrusted code from the application's backend and limiting the resources that code can reach. For AI-generated scripts or customer-defined automations, Vercel Sandbox provides an isolated execution environment. Your application still decides which data enters it and which business actions its results can trigger.

An internal sales assistant might generate code to summarize sales by region. The program needs selected records and somewhere to compute, but no database password or permission to update customer accounts.

Copy link to headingWhen does an enterprise application need a sandbox?

Sandboxing helps when a feature runs code your team hasn't approved through normal development. This includes model-generated scripts, customer-supplied transformations, and plugins written outside your team.

Even a legitimate request can produce code that loops indefinitely, reads unexpected files, or sends data to an unintended destination.

The need depends on what the feature executes. An assistant that summarizes authorized text through a model API may have no arbitrary-code execution step. It still needs access controls and data-handling rules. Adding a tool that runs generated Python introduces a separate environment to secure, with permissions that should follow the task.

If a departmental reporting assistant gains live CRM access, its permissions need another review. Assign an owner and define who can approve changes before expanding its access beyond exported data.

Copy link to headingWhere should the security boundary go?

Keep the application services that enforce identity and business permissions separate from generated-code execution. The backend authorizes a job, selects its inputs, and creates the execution environment. It then receives the result through an interface whose size and format it can check.

Putting the backend and the generated program inside one shared sandbox still leaves them sharing the files and credentials available there. Separating agent compute from generated-code compute creates a boundary between those responsibilities. The model-facing tool can request an analysis without handing the program the service credentials used to retrieve its input.

For the sales assistant, that boundary makes the following decisions explicit:

Resource or operation

Application responsibility

What the analysis job receives

Employee identity

Authenticate the request and check access to the selected accounts

Only the authorized export

Production database

Retrieve permitted records through the backend

A file containing the fields needed for analysis

Model credentials

Keep model calls in the application service

Generated code, without the model API key

Outbound network

Select destinations required by the job

No outbound access for an offline calculation

CRM updates

Enforce permissions and any required approval when writing

No write capability in the analysis job

Tenant IDs supplied in prompts cannot establish these permissions. Resolve the tenant and dataset through authenticated application state before provisioning the sandbox. Even correctly isolated jobs receive the wrong customer's data if the backend exports it incorrectly.

Copy link to headingHow can you isolate a sales-analysis job?

Suppose an employee asks for sales totals by region. The application checks record access and exports permitted regions and amounts in cents. The model can write code from a schema or synthetic sample without the full export.

The generated program runs against the authorized export inside a disposable sandbox. Because this calculation needs no external API, the application can deny outbound networking. The program writes a small JSON result, which the backend validates before displaying it to the same authorized employee.

Use Node.js 22 or later in the host application and configure Sandbox authentication. Install the dependencies for the server-side TypeScript function:

pnpm add @vercel/sandbox zod

The function assumes an authorized export, so the calling service must authenticate the employee and select only records they may access.

The program must read sales.csv and write result.json as an object containing a regions array. Each row has a region string and an integer totalCents. It can use Node.js built-in modules, with no package installation during execution.

enterprise-sales-analysis.mts
import { Sandbox } from '@vercel/sandbox';
import { z } from 'zod';
const SalesResult = z.object({
regions: z.array(z.object({
region: z.string().min(1).max(80),
totalCents: z.number().int().safe(),
}).strict()).max(100),
}).strict();
export async function runSalesAnalysis(
generatedCode: string,
authorizedCsv: Buffer,
) {
if (
Buffer.byteLength(generatedCode) > 100_000 ||
authorizedCsv.length > 5_000_000
) {
throw new Error('Analysis input exceeds the configured limit');
}
const sandbox = await Sandbox.create({
image: 'vercel/sandbox/universal',
persistent: false,
networkPolicy: 'deny-all',
timeout: 60_000,
});
try {
await sandbox.writeFiles([
{ path: 'sales.csv', content: authorizedCsv },
{ path: 'analysis.mjs', content: Buffer.from(generatedCode) },
]);
const command = await sandbox.runCommand({
cmd: 'node',
args: ['analysis.mjs'],
detached: true,
timeoutMs: 15_000,
});
const finished = await command.wait();
if (finished.exitCode !== 0) {
throw new Error('Analysis execution failed');
}
const stream = await sandbox.readFile({ path: 'result.json' });
if (!stream) throw new Error('Analysis result is missing');
const chunks: Buffer[] = [];
let bytes = 0;
for await (const chunk of stream) {
const buffer = Buffer.from(chunk);
bytes += buffer.length;
if (bytes > 64_000) {
throw new Error('Analysis result is too large');
}
chunks.push(buffer);
}
const result: unknown = JSON.parse(
Buffer.concat(chunks).toString('utf8'),
);
return SalesResult.parse(result);
} finally {
await sandbox.delete();
}
}

The SDK runs a detached command and waits for completion without fetching logs into the app. The reader retains up to 64,000 bytes before parsing JSON. This cap does not limit sandbox file growth or total application memory.

The command has a 15-second deadline and the sandbox has a 60-second lifetime. Tune these example limits for your workload.

The function requests sandbox deletion after success or failure. If deletion fails, its error can replace the execution error or prevent a successful result from returning. Record the job outcome separately from cleanup failures in the calling service.

Your service should reconcile abandoned jobs after a host crash and enforce per-user concurrency limits before provisioning new sandboxes.

Schema validation checks structure, not whether totals are correct or labels contain appropriate text. Render labels as text, preserve the input revision for review, and test calculations against known answers.

Integrate isolated execution with Next.js or Python.

Copy link to headingWhat if the job needs to call business APIs?

Some automations need current data or an external service during execution. Add the required access deliberately. An offline job can use deny-all; a connected job needs a policy that allows its intended destinations. Vercel's Sandbox firewall supports both, while its default policy allows outbound internet access. Isolation alone doesn't configure a network restriction.

Credential brokering can attach credentials to outbound requests outside the sandbox, keeping raw secret values away from the program. The receiving API still sees an authenticated request. Limit the credential's authority and enforce which records and operations the job may access; a hidden key with broad write permissions can still authorize a harmful request.

For an automation that proposes CRM changes, keep the write behind an application tool that checks the approved record and revision. Treat the model's proposal as input to that check. Bind human approval to the exact change and recheck it if the record changes before execution.

Notion Workers uses Vercel Sandbox for developer- and agent-written code that extends its platform. Its architecture combines separate microVMs with network controls and credential injection.

Copy link to headingHow should you handle retained state and audit records?

Choose the lifetime of a workspace according to the task. An independent export analysis can discard its environment after returning a result. Continuing projects may need files across sessions, including changes made by earlier untrusted programs. Reusing a workspace also requires checking who owns it and what the next job is allowed to inherit.

Vercel creates persistent sandboxes by default, so the example sets persistent: false. Stopping compute and deleting retained state are different operations. Snapshots survive sandbox deletion by default and need their own expiration or deletion policy.

Review mounted storage separately, and keep reusable base environments free of customer exports or credentials. Restoring a filesystem cannot undo a CRM update already sent to another service.

Store execution records outside the generated program's write access. Connect the initiating user and authorization decision to a job identifier, the sandbox name, and the input revision. Preserve the program version or a protected reference to it.

Record completion, validation failures, and any downstream action. Sandbox command output can help investigate a failure, but it isn't independent evidence that an action was authorized.

An agent audit trail should link attempted actions to their effects in other systems. Restrict access to audit records and keep full exports out of routine logs.

Deleting a sandbox doesn't erase data copied to model requests, application logs, or stored results. Set retention rules for each destination.

Copy link to headingWhat should you test before enabling the feature?

Successful calculations do not establish that access controls hold under misuse. Test the boundaries with requests and programs that should fail:

  • An authenticated employee requests an export belonging to another tenant. The application rejects it before the sandbox receives data.

  • Generated code attempts an outbound request during offline analysis. The configured network policy blocks it.

  • Generated code runs past the command deadline. Confirm that execution stops and the service attempts cleanup or schedules recovery.

  • The program writes a result larger than 64,000 bytes. The reader rejects it instead of returning it to the employee.

  • The result requests a CRM write without a matching approval. The application refuses the write even if the sandbox completed successfully.

  • An employee returns to a retained workspace after losing access. The application rejects the request even if they still know its sandbox identifier.

For reproducible tests, pin the sandbox image to a tested digest and plan updates for security patches. Recheck the affected permissions whenever the image, network policy, or connected tool changes.

Copy link to headingWhat does sandboxing leave to the application?

Sandboxing restricts code execution within a defined environment. Prompt injection can still influence which code an agent produces, and permitted tools can still perform unwanted actions. The application must enforce business permissions at the point where an operation takes place.

The result channel also carries data out of the sandbox. Malicious code can put input records into its output even when outbound networking is disabled. Restrict who receives results and what output the application accepts. If you pass a result back to a model, treat its contents as untrusted data and apply your organization's rules for sending information to that provider.

Copy link to headingFrequently asked questions

Copy link to headingCan an enterprise app keep using a shared service account?

Yes, but review the account's permissions and keep its credential outside untrusted execution. The application must still associate each job with an authorized user or automation and restrict operations to that job's scope. Employees do not inherit access to every record the shared account can reach.

Copy link to headingDoes blocking the sandbox's network prevent every data leak?

No. Files and command results can return through the application's own result channel, and the application may send them to a model or store them in logs. Restrict the input, validate the output contract, and control who can receive the result alongside the network policy.

Copy link to headingCan different departments share one sandbox?

Programs in a shared workspace may inherit files left by earlier jobs. Use separate sandboxes when jobs require separate data or permission boundaries, and authorize every attempt to resume a retained workspace. Sharing a reusable base image is a different decision from sharing a live workspace containing department data.

Copy link to headingDo sandboxed actions still need business approval?

Yes, when the business process requires it. Isolation doesn't grant permission to change a customer record or approve a transaction. Enforce the applicable review and authorization checks in the service that performs the action, with approval tied to the exact proposal.

More Enterprise Apps and Agents articles

Ready to deploy?