Dev Guide
Dev GuideUser GuideGitHubNuGetDevCommunityDoc feedbackLog In

Secrets store

This topic describes how to store customer data using the secrets store in Optimizely Connect Platform (OCP).

See SDK Reference for additional details.

The secrets store is your general-purpose storage for sensitive data such as API tokens, private webhook URLs, or account identification. The secret store is a simplified key-value store that allows you to get, put, patch (atomically), or delete data. The data you read/write to the secret store must be a hash of primitive types, such as strings, numbers, booleans, arrays, or other hashes. Data written to the secret store is encrypted in-flight and at rest using AES 256-bit encryption.



Do not write sensitive data such as user names, passwords, API keys, or API tokens to any store other than the secrets or settings store.

Write a secret

import {storage} from '@zaius/app-sdk';
const siteId = 123;
const token = await authenticate(siteId);
await storage.secrets.put('authToken', {token, siteId});

Get a secret

const authenticationToken = (await storage.secrets.get('authToken')).token;

Check if a secret exists

if (await storage.secrets.exists('authToken')) {
  // we already authenticated

Update a secret

const token = await refreshToken(siteId);
// update the token without changing the Site ID
await storage.secrets.patch('authToken', {token});

You can also perform more complicated updates atomically with a callback function:

interface TokenRateLimit {
  counter: number;
  hour: number;
  token: string;
await storage.secrets.patch('token', (value) => {
  if (value.hour !== currentHour) {
    value.hour = currentHour;
    value.counter = 0;
  } else {
    value.counter += apiCallCost;
  // return the new value to set based on the previous value
  return value;

Delete a secret

await storage.secrets.delete('authToken');

When an app is uninstalled, all secret data will be deleted. If the app is reinstalled, the secret store is empty.

Type safety

get, put, and patch are templated methods, so you can specify what type you are providing or expect to be returned for convenient type safety:

interface Token {
  value: string;
  expiration: number;
const token = await storage.secrets.get<Token>('token');
if (token.expiration < new Date().getTime() + 60000) {
  // Token is expiring soon!