{"_id":"@expo/devcert","_rev":"4296237","name":"@expo/devcert","description":"Generate trusted local SSL/TLS certificates for local SSL development","dist-tags":{"latest":"1.2.1"},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"time":{"modified":"2026-04-07T20:58:54.000Z","created":"2021-02-02T07:50:18.027Z","1.2.1":"2025-12-05T06:00:06.353Z","1.2.0":"2025-04-08T10:43:07.278Z","1.1.4":"2024-08-07T20:18:14.179Z","1.1.2":"2024-05-16T19:12:34.952Z","1.1.1":"2024-05-16T16:16:16.414Z","1.1.0":"2022-11-08T23:04:41.120Z","1.0.0":"2021-02-02T07:50:18.027Z"},"users":{},"author":{"name":"Dave Wasmer"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"versions":{"1.2.1":{"name":"@expo/devcert","version":"1.2.1","description":"Generate trusted local SSL/TLS certificates for local SSL development","main":"dist/index.js","types":"dist/index.d.ts","private":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"echo \"Ha.\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"keywords":["ssl","certificate","openssl","trust"],"author":{"name":"Dave Wasmer"},"license":"MIT","bugs":{"url":"https://github.com/expo/devcert/issues"},"homepage":"https://github.com/expo/devcert#readme","devDependencies":{"@types/debug":"^0.0.30","@types/node":"^20.12.7","standard-version":"^8.0.1","typescript":"^5.1.3"},"dependencies":{"@expo/sudo-prompt":"^9.3.1","debug":"^3.1.0"},"_id":"@expo/devcert@1.2.1","gitHead":"7c2befac5a81d9b6263e9a7d11733e8d68132c58","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"shasum":"1a687985bea1670866e54d5ba7c0ced963c354f4","size":68082,"noattachment":false,"key":"/@expo/devcert/-/@expo/devcert-1.2.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/@expo/devcert/download/@expo/devcert-1.2.1.tgz"},"_npmUser":{"name":"kudochien","email":"ckchien@gmail.com"},"directories":{},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/devcert_1.2.1_1764914406196_0.7137077968498851"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-12-05T06:00:06.353Z","publish_time":1764914406353,"_source_registry_name":"default","_cnpm_publish_time":1764914406353},"1.2.0":{"name":"@expo/devcert","version":"1.2.0","description":"Generate trusted local SSL/TLS certificates for local SSL development","main":"dist/index.js","types":"dist/index.d.ts","private":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"echo \"Ha.\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"keywords":["ssl","certificate","openssl","trust"],"author":{"name":"Dave Wasmer"},"license":"MIT","bugs":{"url":"https://github.com/expo/devcert/issues"},"homepage":"https://github.com/expo/devcert#readme","devDependencies":{"@types/debug":"^0.0.30","@types/node":"^20.12.7","standard-version":"^8.0.1","typescript":"^5.1.3"},"dependencies":{"@expo/sudo-prompt":"^9.3.1","debug":"^3.1.0","glob":"^10.4.2"},"_id":"@expo/devcert@1.2.0","dist":{"shasum":"7b32c2d959e36baaa0649433395e5170c808b44f","size":68058,"noattachment":false,"key":"/@expo/devcert/-/@expo/devcert-1.2.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/@expo/devcert/download/@expo/devcert-1.2.0.tgz"},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/devcert_1.2.0_1744108987091_0.720897617909207"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-04-08T10:43:07.278Z","publish_time":1744108987278,"_source_registry_name":"default","_cnpm_publish_time":1744108987278},"1.1.4":{"name":"@expo/devcert","version":"1.1.4","description":"Generate trusted local SSL/TLS certificates for local SSL development","main":"dist/index.js","types":"dist/index.d.ts","private":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"echo \"Ha.\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"keywords":["ssl","certificate","openssl","trust"],"author":{"name":"Dave Wasmer"},"license":"MIT","bugs":{"url":"https://github.com/expo/devcert/issues"},"homepage":"https://github.com/expo/devcert#readme","devDependencies":{"@types/debug":"^0.0.30","@types/get-port":"^3.2.0","@types/lodash":"^4.14.92","@types/mkdirp":"^0.5.2","@types/node":"^20.12.7","@types/tmp":"^0.0.33","standard-version":"^8.0.1","typescript":"^5.1.3"},"dependencies":{"application-config-path":"^0.1.0","command-exists":"^1.2.4","debug":"^3.1.0","eol":"^0.9.1","get-port":"^3.2.0","glob":"^10.4.2","lodash":"^4.17.21","mkdirp":"^0.5.1","password-prompt":"^1.0.4","sudo-prompt":"^8.2.0","tmp":"^0.0.33","tslib":"^2.4.0"},"_id":"@expo/devcert@1.1.4","dist":{"shasum":"d98807802a541847cc42791a606bfdc26e641277","size":64996,"noattachment":false,"key":"/@expo/devcert/-/@expo/devcert-1.1.4.tgz","tarball":"http://registry.cnpm.dingdandao.com/@expo/devcert/download/@expo/devcert-1.1.4.tgz"},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/devcert_1.1.4_1723061893876_0.8891326380286242"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-08-07T20:18:14.179Z","publish_time":1723061894179,"_source_registry_name":"default","_cnpm_publish_time":1723061894179},"1.1.2":{"name":"@expo/devcert","version":"1.1.2","description":"Generate trusted local SSL/TLS certificates for local SSL development","main":"dist/index.js","types":"dist/index.d.ts","private":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"echo \"Ha.\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"keywords":["ssl","certificate","openssl","trust"],"author":{"name":"Dave Wasmer"},"license":"MIT","bugs":{"url":"https://github.com/expo/devcert/issues"},"homepage":"https://github.com/expo/devcert#readme","devDependencies":{"@types/debug":"^0.0.30","@types/get-port":"^3.2.0","@types/glob":"^5.0.34","@types/lodash":"^4.14.92","@types/mkdirp":"^0.5.2","@types/node":"^8.5.7","@types/rimraf":"^2.0.2","@types/tmp":"^0.0.33","standard-version":"^8.0.1","typescript":"^2.9.2"},"dependencies":{"application-config-path":"^0.1.0","command-exists":"^1.2.4","debug":"^3.1.0","eol":"^0.9.1","get-port":"^3.2.0","glob":"^7.1.2","lodash":"^4.17.21","mkdirp":"^0.5.1","password-prompt":"^1.0.4","rimraf":"^2.6.2","sudo-prompt":"^8.2.0","tmp":"^0.0.33","tslib":"^2.4.0"},"_id":"@expo/devcert@1.1.2","gitHead":"cf83673a5bcf7e53526ccfe0c93f20467bad645c","_nodeVersion":"20.12.2","_npmVersion":"10.5.0","dist":{"shasum":"a4923b8ea5b34fde31d6e006a40d0f594096a0ed","size":63631,"noattachment":false,"key":"/@expo/devcert/-/@expo/devcert-1.1.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/@expo/devcert/download/@expo/devcert-1.1.2.tgz"},"_npmUser":{"name":"brentvatne","email":"brentvatne@gmail.com"},"directories":{},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/devcert_1.1.2_1715886754791_0.5331958053609822"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-05-16T19:12:34.952Z","publish_time":1715886754952,"_source_registry_name":"default","_cnpm_publish_time":1715886754952},"1.1.1":{"name":"@expo/devcert","version":"1.1.1","description":"Generate trusted local SSL/TLS certificates for local SSL development","main":"dist/index.js","types":"dist/index.d.ts","private":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"echo \"Ha.\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"keywords":["ssl","certificate","openssl","trust"],"author":{"name":"Dave Wasmer"},"license":"MIT","bugs":{"url":"https://github.com/expo/devcert/issues"},"homepage":"https://github.com/expo/devcert#readme","devDependencies":{"@types/debug":"^0.0.30","@types/get-port":"^3.2.0","@types/glob":"^5.0.34","@types/lodash":"^4.14.92","@types/mkdirp":"^0.5.2","@types/node":"^8.5.7","@types/rimraf":"^2.0.2","@types/tmp":"^0.0.33","standard-version":"^8.0.1","typescript":"^2.9.2"},"dependencies":{"application-config-path":"^0.1.0","command-exists":"^1.2.4","debug":"^3.1.0","eol":"^0.9.1","get-port":"^3.2.0","glob":"^7.1.2","lodash":"^4.17.21","mkdirp":"^0.5.1","password-prompt":"^1.0.4","rimraf":"^2.6.2","sudo-prompt":"^8.2.0","tmp":"^0.0.33","tslib":"^2.4.0"},"_id":"@expo/devcert@1.1.1","gitHead":"cf83673a5bcf7e53526ccfe0c93f20467bad645c","_nodeVersion":"20.12.2","_npmVersion":"10.5.0","dist":{"shasum":"06bb58335eee842babe03da3c9897506932100e0","size":63632,"noattachment":false,"key":"/@expo/devcert/-/@expo/devcert-1.1.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/@expo/devcert/download/@expo/devcert-1.1.1.tgz"},"_npmUser":{"name":"brentvatne","email":"brentvatne@gmail.com"},"directories":{},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/devcert_1.1.1_1715876176215_0.5048787855704606"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-05-16T16:16:16.414Z","publish_time":1715876176414,"_source_registry_name":"default","_cnpm_publish_time":1715876176414},"1.1.0":{"name":"@expo/devcert","version":"1.1.0","description":"Generate trusted local SSL/TLS certificates for local SSL development","main":"dist/index.js","types":"dist/index.d.ts","private":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"echo \"Ha.\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"keywords":["ssl","certificate","openssl","trust"],"author":{"name":"Dave Wasmer"},"license":"MIT","bugs":{"url":"https://github.com/expo/devcert/issues"},"homepage":"https://github.com/expo/devcert#readme","devDependencies":{"@types/debug":"^0.0.30","@types/get-port":"^3.2.0","@types/glob":"^5.0.34","@types/lodash":"^4.14.92","@types/mkdirp":"^0.5.2","@types/node":"^8.5.7","@types/rimraf":"^2.0.2","@types/tmp":"^0.0.33","standard-version":"^8.0.1","typescript":"^2.9.2"},"dependencies":{"application-config-path":"^0.1.0","command-exists":"^1.2.4","debug":"^3.1.0","eol":"^0.9.1","get-port":"^3.2.0","glob":"^7.1.2","lodash":"^4.17.4","mkdirp":"^0.5.1","password-prompt":"^1.0.4","rimraf":"^2.6.2","sudo-prompt":"^8.2.0","tmp":"^0.0.33","tslib":"^2.4.0"},"gitHead":"c913cd944b29877e39d0df0e3401040afe09f802","_id":"@expo/devcert@1.1.0","_nodeVersion":"16.14.2","_npmVersion":"8.5.0","dist":{"shasum":"d148eb9180db6753c438192e73a123fb13b662ac","size":63385,"noattachment":false,"key":"/@expo/devcert/-/@expo/devcert-1.1.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/@expo/devcert/download/@expo/devcert-1.1.0.tgz"},"_npmUser":{"name":"evanbacon","email":"baconbrix@gmail.com"},"directories":{},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/devcert_1.1.0_1667948680924_0.11885818265338166"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2022-11-08T23:05:54.047Z","publish_time":1667948681120,"_cnpm_publish_time":1667948681120},"1.0.0":{"name":"@expo/devcert","version":"1.0.0","description":"Generate trusted local SSL/TLS certificates for local SSL development","main":"dist/index.js","types":"dist/index.d.ts","private":false,"scripts":{"build":"tsc","prepublishOnly":"npm run build","test":"echo \"Ha.\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/expo/devcert.git"},"keywords":["ssl","certificate","openssl","trust"],"author":{"name":"Dave Wasmer"},"license":"MIT","bugs":{"url":"https://github.com/expo/devcert/issues"},"homepage":"https://github.com/expo/devcert#readme","devDependencies":{"@types/debug":"^0.0.30","@types/get-port":"^3.2.0","@types/glob":"^5.0.34","@types/lodash":"^4.14.92","@types/mkdirp":"^0.5.2","@types/node":"^8.5.7","@types/rimraf":"^2.0.2","@types/tmp":"^0.0.33","standard-version":"^8.0.1","typescript":"^2.9.2"},"dependencies":{"application-config-path":"^0.1.0","command-exists":"^1.2.4","debug":"^3.1.0","eol":"^0.9.1","get-port":"^3.2.0","glob":"^7.1.2","lodash":"^4.17.4","mkdirp":"^0.5.1","password-prompt":"^1.0.4","rimraf":"^2.6.2","sudo-prompt":"^8.2.0","tmp":"^0.0.33","tslib":"^1.10.0"},"gitHead":"d343e2deadc52e7edaff6f81665f1cf214b2f5bf","_id":"@expo/devcert@1.0.0","_nodeVersion":"12.18.1","_npmVersion":"6.14.8","dist":{"shasum":"79df9431e806bc546f6399e35934b9876384f0a9","size":63675,"noattachment":false,"key":"/@expo/devcert/-/@expo/devcert-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/@expo/devcert/download/@expo/devcert-1.0.0.tgz"},"_npmUser":{"name":"evanbacon","email":"baconbrix@gmail.com"},"directories":{},"maintainers":[{"name":"alanhughes","email":""},{"name":"brentvatne","email":"brentvatne@gmail.com"},{"name":"bycedric","email":"me@bycedric.com"},{"name":"evanbacon","email":"baconbrix@gmail.com"},{"name":"expo-bot","email":""},{"name":"expoadmin","email":""},{"name":"exponent","email":""},{"name":"ide","email":"ide+npm@jameside.com"},{"name":"kudochien","email":"ckchien@gmail.com"},{"name":"philpl","email":""},{"name":"tsapeta","email":"sapeta.tomasz@gmail.com"},{"name":"wschurman","email":"wschurman@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/devcert_1.0.0_1612252217866_0.5963585805908"},"_hasShrinkwrap":false,"publish_time":1612252218027,"_cnpm_publish_time":1612252218027,"_cnpmcore_publish_time":"2021-12-16T20:59:54.587Z"}},"readme":"# expo/devcert\n\nA fork of `devcert` with bundle size optimizations.\n\n# devcert - Development SSL made easy\n\nSo, running a local HTTPS server usually sucks. There's a range of\napproaches, each with their own tradeoff. The common one, using self-signed\ncertificates, means having to ignore scary browser warnings for each project.\n\ndevcert makes the process easy. Want a private key and certificate file to\nuse with your server? Just ask:\n\n```js\nlet ssl = await devcert.certificateFor(\"my-app.test\");\nhttps.createServer(ssl, app).listen(3000);\n```\n\nNow open https://my-app.test:3000 and voila - your page loads with no scary\nwarnings or hoops to jump through.\n\n> Certificates are cached by name, so two calls for\n> `certificateFor('foo')` will return the same key and certificate.\n\n## Options\n\nWhen it installs or upgrades, devcert creates a self-signed certificate\nauthority (CA) which it uses to sign all certificates it creates. It will try\nto register this CA with OS keychains in OSX, Linux, and Windows. However,\nsome HTTP clients (such as Firefox and NodeJS itself) use their own trusted\ncertificate list instead of the operating system's keychain. The `getCaPath`\nand `getCaBuffer` options make the CA available in the `certificateFor()`\nreturn object itself, so that these programs can choose whether to trust it.\n\n### getCaPath\n\nSet this option to `true` and the returned object will include a `caPath`\nproperty, set to the file path of the certificate authority file. Use this\npath to add the certificate to local trust stores which accept paths as\narguments, such as NodeJS's built-in environment variable\n`NODE_EXTRA_CA_CERTS`..\n\n### getCaBuffer\n\nSet this option to `true` and the returned object will include a `ca`\nproperty, set to the UTF-8-encoded contents of the certificate authority\nfile. Use this path to add the certificate to local trust stores which don't\nuse OS settings, lke the examples mentioned above.\n\n### skipHostsFile\n\nIf you supply a custom domain name (i.e. any domain other than `localhost`)\nwhen requesting a certificate from devcert, it will attempt to modify your\nsystem to redirect requests for that domain to your local machine (rather\nthan to the real domain). It does this by modifying your `/etc/hosts` file.\n\nIf you pass in the `skipHostsFile` option, devcert will skip this step. This\nmeans that if you ask for certificates for `my-app.test` (for example), and\ndon't have some other DNS redirect method in place, that you won't be able to\naccess your app at `https://my-app.test` because your computer wouldn't know\nthat `my-app.test` should resolve your local machine.\n\nKeep in mind that SSL certificates are issued for _domains_, so if you ask\nfor a certificate for `my-app.test`, and don't have any kind of DNS redirect\nin place (`/etc/hosts` or otherwise), trying to hit `localhost` won't work,\neven if the app you intended to serve via `my-app.test` is running on your\nlocal machine (since the SSL certificate won't say `localhost`).\n\n### skipCertutil\n\nThis option will tell devcert to avoid installing `certutil` tooling.\n\n`certutil` is a tooling package used to automate the installation of SSL\ncertificates in certain circumstances; specifically, Firefox (for every OS)\nand Chrome (on Linux only).\n\nNormally, devcert will attempt to install `certutil` if it's needed and not\nalready present on your system. If you don't want devcert to install this\npackage, pass `skipCertutil: true`.\n\nIf you decide to `skipCertutil`, the initial setup process for devcert\nchanges in these two scenarios:\n\n- **Firefox on all platforms**: Thankully, Firefox makes this easy. There's a\n  point-and-click wizard for importing and trusting a certificate, so if you\n  specify `skipCertutil: true`, devcert will instead automatically open Firefox\n  and kick off this wizard for you. Simply follow the prompts to trust the\n  certificate. **Reminder: you'll only need to do this once per machine**\n\n- **Chrome on Linux**: Unfortunately, it appears that the **only** way to get\n  Chrome to trust an SSL certificate on Linux is via the `certutil` tooling -\n  there is no manual process for it. Thus, if you are using Chrome on Linux, do\n  **not** supply `skipCertuil: true`. If you do, devcert certificates will not\n  be trusted by Chrome.\n\nThe `certutil` tooling is installed in OS-specific ways:\n\n- Mac: `brew install nss`\n- Linux: `apt install libnss3-tools`\n- Windows: N/A (there is no easy, hands-off way to install certutil on Windows,\n  so devcert will simply fallback to the wizard approach for Firefox outlined\n  above)\n\n## How it works\n\nWhen you ask for a development certificate, devcert will first check to see\nif it has run on this machine before. If not, it will create a root\ncertificate authority and add it to your OS and various browser trust stores.\nYou'll likely see password prompts from your OS at this point to authorize\nthe new root CA.\n\nSince your machine now trusts this root CA, it will trust any certificates\nsigned by it. So when you ask for a certificate for a new domain, devcert\nwill use the root CA credentials to generate a certificate specific to the\ndomain you requested, and return the new certificate to you.\n\nIf you request a domain that has already had certificates generated for it,\ndevcert will simply return the cached certificates.\n\nThis setup ensures that browsers won't show scary warnings about untrusted\ncertificates, since your OS and browsers will now trust devcert's\ncertificates.\n\n## Security Concerns\n\nThere's a reason that your OS prompts you for your root password when devcert\nattempts to install its root certificate authority. By adding it to your\nmachine's trust stores, your browsers will automatically trust _any_ certificate\ngenerated with it.\n\nThis exposes a potential attack vector on your local machine: if someone else\ncould use the devcert certificate authority to generate certificates, and if\nthey could intercept / manipulate your network traffic, they could theoretically\nimpersonate some websites, and your browser would not show any warnings (because\nit trusts the devcert authority).\n\nTo prevent this, devcert takes steps to ensure that no one can access the\ndevcert certificate authority credentials to generate malicious certificates\nwithout you knowing. The exact approach varies by platform:\n\n- **macOS and Linux**: the certificate authority's credentials are written to files that are only readable by the root user (i.e. `chown 0 ca-cert.crt` and\n  `chmod 600 ca-cert.crt`). When devcert itself needs these, it shells out to\n  `sudo` invocations to read / write the credentials.\n- **Windows**: because of my unfamiliarity with Windows file permissions, I\n  wasn't confident I would be able to correctly set permissions to mimic the setup\n  on macOS and Linux. So instead, devcert will prompt you for a password, and then\n  use that to encrypt the credentials with an AES256 cipher. The password is never\n  written to disk.\n\nTo further protect these credentials, any time they are written to disk, they\nare written to temporary files, and are immediately deleted after they are no longer needed.\n\nAdditionally, the root CA certificate is unique to your machine only: it's\ngenerated on-the-fly when it is first installed. ensuring there are no\ncentral / shared keys to crack across machines.\n\n### Why install a root certificate authority at all?\n\nThe root certificate authority makes it simpler to manage which domains are\nconfigured for SSL by devcert. The alternative is to generate and trust\nself-signed certificates for each domain. The problem is that while devcert\nis able to add a certificate to your machine's trust stores, the tooling to\nremove a certificate doesn't cover every case. So if you ever wanted to\n_untrust_ devcert's certificates, you'd have to manually remove each one from\neach trust store.\n\nBy trusting only a single root CA, devcert is able to guarantee that when you\nwant to _disable_ SSL for a domain, it can do so with no manual intervention\n\n- we just delete the domain-specific certificate files. Since these\n  domain-specific files aren't installed in your trust stores, once they are\n  gone, they are gone.\n\n## Integration\n\ndevcert has been designed from day one to work as low-level library that other\ntools can delegate to. The goal is to make HTTPS development easy for everyone,\nregardless of framework or library choice.\n\nWith that in mind, if you'd like to use devcert in your library/framework/CLI,\ndevcert makes that easy.\n\nIn addition to the options above, devcert exposes a `ui` option. This option\nallows you to control all the points where devcert requires user interaction,\nsubstituting your own prompts and user interface. You can use this to brand\nthe experience with your own tool's name, localize the messages, or integrate\ndevcert into a larger existing workflow.\n\nThe `ui` option should be an object with the following methods:\n\n```ts\n{\n  async getWindowsEncryptionPassword(): Promise<string> {\n    // Invoked when devcert needs the password used to encrypt the root\n    // certificate authority credentials on Windows. May be invoked multiple\n    // times if the user's supplied password is incorrect\n  },\n  async warnChromeOnLinuxWithoutCertutil(): Promise<string> {\n    // Invoked when devcert is run on Linux, detects that Chrome is installed,\n    // and the `skipCertutil` option is `true`. Used to warn the user that\n    // Chrome will not work with `skipCertutil: true` on Linux.\n  },\n  async closeFirefoxBeforeContinuing() {\n    // Invoked when devcert detects that Firefox is running while it is trying\n    // to programmatically install its certificate authority in the Firefox\n    // trust store. Firefox appears to overwrite changes to the trust store on\n    // exit, so Firefox must be closed before devcert can continue. devcert will\n    // wait for Firefox to exit - this is just to prompt the user that they\n    // need to close the application.\n  },\n  async startFirefoxWizard(certificateHost: string) {\n    // Invoked when devcert detects a Firefox installation and `skipCertutil:\n    // true` was specified. This is invoked right before devcert launches the\n    // Firefox certificate import wizard GUI. Used to give the user a heads up\n    // as to why they are about to see Firefox pop up.\n    //\n    // The certificateHost provided is the URL for the temporary server that\n    // devcert has spun up in order to trigger the wizard(Firefox needs try to\n    // \"download\" the cert to trigger the wizard). This URL will load the page\n    // supplied in the `firefoxWizardPromptPage()` method below.\n    //\n    // Normally, devcert will automatically open this URL, but in case it fails\n    // you may want to print it out to the console with an explanatory message\n    // so the user isn't left hanging wondering what's happening.\n  },\n  async firefoxWizardPromptPage(certificateURL: string): Promise<string> {\n    // When devcert starts the Firefox certificate installation wizard GUI, it\n    // first loads an HTML page in Firefox. The template used for that page is\n    // the return value of this method. The supplied certificateURL is the path\n    // to the actual certificate. The Firefox tab must attempt to load this URL\n    // to trigger the wizard.\n    //\n    // The default implementation is a simple redirect to that URL. But you could\n    // supply your own branded template here, with a button that says \"Install\n    // certificate\" that is linked to the certificateURL, along with a more in\n    // depth explanation of what is happening for example.\n  }\n  async waitForFirefoxWizard() {\n    // Invoked _after_ the Firefox certificate import wizard is kicked off. This\n    // method should not resolve until the user indicates that the wizard is\n    // complete (unfortunately, we have no way of determining that\n    // programmatically)\n  }\n}\n```\n\nYou can supply any or all of these methods - ones you do not supply will fall\nback to the default implementation.\n\n## Testing\n\nTesting a tool like devcert can be a pain. I haven't found a good automated\nsolution for cross platform GUI testing (the GUI part is necessary to test\neach browser's handling of devcert certificates, as well as test the Firefox\nwizard flow).\n\nTo make things easier, devcert comes with a series of virtual machine images. Each one is a snapshot taken right before running a test - just launch the machine and hit <Enter>.\n\nYou can also use the snapshotted state of the VMs to roll them back to a\npristine state for another round of testing.\n\n> **Note**: Be aware that the macOS license terms prohibit running it on\n> non-Apple hardware, so you must own a Mac to test that platform. If you don't\n> own a Mac - that's okay, just mention in the PR that you were unable to test\n> on a Mac and we're happy to test it for you.\n\n### Virtual Machine Snapshots\n\n- [macOS](https://s3-us-west-1.amazonaws.com/devcert-test-snapshots/macOS.pvm.zip)\n- [Windows](https://s3-us-west-1.amazonaws.com/devcert-test-snapshots/MSEdge+-+Win10.zip)\n- [Ubuntu](https://s3-us-west-1.amazonaws.com/devcert-test-snapshots/Ubuntu+Linux.zip)\n\n## License\n\nMIT © [Dave Wasmer](http://davewasmer.com)\n","_attachments":{},"homepage":"https://github.com/expo/devcert#readme","bugs":{"url":"https://github.com/expo/devcert/issues"},"license":"MIT"}