Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit 8d8cbd9

Browse files
committed
docs: document SSL certificate generation strategy
Add comprehensive documentation explaining why certificates are generated on each deployment rather than reused: - Enhanced deployment documentation with certificate management section - New ADR-006 documenting the architectural decision and rationale - Improved inline code documentation in deploy-app.sh - Updated ADR index with new decision record Key rationale documented: 1. Production flexibility: Different environments use different domains 2. Certificate validity: Self-signed certs must match deployment domain 3. Security: Fresh certificates prevent stale credential reuse 4. Workflow consistency: Same process works across all environments 5. Zero configuration: No certificate store or distribution needed While certificates could be reused for local testing (always test.local), this approach ensures deployment workflow consistency between local testing and production, reducing environment-specific issues. Closes: Discussion about certificate reuse vs regeneration strategy
1 parent 9af19e6 commit 8d8cbd9

File tree

4 files changed

+199
-4
lines changed

4 files changed

+199
-4
lines changed

application/docs/deployment.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,57 @@ If you need to manually deploy on the server:
5353
docker compose --env-file /var/lib/torrust/compose/.env up -d
5454
```
5555

56-
## 3. Verification and Smoke Testing
56+
## 3. SSL Certificate Management
57+
58+
### Certificate Generation Strategy
59+
60+
The deployment process generates SSL certificates on each deployment rather than
61+
reusing certificates. This approach provides several advantages:
62+
63+
#### Why Generate Certificates Per Deployment?
64+
65+
1. **Production Flexibility**: Different environments use different domains:
66+
- Local testing: `test.local`
67+
- Staging: `staging.example.com`
68+
- Production: `tracker.torrust-demo.com`
69+
70+
2. **Certificate Validity**: Self-signed certificates are domain-specific and must
71+
exactly match the domain being used in each deployment environment.
72+
73+
3. **Security Best Practices**: Fresh certificates for each deployment ensure no
74+
stale or leaked credentials are reused.
75+
76+
4. **Workflow Consistency**: The same deployment process works across all
77+
environments without manual certificate management or copying certificates
78+
between systems.
79+
80+
5. **Zero Configuration**: No need to maintain a certificate store or handle
81+
certificate distribution between development and production environments.
82+
83+
#### Certificate Types by Environment
84+
85+
- **Local/Testing**: Self-signed certificates with 10-year validity (for convenience in testing)
86+
- **Production**: Let's Encrypt certificates (automatically renewed)
87+
88+
#### Implementation Details
89+
90+
The certificate generation happens during the application deployment phase
91+
(`make app-deploy`) and includes:
92+
93+
1. **Self-signed certificates**: Generated using OpenSSL with domain-specific
94+
Subject Alternative Names (SAN)
95+
2. **Certificate placement**: Stored in `/var/lib/torrust/proxy/certs/` and
96+
`/var/lib/torrust/proxy/private/` on the target server
97+
3. **Container mounting**: Certificates are mounted into nginx container at runtime
98+
4. **Automatic configuration**: nginx configuration is automatically templated
99+
with the correct certificate paths
100+
101+
While it would be possible to reuse certificates for local testing (since we
102+
always use `test.local`), this approach ensures that the deployment workflow is
103+
identical between local testing and production, reducing the chance of
104+
environment-specific issues.
105+
106+
## 4. Verification and Smoke Testing
57107

58108
After deployment, verify that all services are running correctly.
59109

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# ADR-006: SSL Certificate Generation Strategy
2+
3+
## Status
4+
5+
Accepted
6+
7+
## Context
8+
9+
During the implementation of HTTPS support for the Torrust Tracker Demo, we
10+
needed to decide between two approaches for SSL certificate management:
11+
12+
1. **Generate certificates on each deployment** - Create fresh certificates during each deployment process
13+
2. **Reuse certificates across deployments** - Generate certificates once and copy them between deployments
14+
15+
For local testing environments, we consistently use the same domain (`test.local`),
16+
which means certificates could technically be reused. However, for production
17+
environments, different domains are used for different deployment targets.
18+
19+
## Decision
20+
21+
We will **generate SSL certificates on each deployment** rather than reusing
22+
certificates across deployments.
23+
24+
## Rationale
25+
26+
### 1. Production Flexibility
27+
28+
Different environments use different domains:
29+
30+
- Local testing: `test.local`
31+
- Staging environments: `staging.example.com`
32+
- Production: `tracker.torrust-demo.com`
33+
34+
Certificates must match the exact domain being used in each environment.
35+
36+
### 2. Certificate Validity
37+
38+
Self-signed certificates are domain-specific and must exactly match the domain
39+
being used in each deployment environment. Reusing certificates would require
40+
maintaining separate certificate sets for each domain or would fail certificate
41+
validation.
42+
43+
### 3. Security Best Practices
44+
45+
Fresh certificates for each deployment ensure:
46+
47+
- No stale or leaked credentials are reused
48+
- Certificates are generated with current system time
49+
- No cross-environment certificate contamination
50+
51+
### 4. Workflow Consistency
52+
53+
The same deployment process works across all environments without:
54+
55+
- Manual certificate management
56+
- Certificate copying between systems
57+
- Environment-specific deployment procedures
58+
- Certificate store maintenance
59+
60+
### 5. Zero Configuration
61+
62+
This approach requires no additional infrastructure:
63+
64+
- No certificate distribution system
65+
- No certificate storage requirements
66+
- No manual certificate rotation procedures
67+
68+
## Implementation
69+
70+
Certificate generation happens during the application deployment phase (`make app-deploy`):
71+
72+
1. **Self-signed certificates**: Generated using OpenSSL with domain-specific
73+
Subject Alternative Names (SAN)
74+
2. **Certificate placement**: Stored in `/var/lib/torrust/proxy/certs/` and
75+
`/var/lib/torrust/proxy/private/` on the target server
76+
3. **Container mounting**: Certificates are mounted into nginx container at runtime
77+
4. **Automatic configuration**: nginx configuration is automatically templated
78+
with the correct certificate paths
79+
80+
## Consequences
81+
82+
### Positive
83+
84+
- ✅ Identical deployment workflow between local testing and production
85+
- ✅ No certificate management overhead
86+
- ✅ Domain-specific certificates always match deployment target
87+
- ✅ Enhanced security through fresh certificates
88+
- ✅ Simplified deployment automation
89+
90+
### Negative
91+
92+
- ❌ Slight deployment time increase (certificate generation takes ~2-3 seconds)
93+
- ❌ Cannot preserve certificate fingerprints across deployments
94+
- ❌ Requires certificate regeneration for each deployment (even if domain unchanged)
95+
96+
### Neutral
97+
98+
- 🔄 For local testing, certificates are regenerated even though domain remains `test.local`
99+
- 🔄 Certificate validity period is reset on each deployment (10 years for self-signed)
100+
101+
## Alternatives Considered
102+
103+
### Certificate Reuse Strategy
104+
105+
We considered implementing certificate reuse for local testing:
106+
107+
1. Generate certificates once and store them locally
108+
2. Copy stored certificates to VM during deployment
109+
3. Use fresh generation only for production deployments
110+
111+
**Rejected because:**
112+
113+
- Creates environment-specific deployment logic
114+
- Increases complexity for minimal time savings
115+
- Introduces certificate management overhead
116+
- Reduces consistency between local and production workflows
117+
118+
## Related Decisions
119+
120+
- [ADR-004: Configuration Approach Files vs Environment Variables]
121+
(004-configuration-approach-files-vs-environment-variables.md) -
122+
Template-based configuration approach
123+
- [ADR-002: Docker for All Services](002-docker-for-all-services.md) -
124+
Container-based service architecture
125+
126+
## References
127+
128+
- [SSL Certificate Management Documentation](../application/docs/deployment.md#ssl-certificate-management)
129+
- [Deployment Script Implementation](../infrastructure/scripts/deploy-app.sh)
130+
- [Certificate Generation Script](../application/share/bin/ssl-generate-test-certs.sh)

docs/adr/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,15 @@ These are separate infrastructure concerns and should be documented separately:
132132
- [ADR-005: Sudo Cache Management for Infrastructure Operations]
133133
(005-sudo-cache-management-for-infrastructure-operations.md) -
134134
Proactive sudo cache management for better UX during testing
135+
- [ADR-006: SSL Certificate Generation Strategy]
136+
(006-ssl-certificate-generation-strategy.md) -
137+
Generate certificates per deployment vs reusing certificates
135138

136139
### 📊 ADR Statistics
137140

138-
- **Total ADRs**: 5
141+
- **Total ADRs**: 6
139142
- **Status**: All Accepted
140-
- **Coverage**: Infrastructure (3), Application (1), Development Workflow (1)
143+
- **Coverage**: Infrastructure (3), Application (2), Development Workflow (1)
141144

142145
## Contributing
143146

infrastructure/scripts/deploy-app.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,23 @@ generate_nginx_https_selfsigned_config() {
400400
}
401401

402402
# Generate self-signed SSL certificates on the VM
403+
#
404+
# Why we generate certificates on each deployment:
405+
# 1. Production flexibility: Different environments use different domains
406+
# (test.local for local testing, actual domain for production)
407+
# 2. Certificate validity: Self-signed certs are domain-specific and must match
408+
# the actual domain being used in each deployment
409+
# 3. Security: Fresh certificates for each deployment ensure no stale credentials
410+
# 4. Portability: Works across different deployment targets without manual
411+
# certificate management or copying between environments
412+
#
413+
# While we could reuse certificates for local testing (always test.local),
414+
# this approach ensures consistency with production deployment workflows.
403415
generate_selfsigned_certificates() {
404416
local vm_ip="$1"
405417
local domain_name="${DOMAIN_NAME:-test.local}"
406418

407-
log_info "Generating self-signed SSL certificates on VM..."
419+
log_info "Generating self-signed SSL certificates on VM for domain: ${domain_name}..."
408420

409421
# Copy the certificate generation script to VM
410422
local cert_script="${PROJECT_ROOT}/application/share/bin/ssl-generate-test-certs.sh"

0 commit comments

Comments
 (0)