Skip to content

adobe/aio-lib-sandbox

App Builder Sandbox SDK

Version Downloads/week Node.js CI License Codecov Coverage Status

JavaScript SDK for Adobe Runtime Sandboxes.

A sandbox is an ephemeral, isolated compute environment. You create one, run commands and read/write files inside it over a WebSocket session, then destroy it.

Warning

Alpha. This SDK is in active alpha development. The API surface and authentication model may change without notice. Pin exact versions; do not rely on latest.

Pre-requisites

To use this library, you must have Sandboxes enabled for your Runtime namespace. Please contact Michael Goberling (mgoberling@adobe.com) or Cosmin Stanciu (stanciu@adobe.com) to request this.

Install

npm install @adobe/aio-lib-sandbox@alpha

Quickstart

Inside a Runtime action, no configuration is needed to use the SDK as credentials are read automatically from the environment.

const { Sandbox } = require('@adobe/aio-lib-sandbox')

async function main (params) {
  const sandbox = await Sandbox.create({ name: 'my-sandbox' })

  const { stdout } = await sandbox.exec('node --version', { timeout: 10_000 })

  await sandbox.destroy()
  return { stdout: stdout.trim() }
}

exports.main = main

Configuration

When running inside a Runtime action, the SDK reads credentials from the environment automatically:

Variable Description
__OW_API_HOST Runtime API host
__OW_NAMESPACE Runtime namespace
__OW_API_KEY Runtime API key (basic auth)

You can override any of these by passing them explicitly to Sandbox.create() or Sandbox.get():

const sandbox = await Sandbox.create({
  apiHost:   'https://adobeioruntime.net',
  namespace: 'my-namespace',
  auth:    'my-api-key',
  name:      'my-sandbox'
})

Usage

Create Sandbox

const { Sandbox } = require('@adobe/aio-lib-sandbox')

const sandbox = await Sandbox.create({
  name:        'my-sandbox',
  type:        'cpu:default',
  maxLifetime: 3600,
  ports:       [3000, 8080],
  envs:        { API_KEY: 'your-api-key' }
})

Get Status

const sandbox = await Sandbox.get(sandbox.id)
console.log('status:', sandbox.status)

Exec

const result = await sandbox.exec('ls -al', { timeout: 10_000 })
console.log('stdout:', result.stdout.trim())
console.log('exit code:', result.exitCode)

Note: Commands run in the /workspace directory by default, this is not configurable

Detached Commands

Pass detached: true to run a long-lived background process.

// Start a background server
const command = await sandbox.exec('node server.js', { detached: true })

// Wait for it to exit (e.g. after you stop it)
const result = await command.wait()
console.log('exit code:', result.exitCode)

// Send a signal to stop it
await command.kill()

If the process is still running and you need a handle to it from a different context, use getCommand() to re-attach by execId:

const command = await sandbox.getCommand(execId, { onOutput: (data, stream) => process.stdout.write(data) })
await command.wait()

Note: Only 5 background processes are allowed to run at once currently.

File Management

const script = "console.log('hello from sandbox script', process.version)\n"
await sandbox.writeFile('hello.js', script)

const content = await sandbox.readFile('hello.js')
console.log('readFile content:', content.trim())

const entries = await sandbox.listFiles('.')
console.log('listFiles entries:', entries)

Exec a File

const result = await sandbox.exec('node hello.js', { timeout: 10_000 })
console.log('stdout:', result.stdout.trim())
console.log('stderr:', result.stderr.trim())
console.log('exit code:', result.exitCode)

Write to Stdin

Command start

const result = await sandbox.exec('node process_csv.js', {
  stdin: 'col1,col2\nval1,val2\n',
  timeout: 10_000
})
console.log('stdout:', result.stdout.trim())

Running command

const task = sandbox.exec('cat -n', { timeout: 10_000 })

sandbox.writeStdin(task.execId, 'line 1\n')
sandbox.writeStdin(task.execId, 'line 2\n')
sandbox.closeStdin(task.execId)

const result = await task
console.log('stdout:', result.stdout.trim())

Destroy

await sandbox.destroy()

Preview URLs

Ports that should be publicly accessible must be declared at creation time via the ports array.

const sandbox = await Sandbox.create({
  name:  'web-sandbox',
  ports: [3000, 8080]
})

// Start a server inside the sandbox on the declared port
await sandbox.exec('node server.js &', { timeout: 50_000 })

// Retrieve the pre-provisioned preview URL — synchronous, no network call
const url = sandbox.getUrl(3000)
console.log('preview:', url)
// https://sb-abc123-va6-0-xK3mPq2nAeB-3000.sandbox-adobeioruntime.net

Network Policies

Sandboxes are default-deny. All outbound traffic is blocked unless explicitly allowed.

Pass a policy.network.egress array at creation time to allowlist outbound endpoints, paths, or HTTP verbs.

const sandbox = await Sandbox.create({
  name:        'policy-sandbox',
  maxLifetime: 300,
  policy: {
    network: {
      egress: [
        { host: 'httpbin.org', port: 443 },
        {
          host: 'api.github.com',
          port: 443,
          rules: [
            { methods: ['GET'], pathPattern: '/repos/**' }
          ]
        }
      ]
    }
  }
})

Development

Install development dependencies:

npm install

To run the same checks used by CI:

npm test

Linting is powered by ESLint:

npm run lint
npm run lint-fix

About

JavaScript SDK for Adobe App Builder Sandboxes.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors