The first thing we're going to do is create a bash script here. We'll call it build-a-dash mac. Here we're going to set some global environment variables that electron builder will look at and use to select the certificate for code signing.
We're going to use export to set the environment variable. We're setting CSC_link. CSC stands for code signing certificate. We're going to pass to the current working directory. We're going to call this the root of our project. I'm going to pass the folder recurrently and build assets and then mac certs.
Then, when I exported this P12 file, I had to set a password for it. Electron builder needs to know that password to be able to sign. I'll set the key password variable. My password was just password. Then we'll call our MPM scripts that actually calls the electron builder.
Before we try it out, another thing we want to add to our electron builder configuration here, force code signing, true. What this does is this tells electron builder to fail the build if code signing failed or is invalid for whatever reason. Then over here, in bash, we're going to add execute permissions to the bash script that we just create.
Now, let's run it and see if it works. OK, so our build script worked. One important security note here is that we don't want our certificates to be available to any third parties and we don't want it included in our application bundle.
My certificate files are in the build assets folder and that is being ignored by electron builder, so they're not included in the build. If your application is open source and it's going to be on GitHub or something, you'll want to make sure to ignore the certificate files in your source control.
For Windows, I'm going to do the same thing. Create a new file. We'll call it bill-win. Instead of using bash, which isn't natively available in all versions of Windows, I'm going to use command prompts to write a batch a script here. I'm going to do basically the same thing.
Let's see what happens when you don't code sign your application and distribute it to others. I set up a local HTTP server and I have the signed version of our application zipped up and the unsigned version zipped up.
When I try to execute the unsigned version, it says it can't be opened because it's from an unidentified developer. At this point, the only way for the user to run your application is to either find it in the finder, right click and hit open, or change their security settings.
It's not very user-friendly. We try our Hello World here. It says it's an application downloaded from the Internet, are you sure you want to open it? When you hit open, it runs just fine.
As a side note, you might be wondering, why did you have to download it from the web browser to see this behavior? This is because max internal security infrastructure, called gatekeeper, automatically flags executables downloaded from the Internet.
When you build it on your machine unsigned, you can run it no problem but when your users download it from the Internet, gatekeeper flags it as unsafe unless it can verify it has a trusted code sign, which, in the unsigned case it didn't and that's why it wouldn't let us run it.
Let's see how we can verify that our app has been signed. On Mac OS there's a code sign utility that's available on your path by default. Let's use that and we'll run code sign, tell it to verify, tell it to be verbose, so it actually gets an output from it.
We'll tell it to verify deep. Basically, we pass deep because there's a lot of nested executables in our application bundle. Those all have to be signed so we want to verify that those were signed. Then we'll pass strict and then we'll pass our Hello World app bundle.
Then that's returning true there and it was properly signed. Another reason that you want to code sign your app is because it ensures that the internal files in your application have not changed since you signed them. Let's test that out. Where does that go? The string test to our star file. Let's just cut that out.
We can see, this is our RenderJS. There's a test in there. It says clear. We'll run our verify command again. When we run it again, we can see that it says a sealed resource is missing or invalid because it's been modified as saying it's not valid.