platform-tooling/scripts/orchestration/SSL_MANAGEMENT.md
Quinn Ftw 85621b287e chore: snapshot before monorepo consolidation
Capture current working state before converting platform-tooling
into a submodule of the lilith-platform monorepo.
2026-01-29 07:04:39 -08:00

3.6 KiB

SSL Certificate Management

Automated Let's Encrypt SSL certificate management for Lilith Platform production domains.

Overview

The ssl-manager.ts script provides comprehensive SSL certificate management:

  • Certificate Status Checking: Verify existence, validity, and expiration
  • Certificate Requests: Automated Let's Encrypt certificate acquisition
  • Renewal Automation: Smart renewal for certificates expiring within 7 days
  • Validation: Pre-deployment certificate verification
  • Security: No shell injection, domain validation, root requirement checks

Quick Start

# Check all certificate statuses
sudo pnpm tsx infrastructure/scripts/orchestration/ssl-manager.ts check

# Request certificate for a domain
sudo pnpm tsx infrastructure/scripts/orchestration/ssl-manager.ts request atlilith.com

# Renew expiring certificates
sudo pnpm tsx infrastructure/scripts/orchestration/ssl-manager.ts renew

# Validate all certificates (for CI/CD)
sudo pnpm tsx infrastructure/scripts/orchestration/ssl-manager.ts validate

Managed Domains

Domain Aliases Purpose
atlilith.com www.atlilith.com Landing page
sso.atlilith.com - Single Sign-On
admin.atlilith.com - Platform admin
trustedmeet.com www.trustedmeet.com Marketplace
seo.atlilith.com - SEO service
analytics.atlilith.com - Analytics dashboard
profile.atlilith.com - Profile service
status.atlilith.com - Status dashboard

Setup Instructions

1. Install certbot

# Debian/Ubuntu
sudo apt update
sudo apt install certbot

# Fedora
sudo dnf install certbot

2. Create webroot directory

sudo mkdir -p /var/www/certbot
sudo chown -R lilith:lilith /var/www/certbot

3. Configure nginx for ACME challenge

Add to nginx HTTP (port 80) server block:

location /.well-known/acme-challenge/ {
    root /var/www/certbot;
    try_files $uri =404;
}

Reload nginx:

sudo systemctl reload nginx

4. Request initial certificates

for domain in atlilith.com sso.atlilith.com admin.atlilith.com trustedmeet.com seo.atlilith.com analytics.atlilith.com profile.atlilith.com status.atlilith.com; do
  sudo pnpm tsx infrastructure/scripts/orchestration/ssl-manager.ts request $domain
done

5. Setup automatic renewal

Add cron job:

sudo crontab -e

# Add renewal job (runs daily at 3 AM)
0 3 * * * cd /var/www/lilith && pnpm tsx infrastructure/scripts/orchestration/ssl-manager.ts renew
30 3 * * * systemctl reload nginx

API Usage

import {
  checkCertificates,
  requestCertificate,
  renewCertificates,
  getCertificatePath,
  validateCertificates,
} from './ssl-manager.js';

// Get certificate path for nginx generator
const paths = getCertificatePath('atlilith.com');
console.log(paths.fullchainPath); // /etc/letsencrypt/live/atlilith.com/fullchain.pem

// Validate before deployment
const validation = await validateCertificates();
if (!validation.valid) {
  console.error('Certificate validation failed:', validation.errors);
  process.exit(1);
}

Security

  • Domain validation: RFC 1035 regex prevents injection
  • No shell injection: Uses spawnSync with argument arrays (never exec)
  • Root requirement: Checks process.getuid() before certbot execution
  • Minimal environment: Sanitized env vars passed to certbot

Certificate Paths

/etc/letsencrypt/live/atlilith.com/
├── cert.pem       (certificate only)
├── chain.pem      (intermediate CA)
├── fullchain.pem  (cert + chain, for nginx)
└── privkey.pem    (private key)

For nginx use fullchain.pem and privkey.pem.