SecretService: Library for Storing Secrets in Google Apps Script

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, 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.


We created SecretService (GitHub ), 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 a star and share the link with others.


There are several ways to use SecretService. Check out the repository 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, says the user properties of the owner of a Google Sheets document are accessible to anyone via a custom function. (why Google, why?)

1const SECRETS = SecretService.init({
2  storage: PropertiesService.getUserProperties()
5// Only once:
6const API_KEY = SECRETS.setSecret("API_KEY", "value");
8const 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:

1const SECRETS = SecretService.init({
2  storage: PropertiesService.getUserProperties(),
3  scriptContainer: SpreadsheetApp,
4  mode: "interactive",
7const API_KEY = SECRETS.getSecret("API_KEY");

User prompt:

SecretService: Prompting user for a secret
SecretService: Prompting user for a secret

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

SecretService: Error if the secret was not provided
SecretService: Error if the secret was not provided

Contributions are welcome. Feel free to submit pull requests or issues on GitHub .