Skip to main content

Programmatic API

Node SOPS provides a clean and intuitive API for integrating secret management directly into your Node.js applications. This guide covers the complete programmatic interface for both JavaScript and TypeScript users.

Basic Usage

JavaScript

const { Sops } = require('node-sops');

// Create a new Sops instance
const sops = new Sops();

// Encrypt a file
sops.encrypt('secrets.yaml', 'secrets.enc.json');

// Decrypt a file
sops.decrypt('secrets.enc.json', 'secrets.yaml');

// View decrypted content
const secrets = sops.view('secrets.enc.json');
console.log(secrets);

// Get a specific value
const apiKey = sops.get('secrets.enc.json', 'data.api.key');
console.log(apiKey);

TypeScript

import { Sops } from 'node-sops';

// Create a new Sops instance
const sops = new Sops();

// Encrypt a file
sops.encrypt('secrets.yaml', 'secrets.enc.json');

// Decrypt a file
sops.decrypt('secrets.enc.json', 'secrets.yaml');

// View decrypted content with type safety
interface Secrets {
data: {
api: {
key: string;
secret: string;
};
database: {
username: string;
password: string;
};
};
}

const secrets = sops.view<Secrets>('secrets.enc.json');
console.log(secrets.data.api.key); // TypeScript knows this is a string

// Get a specific value
const apiKey = sops.get('secrets.enc.json', 'data.api.key');
console.log(apiKey);

API Reference

Constructor

new Sops(options?: SopsOptions)

Options:

OptionTypeDescription
keyPathstringPath to the encryption key file (default: .sops-key)

Example:

const sops = new Sops({
keyPath: './config/.custom-key'
});

Methods

initialize

Initializes a new encryption key.

initialize(options?: InitOptions): string

Options:

OptionTypeDescription
forcebooleanOverwrite existing key file if it exists (default: false)
keyPathstringOverride the instance keyPath for this operation

Returns: The generated encryption key as a string.

Example:

try {
const key = sops.initialize();
console.log('Created new key:', key);
} catch (error) {
console.log('Key already exists');
}

// Force overwrite existing key
const newKey = sops.initialize({ force: true });

encrypt

Encrypts a plaintext file containing secrets.

encrypt(inputPath: string, outputPath: string, options?: OperationOptions): void

Options:

OptionTypeDescription
keyPathstringOverride the instance keyPath for this operation

Example:

// Encrypt a YAML file
sops.encrypt('secrets.yaml', 'secrets.enc.json');

// Use a custom key file for this operation
sops.encrypt('secrets.yaml', 'secrets.enc.json', {
keyPath: './special-key'
});

decrypt

Decrypts an encrypted file.

decrypt(inputPath: string, outputPath: string, options?: DecryptOptions): void

Options:

OptionTypeDescription
keyPathstringOverride the instance keyPath for this operation
format'yaml' | 'json'Force output format (default: inferred from output file extension)

Example:

// Decrypt to a YAML file
sops.decrypt('secrets.enc.json', 'secrets.yaml');

// Explicitly specify the output format
sops.decrypt('secrets.enc.json', 'secrets.txt', {
format: 'yaml'
});

view

Reads and decrypts an encrypted file, returning the contents as an object.

view<T = any>(inputPath: string, options?: OperationOptions): T

Options:

OptionTypeDescription
keyPathstringOverride the instance keyPath for this operation

Returns: The decrypted content as an object.

Example:

// View the decrypted content
const secrets = sops.view('secrets.enc.json');
console.log(secrets.data.api.key);

// With TypeScript type safety
interface Config {
data: {
api: { key: string }
}
}
const config = sops.view<Config>('secrets.enc.json');

get

Retrieves a specific value from an encrypted file using a dot-notation path.

get(inputPath: string, dotPath: string, options?: OperationOptions): any

Options:

OptionTypeDescription
keyPathstringOverride the instance keyPath for this operation

Returns: The specific value at the requested path.

Example:

// Get a specific value
const apiKey = sops.get('secrets.enc.json', 'data.api.key');
console.log(apiKey);

// Get a nested value
const dbPassword = sops.get('secrets.enc.json', 'data.database.password');

rotate

Re-encrypts an encrypted file with a new initialization vector.

rotate(inputPath: string, outputPath?: string, options?: OperationOptions): void

Options:

OptionTypeDescription
keyPathstringOverride the instance keyPath for this operation

Example:

// Rotate encryption in place
sops.rotate('secrets.enc.json');

// Rotate to a new file
sops.rotate('secrets.enc.json', 'new-secrets.enc.json');

encryptContent

Encrypts a JavaScript object directly without reading from or writing to files.

encryptContent(content: any, options?: OperationOptions): EncryptedContent

Options:

OptionTypeDescription
keyPathstringOverride the instance keyPath for this operation

Returns: An object containing the encrypted content and metadata.

Example:

const plainContent = {
api: {
key: 'secret_value'
}
};
const encrypted = sops.encryptContent(plainContent);
console.log(encrypted);
// { iv: '...', content: '...', metadata: { ... } }

decryptContent

Decrypts an encrypted content object directly without reading from or writing to files.

decryptContent<T = any>(content: EncryptedContent, options?: OperationOptions): T

Options:

OptionTypeDescription
keyPathstringOverride the instance keyPath for this operation

Returns: The decrypted content as an object.

Example:

const encrypted = sops.encryptContent(plainContent);
const decrypted = sops.decryptContent(encrypted);
console.log(decrypted);
// { api: { key: 'secret_value' } }

Environment Variable Integration

A common pattern is to load secrets from an encrypted file and inject them into environment variables:

const { Sops } = require('node-sops');

function loadSecrets() {
const sops = new Sops();
const secrets = sops.view('secrets.enc.json');

// Add secrets to process.env
Object.entries(secrets.data).forEach(([key, value]) => {
if (typeof value === 'string') {
process.env[key.toUpperCase()] = value;
} else {
Object.entries(value).forEach(([subKey, subValue]) => {
if (typeof subValue === 'string') {
process.env[`${key.toUpperCase()}_${subKey.toUpperCase()}`] = subValue;
}
});
}
});
}

// Call early in your application bootstrap
loadSecrets();

Error Handling

Node SOPS throws descriptive error objects when operations fail. It's a good practice to use try/catch blocks when calling API methods:

try {
const secrets = sops.view('secrets.enc.json');
// Use secrets...
} catch (error) {
console.error('Failed to decrypt secrets:', error.message);
// Handle the error appropriately
}

TypeScript Type Definitions

Node SOPS includes comprehensive TypeScript definitions. The main interfaces are:

interface SopsOptions {
keyPath?: string;
}

interface InitOptions {
force?: boolean;
keyPath?: string;
}

interface OperationOptions {
keyPath?: string;
}

interface DecryptOptions extends OperationOptions {
format?: 'yaml' | 'json';
}

interface EncryptedContent {
iv: string;
content: string;
metadata: {
encryptedAt: string;
version: string;
};
}