Skip to content

Custom Certificates

While rpx can automatically generate SSL certificates, you may want to use your own custom certificates in certain scenarios. This guide shows you how to use custom certificates with rpx.

When to Use Custom Certificates

Custom certificates are useful when:

  • You already have certificates from another system
  • You need to share certificates across multiple tools or systems
  • You have specific certificate requirements not covered by the automatic generation
  • You're working in a corporate environment with specific certificate policies

Using Existing Certificates

To use existing certificates with rpx, specify the paths in your configuration:

ts
import { startProxy } from '@stacksjs/rpx'

startProxy({
  from: 'localhost:3000',
  to: 'myapp.test',
  https: {
    certPath: '/path/to/your/certificate.crt',
    keyPath: '/path/to/your/private.key',
    // Optional CA certificate if you have one
    caCertPath: '/path/to/your/ca.crt'
  }
})

With the CLI:

bash
rpx --from localhost:3000 --to myapp.test --certPath /path/to/your/certificate.crt --keyPath /path/to/your/private.key

Certificate Requirements

Your custom certificates should meet these requirements:

  1. The certificate must be valid for the domain you're using
  2. The private key should be unencrypted (no passphrase)
  3. The certificate should be in PEM format
  4. If using a CA certificate, it should also be in PEM format

Creating Custom Certificates

If you want to create your own certificates instead of using rpx's automatic generation, you can use tools like OpenSSL:

Create a CA Certificate

bash
# Generate a private key for the CA
openssl genrsa -out ca.key 2048

# Create a CA certificate
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt -subj "/C=US/ST=State/L=City/O=Organization/CN=My Custom CA"

Create a Server Certificate

bash
# Generate a private key for the server
openssl genrsa -out server.key 2048

# Create a certificate signing request (CSR)
openssl req -new -key server.key -out server.csr -subj "/C=US/ST=State/L=City/O=Organization/CN=myapp.test"

# Create a config file for subject alternative names
cat > san.cnf <<EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
CN = myapp.test

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = myapp.test
DNS.2 = *.myapp.test
DNS.3 = localhost
IP.1 = 127.0.0.1
EOF

# Sign the CSR with your CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile san.cnf -extensions v3_req

Using mkcert

mkcert is a great tool for creating locally-trusted development certificates. You can use certificates generated by mkcert with rpx:

bash
# Install mkcert
brew install mkcert  # macOS
# or your system's package manager

# Install the local CA in the system trust store
mkcert -install

# Generate certificates for your domains
mkcert myapp.test "*.myapp.test" localhost 127.0.0.1 ::1

# This creates:
# - myapp.test+4.pem (the certificate)
# - myapp.test+4-key.pem (the private key)

Then use these with rpx:

ts
startProxy({
  from: 'localhost:3000',
  to: 'myapp.test',
  https: {
    certPath: './myapp.test+4.pem',
    keyPath: './myapp.test+4-key.pem',
  }
})

Certificate Locations

When using custom certificates, you should:

  1. Store them in a secure location
  2. Ensure the user running rpx has read access to them
  3. Consider excluding them from version control (add to .gitignore)
  4. Back them up if they're important

For development, a common pattern is to store certificates in a certs/ folder in your project:

myproject/
  ├── certs/
  │   ├── ca.crt
  │   ├── server.crt
  │   └── server.key
  ├── src/
  ├── rpx.config.ts
  └── ...

Then reference them in your configuration:

ts
import path from 'node:path'

export default {
  from: 'localhost:3000',
  to: 'myapp.test',
  https: {
    certPath: path.join(__dirname, 'certs', 'server.crt'),
    keyPath: path.join(__dirname, 'certs', 'server.key'),
    caCertPath: path.join(__dirname, 'certs', 'ca.crt'),
  }
}

Released under the MIT License.