-
Notifications
You must be signed in to change notification settings - Fork 39
Production checklist for the Isomer team
Remember to enable asset optimization. This allows Netlify to minify and compress our JS and CSS files, as well as images.
Add the following outgoing webhook to the Netlify production site. This allows Netlify to inform and purge the KeyCDN cache when the production site has been deployed successfully.
https://<KEYCDN_API_KEY>@api.keycdn.com/zones/purge/<KEYCDN_ZONE_ID>.json
Ensure that there is a netlify.toml
file in the root folder of the GitHub repository with the following HTTP security header configuration:
[[headers]]
for = "/*"
[headers.values]
X-XSS-Protection = "1; mode=block"
Referrer-Policy = "no-referrer"
X-Content-Type-Options = "nosniff"
X-Frame-Options = "deny"
Content-Security-Policy = "default-src 'self'; script-src 'self' https://assets.dcube.cloud https://*.wogaa.sg https://assets.adobedtm.com https://www.google-analytics.com https://cdnjs.cloudflare.com https://va.ecitizen.gov.sg https://*.cloudfront.net https://printjs-4de6.kxcdn.com https://unpkg.com https://wogadobeanalytics.sc.omtrdc.net 'unsafe-eval'; object-src 'self'; style-src 'self' https://fonts.googleapis.com/ https://*.cloudfront.net https://va.ecitizen.gov.sg https://*.wogaa.sg https://cdnjs.cloudflare.com https://datagovsg.github.io 'unsafe-inline'; img-src *; media-src *; frame-src https://wogaa.demdex.net/ https://*.youtube.com https://*.youtube-nocookie.com https://*.vimeo.com; frame-ancestors 'none'; font-src * data:; connect-src 'self' https://dpm.demdex.net https://www.google-analytics.com https://stats.g.doubleclick.net https://*.wogaa.sg https://va.ecitizen.gov.sg https://ifaqs.flexanswer.com https://*.cloudfront.net https://fonts.googleapis.com https://cdnjs.cloudflare.com https://wogadobeanalytics.sc.omtrdc.net; report-uri https://www.infocommsociety.com/~yicheng/csp-report/"
How to test
Test the HTTP security configuration here: https://securityheaders.com/
To ensure that users are served our site pages over HTTPS only, set the following configuration on the KeyCDN console:
Force SSL: Enabled
To ensure that users are served our site pages over HTTPS only, set the following configuration on the KeyCDN console. Additionally, add the correct Custom SSL Private Key
and Custom SSL Certificate
into the console.
SSL: Custom
To prevent query string caching behavior on the netlify site (this disrupts our search), set the following configuration on the KeyCDN console:
Ignore Query String: Disabled
To prevent an attacker from discovering the Netlify origin server, set the following configuration on the KeyCDN console:
Canonical Header: Disabled
How to test
Test it by checking that the link rel canonical header is not present among the HTTP headers
E.g.
> curl -I https://www.tech.gov.sg
To make KeyCDN cache the page content for at most 5 mins. This ensures that website contents are updated within 5-10 mins of deployment.
Max Expiry controls the duration of time that KeyCDN caches a piece of content before it goes back to the origin server to retrieve that content.
Max Expiry: 5
KeyCDN requires a Zone
to be set up, as well as a Zonealias
record. Remember to set up the Zonealias to allow KeyCDN to display the website to users.
How to test
Test it by setting your local DNS to the to-be-used domain and verify that you can view the site on your browser.
You can make your testing process in this step easier by using the local-cname
package.
Before a government agency user can purchase an SSL certificate, the Isomer team needs to generate a CSR and a private key.
To do so, we use OpenSSL. First, download OpenSSL (for Mac) using the following command:
brew install openssl
Next, generate the CSR and private key:
openssl req -new -newkey rsa:2048 -nodes -keyout <site.gov.sg>.key -out <site.gov.sg>.csr -sha256
If you already have an existing private key, you can use it as an input to generate the CSR:
openssl req -new -key <path to key>.key -out <site.gov.sg>.csr -sha256
Fill up the CSR in the following way:
Country Name (2 letter code) []:SG
State or Province Name (full name) []:Singapore
Locality Name (eg, city) []:Singapore
Organization Name (eg, company) []:< your organization name, for e.g. Prime Minister's Office Strategy Group>
Organizational Unit Name (eg, section) []: ITD
Common Name (eg, fully qualified host name) []:< {agency}.gov.sg for example, csf.gov.sg >
Email Address []:< email of contact person at agency, for example, [email protected] >
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:<leave blank>
Finally, save the CSR and private key into the Isomer Admin
Vault of 1Password. Send the CSR to the government agency user.
Create a file called multisan.conf
with the following contents:
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
default_keyfile = < your fully qualified host name followed by .key, {agency}.gov.sg.key, or for example, csf.gov.sg.key >
prompt = no
[req_distinguished_name]
C = SG
ST = Singapore
L = Singapore
O = < your organization name, for e.g. Prime Minister's Office Strategy Group>
OU = ITD
CN = < your fully qualified host name: {agency}.gov.sg, for example, csf.gov.sg >
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = < your alternative domains >
DNS.2 = < your alternative domains >
DNS.3 = < your alternative domains >
Then, you run the following command in the same directory:
openssl req -new -nodes -out {agency.gov.sg}.csr -sha256 -config multisan.conf
Please refer to the Isomer redirection repo for details.
We have set up some tests on Travis - specifically, the Isomer Checker tests and Lighthouse tests for accessibility.
In order for the script to work, the package @isomerpages/isomerpages-travisci-scripts
must be installed from npm
first. In the root directory of the repo, run:
npm init
npm install @isomerpages/isomerpages-travisci-scripts
Add the following .travis.yml
file into the site repo
#.travis.yml
git:
depth: 3
matrix:
include:
- language: ruby
dist: trusty
script:
- bundle exec jekyll build
cache: bundler
- language: node_js
dist: trusty
node_js: "node"
script: node travis-script.js
cache: npm
addons:
chrome: stable
Add the following travis-script.js
file into the root folder of the repo:
//travis-script.js
const travisScript = require("@isomerpages/isomerpages-travisci-scripts");
const travisBranch = process.env.TRAVIS_BRANCH;
if(travisBranch == "master") {
travisScript.runAll();
}
else {
travisScript.testsOnly();
}
Go to the specific repo settings in Travis. Set the following Travis environmental variables.
-
KEYCDN_API_KEY
- obtained from 1Password's isomer admin vault. Hide this value in the Travis logs -
KEYCDN_ZONE_ID
- obtained from KeyCDN's Zone ID. Display this value in the Travis logs -
NETLIFY_ACCESS_TOKEN
- obtained from 1Password's isomer admin vault. Hide this value in the Travis logs -
NETLIFY_SITE_ID
- obtained from Netlify's site information >> API ID. Display this value in the Travis logs -
SLACK_URI
- the Slack webhook URL for error messages, obtained from https://api.slack.com/. Hide this value in the Travis logs -
SLACK_ALERT_URI
- same process asSLACK_URI
, but for the#alerts
channel. Hide this value in the Travis logs -
PROD_URL
- the full URL of the production site, e.g.https://www.isomer.gov.sg/
. This will the target of the Lighthouse tests. Display this value in the Travis logs -
STAGING_URL
- the full URL of the staging site, e.g.https://isomer-techgovsg-staging.netlify.com/
. This will be the target of the Lighthouse tests. Display this value in the Travis logs
Set up cron jobs for Travis to run a build for the master
and staging
branches automatically weekly (the setting can be found below the environmental variables section). Set Options
to Always run
.
Check that the color contrast in the website (foreground: #FFFFFF, background: all the colors on the site) is greater than 4.5. This is to ensure that isomer fulfills the WCAG AA standard for color contrast.
How to test
Test it by checking that all color combinations in the custom.scss
file pass the min. color contrast here: https://webaim.org/resources/contrastchecker/
In _config.yml
in the root directory, make sure the following configuration are set to their proper values:
-
url
- set this to the base url of the website, e.g.https://www.site.gov.sg
-
resources_name
- set this to the name of the resource room folder -
feedback_form_url
- set this to the form.sg feedback from URL -
exclude: [travis-script.js, .travis.yml, README.md, package.json, package-lock.json, node_modules, vendor/bundle/, vendor/cache/, vendor/gems/, vendor/ruby/, Gemfile, Gemfile.lock]
- this ensures that files that are used for the build do not appear on the live site. Unfortunately, child sites do not inherit this configuration from our parent theme -
title
,title-abbreviated
,email
,description
- self explanatory, consult the agency for the details if needed
In homepage.yml
under the _data
folder, make sure the following configuration are set:
-
favicon
- relative path to the favicon image file in.ico
format -
shareicon
- relative path to the image to appear on all pages when shared via WhatsApp, Facebook, etc. This image must be in.png
format and of size 600px by 600px -
agency-logo
- relative path to the agency logo to be placed at the navbar -
show-reach
- set totrue
if the agency wants a link to REACH at the footer in compliance with DSS. Omit this option or set tofalse
to remove the link
- Remember to update the production URL on the GitHub repository description
- Create a Slack channel for the site. Even if the agency is not using Slack, it can be a good idea to create a channel for the site so that we are alerted when issues arise
- Remember to enable branch protection for
master