0
# SSL Certificate Management
1
2
Automated SSL certificate provisioning using Let's Encrypt ACME protocol for securing deployed applications with HTTPS. This capability enables automatic SSL certificate generation, renewal, and domain configuration for serverless applications.
3
4
## Capabilities
5
6
### Certificate Provisioning
7
8
Main certificate generation and domain update functionality.
9
10
```python { .api }
11
def get_cert_and_update_domain(**kwargs):
12
"""
13
Main function to obtain SSL certificate and update domain.
14
15
Orchestrates the complete SSL certificate provisioning process
16
including domain validation, certificate generation, and AWS configuration.
17
18
Parameters:
19
- domain: str, domain name for certificate
20
- email: str, contact email for Let's Encrypt
21
- certificate_arn: str, existing certificate ARN to update
22
- route53_hosted_zone_id: str, Route53 hosted zone ID
23
- aws_region: str, AWS region for certificate
24
- **kwargs: Additional configuration options
25
26
Returns:
27
dict: Certificate information and ARN
28
"""
29
```
30
31
### Certificate Generation
32
33
Core certificate creation using Let's Encrypt ACME protocol.
34
35
```python { .api }
36
def get_cert(
37
domain,
38
email,
39
account_key_path=None,
40
domain_key_path=None,
41
ca=None,
42
**kwargs
43
):
44
"""
45
Obtain SSL certificate from Let's Encrypt ACME CA.
46
47
Performs domain ownership validation and requests certificate
48
from Let's Encrypt Certificate Authority.
49
50
Parameters:
51
- domain: str, domain name for certificate
52
- email: str, contact email address
53
- account_key_path: str, path to ACME account key file
54
- domain_key_path: str, path to domain private key file
55
- ca: str, Certificate Authority URL
56
- **kwargs: Additional ACME configuration
57
58
Returns:
59
dict: Certificate data and metadata
60
"""
61
```
62
63
### Key and CSR Management
64
65
Generate cryptographic keys and certificate signing requests.
66
67
```python { .api }
68
def create_domain_key(key_path=None, key_size=2048):
69
"""
70
Create RSA private key for domain certificate.
71
72
Generates RSA private key for SSL certificate with
73
specified key size and saves to file.
74
75
Parameters:
76
- key_path: str, path to save private key file
77
- key_size: int, RSA key size in bits (default 2048)
78
79
Returns:
80
str: Path to generated private key file
81
"""
82
```
83
84
```python { .api }
85
def create_domain_csr(domain, key_path, csr_path=None, **kwargs):
86
"""
87
Create certificate signing request for domain.
88
89
Generates CSR using domain private key with proper
90
subject and extensions for SSL certificate.
91
92
Parameters:
93
- domain: str, domain name for certificate
94
- key_path: str, path to domain private key
95
- csr_path: str, path to save CSR file
96
- **kwargs: Additional CSR configuration
97
98
Returns:
99
str: Path to generated CSR file
100
"""
101
```
102
103
### Certificate Processing
104
105
Process and format certificates for deployment.
106
107
```python { .api }
108
def create_chained_certificate(cert_path, chain_path=None):
109
"""
110
Create full certificate chain for deployment.
111
112
Combines domain certificate with intermediate certificates
113
to create complete certificate chain for SSL.
114
115
Parameters:
116
- cert_path: str, path to domain certificate file
117
- chain_path: str, path to certificate chain file
118
119
Returns:
120
str: Full certificate chain content
121
"""
122
```
123
124
```python { .api }
125
def encode_certificate(cert_content):
126
"""
127
Encode certificate for AWS usage.
128
129
Formats certificate content for AWS Certificate Manager
130
or other AWS services requiring specific encoding.
131
132
Parameters:
133
- cert_content: str, certificate content to encode
134
135
Returns:
136
str: Encoded certificate content
137
"""
138
```
139
140
### ACME Protocol Support
141
142
Handle ACME protocol interactions with Certificate Authority.
143
144
```python { .api }
145
def verify_challenge(challenge_url, challenge_content):
146
"""
147
Verify ACME domain ownership challenge.
148
149
Validates that domain challenge file is properly accessible
150
at the expected URL for domain ownership verification.
151
152
Parameters:
153
- challenge_url: str, URL to challenge file
154
- challenge_content: str, expected challenge content
155
156
Returns:
157
bool: True if challenge verification successful
158
"""
159
```
160
161
```python { .api }
162
def sign_certificate(csr_path, ca_url, account_key, **kwargs):
163
"""
164
Sign certificate with Certificate Authority.
165
166
Submits CSR to CA for signing and retrieves signed
167
certificate after domain validation.
168
169
Parameters:
170
- csr_path: str, path to certificate signing request
171
- ca_url: str, Certificate Authority URL
172
- account_key: str, ACME account private key
173
- **kwargs: Additional signing configuration
174
175
Returns:
176
str: Signed certificate content
177
"""
178
```
179
180
### Account and Key Management
181
182
Manage ACME account registration and key parsing.
183
184
```python { .api }
185
def register_account(email, account_key, ca_url):
186
"""
187
Register new account with ACME Certificate Authority.
188
189
Creates new account with Let's Encrypt using email
190
and account private key for future certificate requests.
191
192
Parameters:
193
- email: str, contact email address
194
- account_key: str, ACME account private key
195
- ca_url: str, Certificate Authority URL
196
197
Returns:
198
dict: Account registration information
199
"""
200
```
201
202
```python { .api }
203
def parse_account_key(key_content):
204
"""
205
Parse ACME account private key.
206
207
Parses and validates ACME account key format
208
for use in certificate requests.
209
210
Parameters:
211
- key_content: str, account private key content
212
213
Returns:
214
dict: Parsed key information
215
"""
216
```
217
218
```python { .api }
219
def parse_csr(csr_content):
220
"""
221
Parse certificate signing request data.
222
223
Extracts and validates information from CSR
224
including domain names and key information.
225
226
Parameters:
227
- csr_content: str, CSR content to parse
228
229
Returns:
230
dict: Parsed CSR information
231
"""
232
```
233
234
### File System Support
235
236
Temporary directory management for certificate operations.
237
238
```python { .api }
239
def gettempdir():
240
"""
241
Get temporary directory for certificate operations.
242
243
Returns appropriate temporary directory path for
244
storing certificate files during generation process.
245
246
Returns:
247
str: Temporary directory path
248
"""
249
```
250
251
## Constants
252
253
```python { .api }
254
# Default Certificate Authority URL (Let's Encrypt production)
255
DEFAULT_CA = "https://acme-v02.api.letsencrypt.org/directory"
256
```
257
258
## Usage Examples
259
260
### Basic Certificate Generation
261
262
```python
263
from zappa.letsencrypt import get_cert_and_update_domain
264
265
# Generate certificate for domain
266
cert_info = get_cert_and_update_domain(
267
domain='api.myapp.com',
268
email='admin@myapp.com',
269
route53_hosted_zone_id='Z123456789',
270
aws_region='us-east-1'
271
)
272
273
print(f"Certificate ARN: {cert_info['certificate_arn']}")
274
```
275
276
### Manual Certificate Process
277
278
```python
279
from zappa.letsencrypt import (
280
create_domain_key,
281
create_domain_csr,
282
get_cert,
283
create_chained_certificate
284
)
285
286
# Generate domain private key
287
key_path = create_domain_key('domain.key', key_size=2048)
288
289
# Create certificate signing request
290
csr_path = create_domain_csr(
291
domain='myapp.com',
292
key_path=key_path,
293
csr_path='domain.csr'
294
)
295
296
# Get certificate from Let's Encrypt
297
cert_data = get_cert(
298
domain='myapp.com',
299
email='admin@myapp.com',
300
domain_key_path=key_path
301
)
302
303
# Create full certificate chain
304
full_chain = create_chained_certificate(cert_data['cert_path'])
305
```
306
307
### Account Registration
308
309
```python
310
from zappa.letsencrypt import register_account, parse_account_key
311
312
# Register account with Let's Encrypt
313
account_key_content = """-----BEGIN RSA PRIVATE KEY-----
314
MIIEpAIBAAKCAQEA...
315
-----END RSA PRIVATE KEY-----"""
316
317
account_info = register_account(
318
email='certificates@myapp.com',
319
account_key=account_key_content,
320
ca_url='https://acme-v02.api.letsencrypt.org/directory'
321
)
322
323
print(f"Account registered: {account_info['status']}")
324
```
325
326
### Certificate Validation
327
328
```python
329
from zappa.letsencrypt import verify_challenge
330
331
# Verify domain ownership challenge
332
challenge_verified = verify_challenge(
333
challenge_url='http://myapp.com/.well-known/acme-challenge/token123',
334
challenge_content='token123.signature456'
335
)
336
337
if challenge_verified:
338
print("Domain ownership verified successfully")
339
else:
340
print("Challenge verification failed")
341
```
342
343
### Custom CA Configuration
344
345
```python
346
from zappa.letsencrypt import get_cert
347
348
# Use Let's Encrypt staging environment for testing
349
staging_ca = "https://acme-staging-v02.api.letsencrypt.org/directory"
350
351
cert_data = get_cert(
352
domain='test.myapp.com',
353
email='test@myapp.com',
354
ca=staging_ca
355
)
356
357
print(f"Test certificate obtained: {cert_data['cert_path']}")
358
```
359
360
### Certificate Chain Processing
361
362
```python
363
from zappa.letsencrypt import create_chained_certificate, encode_certificate
364
365
# Create certificate chain
366
cert_chain = create_chained_certificate(
367
cert_path='domain.crt',
368
chain_path='chain.crt'
369
)
370
371
# Encode for AWS
372
encoded_cert = encode_certificate(cert_chain)
373
374
# Use with AWS Certificate Manager
375
import boto3
376
acm = boto3.client('acm', region_name='us-east-1')
377
378
response = acm.import_certificate(
379
Certificate=encoded_cert,
380
PrivateKey=open('domain.key').read(),
381
CertificateChain=cert_chain
382
)
383
384
print(f"Certificate imported: {response['CertificateArn']}")
385
```
386
387
### Automated Renewal Setup
388
389
```python
390
from zappa.letsencrypt import get_cert_and_update_domain
391
from zappa.asynchronous import task
392
393
@task
394
def renew_certificate(domain, email, cert_arn):
395
"""Async certificate renewal task."""
396
try:
397
new_cert = get_cert_and_update_domain(
398
domain=domain,
399
email=email,
400
certificate_arn=cert_arn,
401
renew=True
402
)
403
return f"Certificate renewed: {new_cert['certificate_arn']}"
404
except Exception as e:
405
return f"Renewal failed: {str(e)}"
406
407
# Schedule certificate renewal
408
renewal_response = renew_certificate(
409
domain='api.myapp.com',
410
email='admin@myapp.com',
411
cert_arn='arn:aws:acm:us-east-1:123456789012:certificate/abc123'
412
)
413
```