Local Certificate
Generate or convert a .p12 certificate and configure it for document signing.
Generating a Self-Signed Certificate
Create a self-signed certificate using OpenSSL. These commands work on Linux, macOS, and Windows Subsystem for Linux (WSL).
Create a self-signed certificate
Generate a certificate valid for one year:
openssl req -new -x509 -key private.key -out certificate.crt -days 365When prompted, enter your organisation details:
| Field | Example |
|---|---|
| Country Name | US |
| State or Province | California |
| Locality Name | San Francisco |
| Organization Name | Your Company Inc |
| Organizational Unit | Engineering |
| Common Name | Your Company Signing CA |
| Email Address | admin@example.com |
Create the .p12 certificate
Combine the private key and certificate into a PKCS#12 (.p12) file:
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crtYou must set a password when prompted. Certificates without passwords cause signing failures with the error "Failed to get private key bags".
To set the password non-interactively:
# Set password securely (won't appear in command history)
read -s -p "Enter certificate password: " CERT_PASS
echo
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt \
-password env:CERT_PASSClean up
Remove the intermediate files:
rm private.key certificate.crtKeep certificate.p12 and the password secure.
Using an Existing Certificate
If you have an existing certificate from a CA, convert it to PKCS#12 format.
If you have separate certificate and key files:
openssl pkcs12 -export -out certificate.p12 \
-inkey private.key \
-in certificate.crt \
-certfile chain.crtInclude -certfile chain.crt if you have intermediate certificates.
Convert from DER to PEM first:
openssl x509 -inform DER -in certificate.der -out certificate.crt
openssl rsa -inform DER -in private.der -out private.keyPFX files are the same format as P12. You can use them directly by renaming to .p12.
Certificate Validation
Verify your certificate is valid:
# Check certificate details
openssl pkcs12 -in certificate.p12 -info -nokeys
# Verify password works
openssl pkcs12 -in certificate.p12 -nooutEnvironment Variables
| Variable | Description |
|---|---|
NEXT_PRIVATE_SIGNING_TRANSPORT | Set to local (default) |
NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH | Path to the .p12 certificate file |
NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS | Base64-encoded .p12 file contents (alternative to file path) |
NEXT_PRIVATE_SIGNING_PASSPHRASE | Passphrase for the certificate |
Using File Path
Mount the certificate file and set the path:
NEXT_PRIVATE_SIGNING_TRANSPORT=local
NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12
NEXT_PRIVATE_SIGNING_PASSPHRASE=your-certificate-passwordDocker example:
docker run -d \
-v /path/to/certificate.p12:/opt/documenso/cert.p12:ro \
-e NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12 \
-e NEXT_PRIVATE_SIGNING_PASSPHRASE="your-certificate-password" \
documenso/documenso:latestUsing Base64-Encoded Contents
For environments where file mounting is not available (e.g., Railway, Vercel):
# Encode the certificate
base64 -i certificate.p12Set the encoded string as an environment variable:
NEXT_PRIVATE_SIGNING_TRANSPORT=local
NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS=MIIKEQIBAzCCCdcGCSqGSIb3DQEHAaCCCcg...
NEXT_PRIVATE_SIGNING_PASSPHRASE=your-certificate-passwordThe NEXT_PRIVATE_SIGNING_LOCAL_FILE_CONTENTS variable takes precedence over
NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH if both are set.
Docker File Permissions
When running in Docker, the application runs as user 1001. The certificate file must be readable:
# On the host, before mounting
sudo chown 1001 certificate.p12
chmod 400 certificate.p12Or mount as read-only and ensure group readability:
chmod 440 certificate.p12