Skip to main content

Managing Secrets

This guide covers all CRUD operations for workspace secrets using the Ductape SDK.

Prerequisites

Before managing secrets, ensure you have:

  1. Installed the Ductape SDK
  2. Initialized the SDK with valid credentials
  3. Access to the workspace where you want to manage secrets
import Ductape from '@ductape/sdk';

const ductape = new Ductape({
workspace_id: 'your_workspace_id',
user_id: 'your_user_id',
private_key: 'your_private_key'
});

await ductape.init();

Create a Secret

Create a new encrypted secret in your workspace.

Parameters

FieldTypeRequiredDescriptionExample
keystringYesUnique identifier for the secretSTRIPE_API_KEY
valuestringYesThe secret value (will be encrypted)sk_live_xxx...
descriptionstringNoHuman-readable descriptionProduction Stripe key
token_typestringNoType of token: api or accessapi
scopestring[]NoArray of app tags this secret can be used with['stripe_app', 'pay_app']
envsstring[]NoArray of environment slugs['prd', 'staging']
expires_atnumberNoUnix timestamp for expiration (null = no expiry)1735689600

Example

const secret = await ductape.secrets.create({
key: 'STRIPE_API_KEY',
value: 'sk_live_51ABC123...',
description: 'Production Stripe API key for payment processing',
token_type: 'api',
scope: ['stripe_payments', 'checkout_service'],
envs: ['prd', 'staging'],
expires_at: Math.floor(Date.now() / 1000) + (365 * 24 * 60 * 60) // 1 year from now
});

console.log('Secret created:', secret.key);

Response

{
_id: '507f1f77bcf86cd799439011',
workspace_id: 'ws_123',
key: 'STRIPE_API_KEY',
description: 'Production Stripe API key for payment processing',
token_type: 'api',
scope: ['stripe_payments', 'checkout_service'],
envs: ['prd', 'staging'],
expires_at: 1735689600,
createdAt: '2024-01-15T10:30:00.000Z',
updatedAt: '2024-01-15T10:30:00.000Z'
}

List All Secrets

Retrieve all secrets in your workspace. Note: This returns metadata only, not the encrypted values.

Example

const secrets = await ductape.secrets.fetchAll();

secrets.forEach(secret => {
console.log(`${secret.key}: ${secret.description || 'No description'}`);
console.log(` Type: ${secret.token_type || 'Not specified'}`);
console.log(` Scope: ${secret.scope?.join(', ') || 'All apps'}`);
console.log(` Environments: ${secret.envs?.join(', ') || 'All environments'}`);
});

Response

[
{
_id: '507f1f77bcf86cd799439011',
workspace_id: 'ws_123',
key: 'STRIPE_API_KEY',
description: 'Production Stripe API key',
token_type: 'api',
scope: ['stripe_payments'],
envs: ['prd'],
expires_at: 1735689600,
createdAt: '2024-01-15T10:30:00.000Z',
updatedAt: '2024-01-15T10:30:00.000Z'
},
{
_id: '507f1f77bcf86cd799439012',
workspace_id: 'ws_123',
key: 'SENDGRID_KEY',
description: 'SendGrid API key for emails',
token_type: 'api',
scope: ['email_service'],
envs: ['dev', 'staging', 'prd'],
expires_at: null,
createdAt: '2024-01-10T08:00:00.000Z',
updatedAt: '2024-01-10T08:00:00.000Z'
}
]

Fetch a Single Secret

Retrieve a specific secret including its decrypted value.

Parameters

FieldTypeRequiredDescription
keystringYesThe unique key of the secret

Example

const secret = await ductape.secrets.fetch('STRIPE_API_KEY');

console.log('Key:', secret.key);
console.log('Value:', secret.value); // Decrypted value
console.log('Description:', secret.description);

Response

{
_id: '507f1f77bcf86cd799439011',
workspace_id: 'ws_123',
key: 'STRIPE_API_KEY',
value: 'sk_live_51ABC123...', // Decrypted value
description: 'Production Stripe API key',
token_type: 'api',
scope: ['stripe_payments'],
envs: ['prd'],
expires_at: 1735689600,
createdAt: '2024-01-15T10:30:00.000Z',
updatedAt: '2024-01-15T10:30:00.000Z'
}

Update a Secret

Update an existing secret's value or metadata.

Parameters

FieldTypeRequiredDescription
keystringYesThe key of the secret to update (path parameter)
valuestringNoNew secret value (will be re-encrypted)
descriptionstringNoUpdated description
token_typestringNoUpdated token type
scopestring[]NoUpdated scope array
envsstring[]NoUpdated environments array
expires_atnumberNoUpdated expiration timestamp

Example

// Update the value and extend expiration
const updated = await ductape.secrets.update('STRIPE_API_KEY', {
value: 'sk_live_51NEW_KEY...',
description: 'Rotated Stripe API key - January 2025',
expires_at: Math.floor(Date.now() / 1000) + (180 * 24 * 60 * 60) // 180 days
});

console.log('Secret updated:', updated.key);
console.log('New expiration:', new Date(updated.expires_at * 1000));

Update Metadata Only

// Update scope and environments without changing the value
const updated = await ductape.secrets.update('STRIPE_API_KEY', {
scope: ['stripe_payments', 'subscription_service', 'invoice_service'],
envs: ['dev', 'staging', 'prd']
});

Delete a Secret

Permanently delete a secret from your workspace.

Parameters

FieldTypeRequiredDescription
keystringYesThe key of the secret to delete

Example

const deleted = await ductape.secrets.delete('OLD_API_KEY');

if (deleted) {
console.log('Secret successfully deleted');
}

Revoke a Secret

Revoke a secret to disable it without deleting. The secret remains in your workspace but cannot be used.

Example

const revoked = await ductape.secrets.revoke('COMPROMISED_KEY');

if (revoked) {
console.log('Secret has been revoked');
}

Best Practices

Naming Conventions

Use clear, descriptive names with consistent formatting:

// Good naming
'STRIPE_API_KEY_PROD'
'SENDGRID_API_KEY'
'DB_PASSWORD_STAGING'
'WEBHOOK_SECRET_GITHUB'

// Avoid
'key1'
'api_key'
'secret'

Token Rotation

Set expiration dates and rotate secrets regularly:

// Set 90-day expiration for compliance
const secret = await ductape.secrets.create({
key: 'PCI_COMPLIANT_KEY',
value: 'sensitive_value',
expires_at: Math.floor(Date.now() / 1000) + (90 * 24 * 60 * 60)
});

Scope Restriction

Limit secrets to only the apps that need them:

// Restrict Stripe key to payment-related apps only
const secret = await ductape.secrets.create({
key: 'STRIPE_SECRET',
value: 'sk_live_xxx',
scope: ['payment_processor', 'subscription_handler'],
envs: ['prd'] // Production only
});

Environment Separation

Use different secrets for different environments:

// Development
await ductape.secrets.create({
key: 'STRIPE_KEY_DEV',
value: 'sk_test_xxx',
envs: ['dev']
});

// Production
await ductape.secrets.create({
key: 'STRIPE_KEY_PROD',
value: 'sk_live_xxx',
envs: ['prd']
});

Error Handling

try {
const secret = await ductape.secrets.create({
key: 'MY_SECRET',
value: 'secret_value'
});
} catch (error) {
if (error.response?.status === 409) {
console.error('Secret with this key already exists');
} else if (error.response?.status === 403) {
console.error('You do not have permission to create secrets');
} else {
console.error('Failed to create secret:', error.message);
}
}

Next Steps

  • Using Secrets - Learn how to reference secrets in your integrations
  • Overview - Return to the secrets overview