DO

documenso-security-basics

Outlines security requirements for Documenso, including secret rotation, environment variable management, and secure webhook verification.

Install

mkdir -p .claude/skills/documenso-security-basics && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/7281" && unzip -o skill.zip -d .claude/skills/documenso-security-basics && rm skill.zip

Installs to .claude/skills/documenso-security-basics

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Implement security best practices for Documenso document signing integrations.
78 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Implement secure API key management using environment variables
  • Configure webhook verification using constant-time comparison
  • Enforce document access control based on ownership
  • Generate self-signed certificates for local development
  • Rotate API keys with zero downtime

How it works

The skill provides protocols for environment-based secret management and constant-time cryptographic verification to prevent timing attacks on webhooks. It also defines procedures for key rotation and document ownership validation.

Inputs & outputs

You give it
API key or webhook request
You get back
Verified secure connection or authorized document access

When to use documenso-security-basics

  • Securing Documenso API keys
  • Implementing secure webhook verification
  • Configuring key rotation for compliance

About this skill

Documenso Security Basics

Overview

Essential security practices for Documenso integrations: API key management, webhook verification, document access control, and self-hosted signing certificate configuration.

Prerequisites

  • Documenso account with API access
  • Understanding of environment variables and secret management
  • Completed documenso-install-auth setup

Instructions

Step 1: API Key Security

// NEVER hardcode keys
const BAD = new Documenso({ apiKey: "api_abc123..." }); // Exposed in source

// ALWAYS use environment variables
const GOOD = new Documenso({ apiKey: process.env.DOCUMENSO_API_KEY! });

Key management rules:

  • Store in .env (never committed) or a secrets manager (Vault, AWS Secrets Manager)
  • Use team-scoped keys for team resources, personal keys for personal documents
  • Rotate keys on employee offboarding -- revoke in dashboard immediately
  • CI/CD: use masked/encrypted secrets (GitHub Secrets, GitLab CI variables)
# .gitignore — always include
.env
.env.*
!.env.example

Step 2: Key Rotation with Zero Downtime

// Support dual keys during rotation
function getApiKey(): string {
  // Try primary first, fall back to secondary during rotation
  return process.env.DOCUMENSO_API_KEY_PRIMARY
    ?? process.env.DOCUMENSO_API_KEY_SECONDARY
    ?? (() => { throw new Error("No Documenso API key configured"); })();
}

// Rotation procedure:
// 1. Generate new key in Documenso dashboard
// 2. Set as DOCUMENSO_API_KEY_SECONDARY, deploy
// 3. Verify secondary key works
// 4. Move secondary to PRIMARY, deploy
// 5. Revoke old key in dashboard

Step 3: Webhook Secret Verification

import { timingSafeEqual } from "crypto";

function verifyWebhookSecret(req: Request): boolean {
  const received = req.headers["x-documenso-secret"] as string;
  const expected = process.env.DOCUMENSO_WEBHOOK_SECRET!;

  if (!received || !expected) return false;

  // Use constant-time comparison to prevent timing attacks
  return timingSafeEqual(
    Buffer.from(received, "utf8"),
    Buffer.from(expected, "utf8")
  );
}
# Python equivalent
import hmac, os
from flask import request

def verify_webhook(req):
    received = req.headers.get("X-Documenso-Secret", "")
    expected = os.environ["DOCUMENSO_WEBHOOK_SECRET"]
    return hmac.compare_digest(received, expected)

Step 4: Document Access Control

// Principle of least privilege with API keys
// Personal keys: only YOUR documents
// Team keys: all documents in the team

// Restrict document access by checking ownership
async function getDocumentSecure(documentId: number, userId: string) {
  const doc = await client.documents.getV0(documentId);

  // Verify the requesting user is the owner or a recipient
  const isOwner = doc.userId === parseInt(userId);
  const isRecipient = doc.recipients?.some(r => r.email === userEmail);

  if (!isOwner && !isRecipient) {
    throw new Error("Access denied: not authorized for this document");
  }

  return doc;
}

Step 5: Signing Certificate Security (Self-Hosted)

Self-hosted Documenso requires a .p12 signing certificate for legally valid digital signatures.

# Generate a self-signed certificate (development only)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
openssl pkcs12 -export -out signing-cert.p12 -inkey key.pem -in cert.pem

# Mount into Docker container
docker run -v $(pwd)/signing-cert.p12:/opt/documenso/cert.p12 \
  -e NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12 \
  -e NEXT_PRIVATE_SIGNING_PASSPHRASE=your-passphrase \
  documenso/documenso:latest

For production, use a certificate from a trusted CA (e.g., GlobalSign, DigiCert).

Step 6: Self-Hosted Production Secrets

# Generate cryptographically secure secrets
openssl rand -hex 32  # NEXTAUTH_SECRET
openssl rand -hex 32  # NEXT_PRIVATE_ENCRYPTION_KEY
openssl rand -hex 32  # NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY

# Never reuse secrets across environments
# Never use default values in production

Security Checklist

  • API key stored in environment variable, never in source code
  • .env in .gitignore
  • CI secrets use masked/encrypted storage
  • Team keys rotated on employee offboarding
  • Webhook secret uses constant-time comparison
  • Self-hosted: HTTPS with valid TLS certificates
  • Self-hosted: signing certificate from trusted CA
  • Self-hosted: secrets generated with openssl rand -hex 32
  • No API keys or secrets in logs (sanitize before logging)
  • Key rotation procedure documented and tested

Error Handling

Security IssueIndicatorResponse
Invalid API key401 errorsRotate key immediately
Webhook spoofingInvalid secret headerReject request, alert team
Key exposed in gitGitHub secret scanning alertRevoke key, rotate, audit access
Brute forceMany 401s from same IPRate limit by IP at reverse proxy

Resources

Next Steps

For production deployment, see documenso-prod-checklist.

When not to use it

  • Hardcoding API keys directly in source code
  • Using default secrets in production environments
  • Reusing secrets across different environments

Prerequisites

Documenso account with API accessUnderstanding of environment variables and secret managementCompleted documenso-install-auth setup

Limitations

  • Requires manual revocation of keys in the dashboard
  • Self-hosted production requires a trusted CA certificate

How it compares

This approach mandates specific security patterns like dual-key rotation and constant-time comparison rather than relying on standard library defaults.

Compared to similar skills

documenso-security-basics side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
documenso-security-basics (this skill)127dReviewIntermediate
file-uploads46moNo flagsAdvanced
graphql66moNo flagsAdvanced
vercel-webhooks-events327dCautionIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

file-uploads

davila7

Expert at handling file uploads and cloud storage. Covers S3, Cloudflare R2, presigned URLs, multipart uploads, and image optimization. Knows how to handle large files without blocking. Use when: file upload, S3, R2, presigned URL, multipart.

438

graphql

davila7

GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.

624

vercel-webhooks-events

jeremylongshore

Implement Vercel webhook signature validation and event handling. Use when setting up webhook endpoints, implementing signature verification, or handling Vercel event notifications securely. Trigger with phrases like "vercel webhook", "vercel events", "vercel webhook signature", "handle vercel events", "vercel notifications".

325

identify-vault-protocol

tradingstrategy-ai

Identify an unknown vault protocol based on its smart contract address

15

exa-policy-guardrails

jeremylongshore

Implement Exa lint rules, policy enforcement, and automated guardrails. Use when setting up code quality rules for Exa integrations, implementing pre-commit hooks, or configuring CI policy checks for Exa best practices. Trigger with phrases like "exa policy", "exa lint", "exa guardrails", "exa best practices check", "exa eslint".

11

openevidence-multi-env-setup

jeremylongshore

Configure OpenEvidence across development, staging, and production environments. Use when setting up multiple environments, managing environment-specific configurations, or implementing environment promotion strategies for clinical AI applications. Trigger with phrases like "openevidence environments", "openevidence staging", "openevidence dev setup", "multi-environment openevidence".

11

Search skills

Search the agent skills registry