A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

Gists

A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

Abstract

Generating Google Apps Script (GAS) with Gemini CLI from natural language introduces security risks due to broad permissions. This report investigates a “Fake-Sandbox” using the gas-fakes library, translating GAS calls into granularly-scoped API requests to securely execute scripts created from user prompts.

Introduction

1. Background: Generative AI and the Challenge of Secure Script Execution

The emergence of Generative AI now makes it possible to generate executable scripts directly from natural language instructions, particularly through interfaces like the Gemini CLI. For locally executable languages such as JavaScript (Node.js) and Python, code generated from a simple prompt can be run directly. However, Google Apps Script (GAS) presents a unique challenge as it operates within Google’s server-side infrastructure. Executing locally generated GAS code requires the remote invocation of a server-side function via the scripts.run method of the Apps Script API. This process highlights the critical need for a sandbox environment to manage permissions effectively and mitigate the risks associated with executing code generated from natural language, which can sometimes produce unintended or insecure outcomes.

2. Existing Sandbox Strategies and Their Inherent Limitations

Implementing a sandbox—an isolated, secure environment for code execution—for Google Apps Script involves several potential strategies, each with significant drawbacks:

3. A Novel Approach: A Fake-Sandbox with gas-fakes

The Node.js package gas-fakes, developed by Bruce McPherson, offers a potential solution to this dilemma. This library functions as a local runtime environment for GAS, translating calls to standard GAS services (e.g., SpreadsheetApp.openById("###")) into their equivalent Google API requests (e.g., Google Sheets API). This abstraction allows developers to write scripts using familiar GAS syntax while the underlying operations are executed via Google APIs that support more granular permission controls.

This mechanism makes it possible to operate on a specific spreadsheet using standard GAS methods while restricting access to designated files and methods. This approach effectively decouples the developer experience from the underlying permission model, combining the security benefits of fine-grained permissions with the development efficiency of native GAS services. This capability suggests its potential as a “Fake-Sandbox” for executing code generated from natural language with tightly controlled access.

4. Objective of This Report

This report aims to examine the feasibility of constructing this Fake-Sandbox environment for Google Apps Script. We will investigate the use of the gas-fakes library as a means to safely execute scripts generated from natural language prompts using Gemini CLI by intercepting and managing their execution. While gas-fakes does not yet have comprehensive coverage of all GAS classes and methods, our preliminary findings suggest that this approach represents a promising pathway toward secure and scalable automation with Google Apps Script.

Conceptual Workflow

The following diagram illustrates the process of executing a Google Apps Script generated by the Gemini CLI within the fake-sandbox environment:

A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

Mermaid Playground

Practical Implementation

1. Install Gemini CLI

Instructions for installing the Gemini CLI can be found at https://github.com/google-gemini/gemini-cli.

Gemini CLI Configuration

To execute Google Apps Script within the fake-sandbox, you need to configure the Gemini CLI. Add the following text to the GEMINI.md file located in the .gemini directory:

# Generate and run Google Apps Script

Generate the script by referring to the sample scripts at "StackOverflow" obtained using a Google search. If an error occurs, modify the script by referring to StackOverflow again.

In order to run the script of Google Apps Script, use "@mcpher/gas-fakes". The base of the script is as follows: "BaseScript". Google Apps Script is safely run in the sandbox. As additional information, in the current stage, gas-fakes cannot use `Logger.log`. So, please use `console.log` instead of it.

<BaseScript>
```javascript
import "@mcpher/gas-fakes/main.js"
ScriptApp.__behavior.sandBoxMode = true;

//---
// Generated Google Apps Script
//---

ScriptApp.__behavior.trash();
```
</BaseScript>

Please replace the comment lines in "BaseScript" with the generated Google Apps Script. And, run the script by `node [filename.js]`.

The prompt Generate the script by referring to the sample scripts at "StackOverflow" obtained using a Google search. is included to guide Gemini towards generating code that uses current and effective methods.

2. Install gas-fakes

You can find instructions for installing gas-fakes at https://github.com/brucemcpherson/gas-fakes.

3. Example Use Cases

Run the Gemini CLI by entering $ gemini in your terminal.

Example 1: Create Spreadsheet and Populate with Values

Prompt:

Create the following application using Google Apps Script and run the script.
1. Create a new Google Spreadsheet as "temp spreadsheet".
2. Insert a new sheet as "temp" to the created Spreadsheet.
3. Put a value of `[["header1", "header2", "header3"], ["a2", "b2","c2"]]` into the "temp" sheet.

Result: The Gemini CLI will generate and execute a script that safely performs these actions within the fake-sandbox.

A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

The generated script is as follows. The core logic within the createAndPopulateSpreadsheet function is also compatible with the standard Google Apps Script editor.

import "@mcpher/gas-fakes/main.js";
ScriptApp.__behavior.sandBoxMode = true;

//---
// Generated Google Apps Script
//---

function createAndPopulateSpreadsheet() {
  // 1. Create a new Google Spreadsheet as "temp spreadsheet".
  const ss = SpreadsheetApp.create("temp spreadsheet");
  console.log(`Spreadsheet created: ${ss.getName()} (ID: ${ss.getId()})`);

  // 2. Insert a new sheet as "temp" to the created Spreadsheet.
  // Get the default sheet and rename it, or create a new one and delete the default.
  // Let's create a new one and delete the default for clarity.
  const tempSheet = ss.insertSheet("temp");
  console.log(`Created new sheet: ${tempSheet.getName()}`);

  // Delete the default "Sheet1" if it exists
  const defaultSheet = ss.getSheetByName("Sheet1");
  if (defaultSheet) {
    ss.deleteSheet(defaultSheet);
    console.log("Deleted default 'Sheet1'.");
  }

  // 3. Put a value of [["header1", "header2", "header3"], ["a2", "b2","c2"]] into the "temp" sheet.
  const data = [
    ["header1", "header2", "header3"],
    ["a2", "b2", "c2"],
  ];

  const range = tempSheet.getRange(1, 1, data.length, data[0].length);
  range.setValues(data);
  console.log("Values have been added to the 'temp' sheet.");
  console.log(`URL: ${ss.getUrl()}`);
}

createAndPopulateSpreadsheet();

ScriptApp.__behavior.trash();

Example 2: Create Spreadsheet and Move to a Folder

Prompt:

Create the following application using Google Apps Script and run the script.
1. Create a new Google Spreadsheet as "temp spreadsheet".
2. Create a new folder of "tempFolder".
3. Move the Spreadsheet to the folder.

Result: The script is generated and executed securely, demonstrating file and folder manipulation.

A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

The generated script can also be used in the Google Apps Script editor.

import "@mcpher/gas-fakes/main.js";
ScriptApp.__behavior.sandBoxMode = true;

//---
// Generated Google Apps Script
//---

function createSpreadsheetCreateFolderMoveFile() {
  const spreadsheetName = "temp spreadsheet";
  const folderName = "tempFolder";

  // 1. Create a new folder
  const newFolder = DriveApp.createFolder(folderName);
  console.log(`Folder '${folderName}' created with ID: ${newFolder.getId()}`);

  // 2. Create a new spreadsheet in the root (initially)
  const newSpreadsheet = SpreadsheetApp.create(spreadsheetName);
  console.log(
    `Spreadsheet '${spreadsheetName}' created with ID: ${newSpreadsheet.getId()}`
  );

  // 3. Get the file object of the newly created spreadsheet
  const file = DriveApp.getFileById(newSpreadsheet.getId());

  // 4. Move the spreadsheet to the new folder
  file.moveTo(newFolder);
  console.log(
    `Spreadsheet '${spreadsheetName}' moved to folder '${folderName}'.`
  );

  // Optional: Log URLs for verification
  console.log(`New Folder URL: ${newFolder.getUrl()}`);
  console.log(`New Spreadsheet URL: ${newSpreadsheet.getUrl()}`);
}

// Call the main function
createSpreadsheetCreateFolderMoveFile();

ScriptApp.__behavior.trash();

Example 3: Create, Populate, and Organize a Spreadsheet

Prompt:

Create the following application using Google Apps Script and run the script.
1. Create a new Google Spreadsheet as "temp spreadsheet".
2. Insert a new sheet as "temp" to the created Spreadsheet.
3. Put a value of `[["header1", "header2", "header3"], ["a2", "b2","c2"]]` into the "temp" sheet.
4. Freeze the 1st row and 1st column of the "temp" sheet.
5. Create a new folder of "tempFolder".
6. Move the Spreadsheet to the folder.

Result: This more complex workflow is also handled securely by the fake-sandbox.

A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

The generated script is as follows:

import "@mcpher/gas-fakes/main.js";
ScriptApp.__behavior.sandBoxMode = true;

function main() {
  try {
    // 1. Create a new Google Spreadsheet as "temp spreadsheet".
    const spreadsheetName = "temp spreadsheet";
    const spreadsheet = SpreadsheetApp.create(spreadsheetName);
    const spreadsheetId = spreadsheet.getId();
    console.log(
      `Created spreadsheet: ${spreadsheetName} (ID: ${spreadsheetId})`
    );

    // 2. Insert a new sheet as "temp" to the created Spreadsheet.
    const newSheetName = "temp";
    const sheet = spreadsheet.insertSheet(newSheetName);
    console.log(`Inserted new sheet: ${newSheetName}`);

    // Remove the default "Sheet1" if it exists and is empty
    const defaultSheet = spreadsheet.getSheetByName("Sheet1");
    if (defaultSheet) {
      spreadsheet.deleteSheet(defaultSheet);
      console.log("Deleted default 'Sheet1'.");
    }

    // 3. Put a value of `[["header1", "header2", "header3"], ["a2", "b2","c2"]]` into the "temp" sheet.
    const data = [
      ["header1", "header2", "header3"],
      ["a2", "b2", "c2"],
    ];
    sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
    console.log("Inserted values into the sheet.");

    // 4. Freeze the 1st row and 1st column of the "temp" sheet.
    sheet.setFrozenRows(1);
    sheet.setFrozenColumns(1);
    console.log("Frozen first row and first column.");

    // 5. Create a new folder of "tempFolder".
    const folderName = "tempFolder";
    const folder = DriveApp.createFolder(folderName);
    const folderId = folder.getId();
    console.log(`Created new folder: ${folderName} (ID: ${folderId})`);

    // 6. Move the Spreadsheet to the folder.
    const file = DriveApp.getFileById(spreadsheetId);
    file.moveTo(folder);
    console.log(
      `Moved spreadsheet '${spreadsheetName}' to folder '${folderName}'.`
    );
  } catch (e) {
    console.error("An error occurred: " + e.toString());
  }
}

main(); // Call the main function
ScriptApp.__behavior.trash();

Example 4: Create a Document and Add a Paragraph

Prompt:

Create the following application using Google Apps Script and run the script.
1. Create a new Google Document as "temp document".
2. Add a paragraph as a text of "sample".

Result: This example demonstrates that the fake-sandbox can also handle other Google Workspace applications like Google Docs.

A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

The generated script is as follows:

import "@mcpher/gas-fakes/main.js";
ScriptApp.__behavior.sandBoxMode = true;

//---
// Generated Google Apps Script
//---

function createDocumentAndAddText() {
  const docTitle = "temp document";
  const textContent = "sample";

  try {
    const doc = DocumentApp.create(docTitle);
    const body = doc.getBody();
    body.appendParagraph(textContent);
    console.log(
      `Successfully created document: ${doc.getName()} (ID: ${doc.getId()})`
    );
    console.log(`Document URL: ${doc.getUrl()}`);
  } catch (e) {
    console.error(`Failed to create document: ${e.message}`);
  }
}

// Call the function to execute the script
createDocumentAndAddText();

ScriptApp.__behavior.trash();

Summary

This feasibility study demonstrates a promising approach to securely executing Google Apps Script code generated by AI. The key takeaways are as follows:

 Share!