{"result":{"depiction_url":null,"edges":{"observes":{"objects":[{"created":"2026-09-09T13:47:43Z","object_id":{"id":2009,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_ssl_options","title":"observe_ssl_options\/2","uri":"https:\/\/zotonic.com\/id\/2009"},"seq":1}],"predicate":{"id":2550,"is_a":["meta","predicate"],"name":"observes","title":{"_type":"trans","tr":{"en":"Observes"}},"uri":"https:\/\/zotonic.com\/id\/observes"}},"references":{"objects":[{"created":"2020-05-30T05:47:48Z","object_id":{"id":1754,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_ssl_letsencrypt","title":"mod_ssl_letsencrypt","uri":"https:\/\/zotonic.com\/id\/1754"},"seq":1000000}],"predicate":{"id":332,"is_a":["meta","predicate"],"name":"references","title":{"_type":"trans","tr":{"en":"References"}},"uri":"https:\/\/zotonic.com\/id\/references"}},"refers":{"objects":[{"created":"2026-09-09T13:47:43Z","object_id":{"id":1754,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_ssl_letsencrypt","title":"mod_ssl_letsencrypt","uri":"https:\/\/zotonic.com\/id\/1754"},"seq":1000000}],"predicate":{"id":2409,"is_a":["meta","predicate"],"name":"refers","title":{"_type":"trans","tr":{"en":"Refers"}},"uri":"https:\/\/zotonic.com\/id\/refers"}},"relation":{"objects":[{"created":"2020-05-30T05:47:48Z","object_id":{"id":1754,"is_a":["text","documentation","reference","module"],"name":"doc_module_mod_ssl_letsencrypt","title":"mod_ssl_letsencrypt","uri":"https:\/\/zotonic.com\/id\/1754"},"seq":1000000},{"created":"2020-05-30T05:47:48Z","object_id":{"id":1482,"is_a":["text","documentation","reference"],"name":"doc_developerguide_configuration_port_ssl_configuration","title":"Port configurations","uri":"https:\/\/zotonic.com\/id\/1482"},"seq":1000000}],"predicate":{"id":303,"is_a":["meta","predicate"],"name":"relation","title":{"_type":"trans","tr":{"nl":"Relatie","en":"Relation"}},"uri":"http:\/\/purl.org\/dc\/terms\/relation"}},"subject":{"objects":[{"created":"2026-09-09T13:47:43Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-09-09T13:47:43Z","object_id":{"id":2566,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_operator","title":"Operator","uri":"https:\/\/zotonic.com\/id\/2566"},"seq":2},{"created":"2026-09-09T13:47:43Z","object_id":{"id":2635,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_module","title":"Module","uri":"https:\/\/zotonic.com\/id\/2635"},"seq":3},{"created":"2026-09-09T13:47:43Z","object_id":{"id":2636,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_configure","title":"Configure","uri":"https:\/\/zotonic.com\/id\/2636"},"seq":4},{"created":"2026-09-09T13:47:43Z","object_id":{"id":2682,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_tls_and_certificates","title":"TLS and certificates","uri":"https:\/\/zotonic.com\/id\/2682"},"seq":5},{"created":"2026-09-09T13:47:43Z","object_id":{"id":2685,"is_a":["categorization","keyword","keyword_quality"],"name":"zotonic_topic_security","title":"Security","uri":"https:\/\/zotonic.com\/id\/2685"},"seq":6}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":1753,"is_a":["text","documentation","reference","module"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1753"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_module_mod_ssl_ca","page_url":{"en":"https:\/\/zotonic.com\/docs\/1753\/mod_ssl_ca","x-default":"https:\/\/zotonic.com\/docs\/1753\/mod_ssl_ca"},"preview_url":null,"resource":{"version":3346,"pivot_location_lat":null,"title":"mod_ssl_ca","is_authoritative":true,"body":"<p>The mod_ssl_ca module adds support for using SSL certificates bought from a Certificate Authority.<\/p>\n<p>A free alternative to CA provided tickets is Let’s Encrypt, see <a href=\"\/id\/doc_module_mod_ssl_letsencrypt\" class=\"doc-reference doc-reference-module\"><code>module#mod_ssl_letsencrypt<\/code><\/a>.<\/p>\n<h2>Certificate and key files<\/h2>\n<p>The certificate and key files are placed into the site sub-directory of the security directory. The subdirectory will\nbe: <code>sitename\/ca\/<\/code><\/p>\n<p>Where <em>sitename<\/em> must be replaced with the name of your site.<\/p>\n<p>The security directory can be found by inspecting the output of:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">bin\/zotonic config\n<\/code><\/pre>\n<p>The Zotonic <em>security<\/em> directory can be in one of the following directories:<\/p>\n<ul><li>The environment variable <code>ZOTONIC_SECURITY_DIR<\/code><\/li><li>The <code>~\/.zotonic\/security<\/code> directory<\/li><li>The <code>\/etc\/zotonic\/security<\/code> directory (only on Linux)<\/li><li>The OS specific directory for application data files<\/li><\/ul>\n<p>The OS specific directories are:<\/p>\n<ul><li>On Unix: <code>~\/.config\/zotonic\/security\/<\/code><\/li><li>On macOS: <code>~\/Library\/Application Support\/zotonic\/security\/<\/code><\/li><\/ul>\n<p>The default is the OS specific directory.<\/p>\n<p>If there is a directory <code>priv\/security\/ca<\/code> inside your site’s OTP application folder then that directory will be used.<\/p>\n<p>The filenames are checked against their extension. When you copy your files to the <code>ca<\/code> directory then you need to\nensure that they have the right extensions.<\/p>\n<p>The following file extensions are expected:<\/p>\n<p><code>*.pem<\/code> or <code>*.key<\/code><\/p>\n<p>This holds the private key for the encryption. The key must be unlocked and in PKCS#1 format (see below).<\/p>\n<p><code>*.crt<\/code><\/p>\n<p>This is the certificate. Usually it is supplied by the certificate authority where you bought it. It can also be a self\nsigned certificate, see below.<\/p>\n<p><code>*.ca.crt<\/code>, <code>cabundle.crt<\/code> or <code>bundle.crt<\/code><\/p>\n<p>This is the (optional) <em>CA bundle<\/em> that contains root and intermediate certificates for the certificate authority that\nissued the <code>.crt<\/code> certificate.<\/p>\n<p>The certificate authority will supply these. All supplied certificates are concatenated, with the root certificate last.<\/p>\n<p>The concatenation is a literal command, like:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-bash\">cat intermediate.crt root.crt &gt; cabundle.crt\n<\/code><\/pre>\n<p>Due to caching, it can take up to a minute before the new certificates are used.<\/p>\n<h2>Format of the private key<\/h2>\n<p>The Erlang SSL implementation accepts PKCS#1 and PKCS#8 format keys. OpenSSL generates (since 2010) PKCS#8 format keys.<\/p>\n<p>A PKCS#1 key starts with:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-none\">-----BEGIN RSA PRIVATE KEY-----\n<\/code><\/pre>\n<p>A PKCS#8 key starts with:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-none\">-----BEGIN PRIVATE KEY-----\n<\/code><\/pre>\n<p>If there are problems then check if the <code>.key<\/code> or <code>.pem<\/code> file starts with one of the above strings.<\/p>\n<h2>Using SSL certificates<\/h2>\n<p>If you order a SSL certificate, the signing authority will ask you which kind of web server you are using and a CSR\nfile. For the web server, select <em>other<\/em>. For the CSR, use the following command:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-bash\">openssl req -out certificate.csr -new -newkey rsa:2048 -nodes -keyout certificate.key\n<\/code><\/pre>\n<p>When OpenSSL asks for the <em>Common Name<\/em> then fill in the site’s hostname (e.g. *<a href=\"http:\/\/www.example.com*)\">www.example.com*)<\/a>.<\/p>\n<p>From the SSL certificate authority you will receive a signed <code>.crt<\/code> file and maybe a <code>cabundle.crt<\/code> file.<\/p>\n<p>See the section <em>Certificate and key files<\/em> above for instructions how to use the <code>.crt<\/code> and <code>.key<\/code> files.<\/p>\n<h2>Generating a self signed certificate<\/h2>\n<p>There is no need to make your own self signed certificate as Zotonic will generate one for every site.<\/p>\n<p>Nevertheless, if you want to use your own self signed certificate, then run the following commmands:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-bash\">openssl req -x509 -nodes -days 3650 -subj &#39;\/CN=www.example.com&#39; -newkey rsa:2048 \\\n     -keyout certificate.key -out certificate.crt\n<\/code><\/pre>\n<p>This generates a private key of 2048 bits and a certificate that is valid for 10 years.<\/p>\n<h2>Accepted Events<\/h2>\n<p>This module handles the following notifier callbacks:<\/p>\n<ul><li><code>observe_ssl_options<\/code>: Return the certificates of this site using <code>z_depcache:memo<\/code>.<\/li><\/ul>","slug":"mod_ssl_ca","doc_module_config":[],"is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"7d7a0b516513a35d749fad17f5a78bd623fa147e844e3dfc6f94be01242c8dd7","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"category_id":{"id":320,"is_a":["meta","category"],"name":"module","title":"Modules","uri":"https:\/\/test.zotonic.com\/id\/320"},"doc_source_path":"apps\/zotonic_mod_ssl_ca\/src\/mod_ssl_ca.erl","publication_start":"2023-01-30T19:24:02Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_mod_ssl_ca\/src\/mod_ssl_ca.erl","pivot_location_lng":null,"doc_source_kind":"module","name":"doc_module_mod_ssl_ca","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:33Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_mod_ssl_ca","publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"652b4eddf9263041a2798f290b6c867343988a3f\n","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-06T13:25:05Z","title_slug":"mod_ssl_ca"},"uri":"https:\/\/zotonic.com\/id\/1753","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1753"}},"status":"ok"}