Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.tenbyte.io/llms.txt

Use this file to discover all available pages before exploring further.

Use a custom certificate when you need EV / OV identity, a wildcard, an internal CA, or a cert your security team manages. You upload PEM-format material and the edge installs it. For free DV certs, use Let’s Encrypt — it auto-renews.

Prerequisites

  • Custom domain CNAMEs to your distribution.
  • Cert files in PEM format:
    • Server certificate (with BEGIN CERTIFICATE / END CERTIFICATE lines).
    • Private key (with BEGIN PRIVATE KEY / END PRIVATE KEY).
    • Intermediate / chain (one or more PEM blocks concatenated).
  • Cert covers the hostname (CN or SAN match).

Validate locally before uploading

# 1. Subject and SANs cover the hostname
openssl x509 -in cert.pem -noout -subject -ext subjectAltName

# 2. Cert and key match
openssl x509 -in cert.pem -noout -modulus | openssl md5
openssl rsa  -in key.pem  -noout -modulus | openssl md5
# both md5 hashes must be identical

# 3. Chain validates
openssl verify -CAfile chain.pem cert.pem
# cert.pem: OK

# 4. Expiry
openssl x509 -in cert.pem -noout -dates
If any step fails, fix locally before uploading — the upload form does the same checks.

Upload via console

1

Click + New Certificate

Add SSL
2

Enter certificate details

Enter Details
FieldValue
LabelInternal name (prod-2026-wildcard). Include year for easy rotation.
CertificatePaste the server cert PEM.
Private KeyPaste the private key PEM.
ChainPaste intermediate certs PEM (root not required).
3

Upload

Upload
Tenbyte validates the cert/key match and chain order. On success, attach the cert to your distribution from the SSL tab.

Upload via API

curl -X POST "https://api.tenbyte.io/cdn/certificates" \
  -H "Authorization: Bearer $TENBYTE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg label    'prod-2026-wildcard' \
    --arg cert     "$(cat cert.pem)" \
    --arg key      "$(cat key.pem)" \
    --arg chain    "$(cat chain.pem)" \
    '{label: $label, certificate: $cert, private_key: $key, chain: $chain}')"
Attach to a distribution:
curl -X PUT "https://api.tenbyte.io/cdn/distributions/$DISTRIBUTION_ID/ssl" \
  -H "Authorization: Bearer $TENBYTE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type": "custom", "certificate_id": "cert_..."}'
See the CDN API reference for canonical fields.

Verify

openssl s_client -connect cdn.yoursite.com:443 -servername cdn.yoursite.com </dev/null \
  2>/dev/null | openssl x509 -noout -subject -issuer -dates
Confirm subject matches your domain and notAfter is the expected date.

Rotation runbook

Custom certs do not auto-renew. You must replace before notAfter.
WhenAction
30 d before expiryCalendar reminder fires. Order / generate new cert.
14 d before expiryUpload new cert via console / API. Do not detach the old one yet.
7 d before expirySwitch the distribution’s SSL config to the new certificate_id. Verify: openssl s_client and SSL Labs.
Immediately afterWatch response classes for unexpected 5xx — rare but possible if the new chain is wrong.
Old cert expiredDelete the old cert from the certificate store.
Never replace a private key on a hot endpoint without a tested rollback. Keep the previous cert + key around for at least one rollback window.

Common formats and conversions

You haveConvert to PEM
.pfx / .p12openssl pkcs12 -in cert.pfx -nodes -out combined.pem, then split into cert / key / chain.
.cer (DER)openssl x509 -inform DER -in cert.cer -out cert.pem
Private key encryptedopenssl rsa -in key.pem -out key.pem (writes unencrypted — handle carefully).
Chain order wrongConcatenate as: leaf → intermediate(s) → (omit root).

Troubleshooting

SymptomFix
Upload rejected — cert/key mismatchThe key doesn’t match this cert. Re-export both from the same source.
Upload rejected — chain incompleteAdd the issuing intermediate(s). Test with openssl verify -CAfile chain.pem cert.pem.
Browser shows NET::ERR_CERT_AUTHORITY_INVALIDChain missing or out of order. Reconcatenate leaf → intermediates.
notAfter already passed at uploadGenerate / order a new cert; you can’t upload an expired one.
Wildcard cert not matching subdomainWildcard covers one level only — *.example.com doesn’t match a.b.example.com. Use a multi-SAN cert.