SecretService: Library for Storing Secrets in Google Apps Script
Tags: googleappsscript, gas, opensource, security
Published: 2024-03-12 12:11:16

Google Apps Script is an excellent tool for connecting various services via API. Access to API requires storing secrets: tokens, passwords, and other secrets. There are [many ways to store secrets in Google Apps Script](https://dataful.tech/apps-script/security/how-to-store-secrets/), but most of them are challenging and have drawbacks. The most popular way to store secrets is still saving them directly in the code: it might be okay for a small one-off script that only you have access to, but it doesn’t cut it when we are talking about real-life implementations.

## Solution 

We created `SecretService` ([GitHub](https://github.com/dataful-tech/secret-service)), an open-source Google Apps Script library, to solve this problem. It is designed to simplify storing secrets and add various quality-of-life improvements.

These are the main features of `SecretService`:

1. **Choose a storage for the secrets:**
    - *Any Properties instance* from your script
    - *Custom secret storage*, like Google Cloud Secret Manager
2. **Different modes in case of a missing secret:**
    - *Silent:* do nothing, return null.
    - *Strict:* throw an error.
    - *Interactive:* prompt the user for a missing secret.

_**If you find this library useful, please give the [repository](https://github.com/dataful-tech/secret-service) a star and share the link with others.**_

## Examples

There are several ways to use SecretService. Check out the [repository](https://github.com/dataful-tech/secret-service) for the complete documentation and more examples.

### Store Secrets in UserProperties

Generally, the safest out of the box place to store secrets is `UserProperties`: they are accessible only to the user who runs the script, and only in the script you mean.

> **Important:** regardless of what the [official documentation](https://developers.google.com/apps-script/reference/properties/properties-service#getuserproperties), says the user properties of the owner of a Google Sheets document are accessible to anyone via a custom function. (why Google, why?)

```js
const SECRETS = SecretService.init({
  storage: PropertiesService.getUserProperties()
});

// Only once:
const API_KEY = SECRETS.setSecret("API_KEY", "value");

const API_KEY = SECRETS.getSecret("API_KEY");
```

### Interactive Mode

If your Google Apps Script is attached to a spreadsheet/document/form/slides, you can use interactive mode that will prompt the user to enter the secret if it was not set before:

```js
const SECRETS = SecretService.init({
  storage: PropertiesService.getUserProperties(),
  scriptContainer: SpreadsheetApp,
  mode: "interactive",
});

const API_KEY = SECRETS.getSecret("API_KEY");
```

User prompt:

![SecretService: Prompting user for a secret](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3bo8lcgd8o529vk031z.png)

If the user clicks `Cancel` or closes the prompt, SecretService will throw an error.

![SecretService: Error if the secret was not provided](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lubqltkxysb2na382atj.png)

---

Contributions are welcome. Feel free to submit pull requests or issues on [GitHub](https://github.com/dataful-tech/secret-service).