Skip to main content
The Vault API provides methods for securely storing sensitive data with automatic encryption, managing encrypted objects, and handling data encryption keys.

Create Object

Creates a new encrypted object in the vault.
const metadata = await workos.vault.createObject({
  name: 'api_key_stripe',
  value: 'sk_live_1234567890abcdef',
  context: {
    environment: 'production',
    service: 'payment'
  }
});

Parameters

options
object
required
name
string
required
Unique name for the vault object. Used to retrieve the object later.
value
string
required
The sensitive data to encrypt and store.
context
KeyContext
required
Key-value pairs used for encryption context. This context must be provided when decrypting the data.

Response

id
string
Unique identifier for the vault object.
environmentId
string
ID of the environment where the object is stored.
keyId
string
ID of the encryption key used.
context
KeyContext
The encryption context provided when creating the object.
versionId
string
Version ID for this object.
updatedAt
Date
Timestamp when the object was last updated.
updatedBy
object
Information about who last updated the object.

List Objects

Retrieves a paginated list of vault objects.
const { data, listMetadata } = await workos.vault.listObjects({
  limit: 20,
  after: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25'
});

data.forEach(obj => {
  console.log(obj.name, obj.updatedAt);
});

Parameters

options
object
limit
number
Maximum number of objects to return. Default is 10.
after
string
Cursor for pagination. Use the listMetadata.after value from a previous response.

Response

data
array
Array of object digests.
listMetadata
object
Pagination metadata.

Read Object

Retrieves a vault object by its ID, including the encrypted value.
const vaultObject = await workos.vault.readObject({
  id: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25'
});

console.log('Name:', vaultObject.name);
console.log('Value:', vaultObject.value); // Encrypted

Parameters

options
object
required
id
string
required
The ID of the vault object to retrieve.

Response

id
string
Unique identifier for the object.
name
string
Name of the vault object.
value
string
The encrypted value (base64-encoded ciphertext).
metadata
object
Object metadata including encryption context and version information.

Read Object by Name

Retrieves a vault object by its unique name.
const vaultObject = await workos.vault.readObjectByName('api_key_stripe');
console.log('Value:', vaultObject.value);

Parameters

name
string
required
The unique name of the vault object.

Response

Returns the same structure as Read Object.

Describe Object

Retrieves metadata about a vault object without returning the encrypted value.
const metadata = await workos.vault.describeObject({
  id: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25'
});

console.log('Context:', metadata.metadata.context);
console.log('Last updated:', metadata.metadata.updatedAt);

Parameters

options
object
required
id
string
required
The ID of the vault object.

Response

Returns a vault object with metadata but without the value field.

Update Object

Updates the value of an existing vault object.
const updated = await workos.vault.updateObject({
  id: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25',
  value: 'sk_live_new_key_9876543210',
  versionCheck: 'version_abc123' // Optional: prevent race conditions
});

Parameters

options
object
required
id
string
required
The ID of the vault object to update.
value
string
required
The new value to encrypt and store.
versionCheck
string
Optional version ID. If provided, the update will only succeed if the current version matches this value. Prevents concurrent modification issues.

Response

Returns the updated vault object with new version information.

Delete Object

Permanently deletes a vault object.
await workos.vault.deleteObject({
  id: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25'
});

Parameters

options
object
required
id
string
required
The ID of the vault object to delete.

Response

Returns a Promise that resolves to void when deletion is successful.

List Object Versions

Retrieves all versions of a vault object.
const versions = await workos.vault.listObjectVersions({
  id: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25'
});

versions.forEach(version => {
  console.log(`Version ${version.id}: ${version.createdAt}`);
  console.log(`Current: ${version.currentVersion}`);
});

Parameters

options
object
required
id
string
required
The ID of the vault object.

Response

versions
array
Array of version objects.

Create Data Key

Generates a new data encryption key for client-side encryption.
const keyPair = await workos.vault.createDataKey({
  context: {
    environment: 'production',
    purpose: 'file_encryption'
  }
});

console.log('Plain key:', keyPair.dataKey.key);
console.log('Encrypted keys:', keyPair.encryptedKeys);

Parameters

options
object
required
context
KeyContext
required
Encryption context for the data key. Must be provided when decrypting.

Response

context
KeyContext
The encryption context provided.
dataKey
object
The plaintext data key.
encryptedKeys
string
Base64-encoded encrypted version of the data key. Store this alongside your encrypted data.

Decrypt Data Key

Decrypts an encrypted data key for use in decryption operations.
const dataKey = await workos.vault.decryptDataKey({
  keys: encryptedKeysString
});

// Use dataKey.key for decryption

Parameters

options
object
required
keys
string
required
Base64-encoded encrypted keys string from createDataKey.

Response

key
string
Base64-encoded plaintext encryption key.
id
string
Unique identifier for the data key.

Encrypt

Client-side encryption of data using WorkOS-managed keys.
const encryptedData = await workos.vault.encrypt(
  'sensitive customer data',
  {
    environment: 'production',
    data_type: 'pii'
  },
  'additional authenticated data' // Optional
);

// Store encryptedData in your database

Parameters

data
string
required
The plaintext data to encrypt.
context
KeyContext
required
Encryption context. Must match when decrypting.
associatedData
string
Optional additional authenticated data (AAD) for AES-GCM encryption. Provides additional integrity protection.

Response

Returns a base64-encoded string containing the IV, authentication tag, encrypted keys, and ciphertext.

Decrypt

Client-side decryption of data encrypted with the encrypt method.
const plaintext = await workos.vault.decrypt(
  encryptedData,
  'additional authenticated data' // Must match what was used during encryption
);

console.log('Decrypted:', plaintext);

Parameters

encryptedData
string
required
Base64-encoded encrypted data from the encrypt method.
associatedData
string
Optional AAD. Must match the value used during encryption.

Response

Returns the decrypted plaintext string.

End-to-End Encryption Example

import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS(process.env.WORKOS_API_KEY);

// Encrypt sensitive data
const sensitiveData = {
  ssn: '123-45-6789',
  creditCard: '4111-1111-1111-1111'
};

const context = {
  userId: 'user_123',
  environment: 'production'
};

// Method 1: Vault storage (recommended for secrets)
const metadata = await workos.vault.createObject({
  name: 'user_123_payment_info',
  value: JSON.stringify(sensitiveData),
  context
});

// Later, retrieve and use
const vaultObject = await workos.vault.readObjectByName('user_123_payment_info');
const decrypted = JSON.parse(vaultObject.value);

// Method 2: Client-side encryption (for application data)
const encrypted = await workos.vault.encrypt(
  JSON.stringify(sensitiveData),
  context
);

// Store encrypted in your database
await db.users.update(userId, { encryptedData: encrypted });

// Later, decrypt
const retrieved = await db.users.findById(userId);
const decrypted = await workos.vault.decrypt(retrieved.encryptedData);
const data = JSON.parse(decrypted);

Encryption Context Best Practices

  1. Use meaningful context: Include identifiers that relate to the data being encrypted (e.g., user ID, tenant ID, data type)
  2. Consistency is key: Use the same context structure across your application
  3. Don’t include sensitive data: Context values are not encrypted
  4. Version your contexts: Consider including a version field for schema evolution
const context = {
  version: '1',
  tenantId: 'tenant_123',
  userId: 'user_456',
  dataType: 'payment_method',
  environment: process.env.NODE_ENV
};

Version Control

Vault objects support versioning to help you:
  • Track changes to sensitive data
  • Rollback to previous values if needed
  • Prevent concurrent modification conflicts
// Get all versions
const versions = await workos.vault.listObjectVersions({
  id: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25'
});

// Update with version check to prevent race conditions
const currentVersion = versions.find(v => v.currentVersion);

try {
  await workos.vault.updateObject({
    id: 'vault_obj_01HEZYMVP4E1Q5QFZGS4Z0WM25',
    value: 'new secret value',
    versionCheck: currentVersion.id
  });
} catch (error) {
  // Handle version mismatch - object was modified by another process
  console.error('Concurrent modification detected');
}

Build docs developers (and LLMs) love