Skip to content

Latest commit

 

History

History
220 lines (164 loc) · 8.9 KB

README.md

File metadata and controls

220 lines (164 loc) · 8.9 KB

About

This is the API component to the Secure Image application suite. Secure Image is designed to provide a simple yet secure way for people to take sensitive photographs (or image related documentation) and store it outside of the device's camera roll. It also provides a convenient way to extract the images by providing a secure URL to download an album.

Build

This component builds using GitHub Actions in combination with the OpenShift Container Platform (OCP). The GitHub Actions workflow will build and test the project against various node versions and, once successful, if the changes are on the master branch trigger an OCP image build using a service account with highly restricted access.

There are two steps for setting up the CICD pipeline:

  1. Setup a OCP service account with restricted access and add the credentials to GitHub;
  2. Setup the OCP image build.

Step 1: CICD Service Account

To setup the CICD pipeline GitHub needs to be able to trigger an image build in OCP. We do this by setting up a service account that only has access to trigger and image build.

In the root directory of the repo there is an directory containing common OpenShift templates. Use the following command to create a CICD service account for GitHub.

oc process -f ../openshift/templates/cicd.yaml \
-p NAMESPACE=$(oc project --short) | \
oc apply -f -
Parameter Optional Description
NAMESPACE NO The namespace used for all components of the credentials.

You'll see some output from the above command similar to this:

serviceaccount/github-cicd created
role.authorization.openshift.io/github-cicd created
rolebinding.authorization.openshift.io/github-cicd created

You can list your secrets with the following command:

oc get secrets

Again, you'll see output similar to this:

NAME                          TYPE                                  DATA   AGE
github-cicd-dockercfg-gsd7b   kubernetes.io/dockercfg               1      85s
github-cicd-token-9jnw6       kubernetes.io/service-account-token   4      85s
github-cicd-token-gr9pf       kubernetes.io/service-account-token   4      85s

Pick either of the secrets beginning with github-cicd-token and get the token field from it. You can do this via the Web UI or with the following command providing you have jq installed:

oc get secret/github-cicd-token-9jnw6 -o json | \
jq '.data.token' | \
tr -d "\""

Pro Tip 🤓: If you have a mac, add | pbcopy after the above command to copy the token directly to your clipboard.

Once you have your token go to the Settings of your GitHub repo and create the following encrypted secrets:

Name Optional Value
OPENSHIFTTOKEN NO The token from from the command above.
OPENSHIFTSERVERURL NO The URL for the OpenShift console (everything up to the port number).

These secrets are used by the official RedHat GitHub actions to trigger the image build. You can see them in the workflow file here and in the excerpt below:

steps:
  - name: S2I Build
    uses: redhat-developer/openshift-actions@v1.1
    with:
      version: "latest"
      openshift_server_url: ${{ secrets.OpenShiftServerURL}}
      parameters: '{"apitoken": "${{ secrets.OpenShiftToken }}", "acceptUntrustedCerts": "true"}'
      cmd: |
        'version'
        'start-build secure-image-api-master-build --follow -n devex-mpf-secure-tools'

Step 2: OCP Image Build

The second and final step is to setup the image build on the OCP platform. The workflow is setup to only run this step when changes impact the master branch.

Use the following command to setup the image BuildConfig in your tools namespace:

oc process -f openshift/templates/build.yaml | oc apply -f -

You can trigger this build manually to check that it works as expected:

oc start-build bc/secure-image-api-master-build --follow

Deployment

Whereas image is generated by build, all other artifacts are managed using Helm. To deploy the artifacts to various OpenShift environments,

  1. install oc and helm cli

  2. login to oc by running oc login ...

  3. set environment by running oc project ...

  4. create a yaml values file under helm folder for each environment containing the environment specific and potentially sensitive information. The file must have extension .local.yaml to avoid checking into SCM. For example, for OCP4 dev environment, the file can be named values.ocp4.ev.local.yaml and should contain following information (sensitive data are masked)

    minio:
      accessKey: "xxxxx"
      secretKey: "xxxxx"
    route:
      host: dev-secure-image.apps.silver.devops.gov.bc.ca
    sessionSecret: "xxxxx"
    sso:
      clientSecret: "xxxxx"
    
    congJson: |
      {
        "temporaryUploadPath": "uploads",
        "archiveFileBaseName": "IMG_",
        "templates": {
          "path": "templates"
        },
        "albumExpirationInDays": 90,
        "minio": {
          "bucket": "secure-image-pr",
          "port": 9000,
          "secure": false,
          "expiry": 604800,
          "region": "us-east-1"
        },
        "session": {
          "maxAge": 604800000,
          "expires": 604800000,
          "domain": ".gov.bc.ca",
          "memcached": {
            "hosts": "{{ include "secure-image-api.fullname" . }}-memcached:11211"
          }
        },
        "sso": {
          "clientId": "secure-image-api",
          "callback": "/v1/auth/callback",
          "authUrl": "https://dev.oidc.gov.bc.ca/auth/realms/secimg/protocol/openid-connect/auth",
          "tokenUrl": "https://dev.oidc.gov.bc.ca/auth/realms/secimg/protocol/openid-connect/token",
          "certsUrl": "https://dev.oidc.gov.bc.ca/auth/realms/secimg/protocol/openid-connect/certs"
        }
      }

    This file overwrites and supplements helm/values.yaml. Consult helm/values.yaml for other values that you want to overwrite by environment.

  5. to install artifacts to say dev env, run

    helm install secure-image-api -f helm/values.ocp4.dev.local.yaml helm
    

    to upgrade/update, run

    helm upgrade secure-image-api helm -f helm/values.ocp4.dev.local.yaml
    

    to ininstall, run

    helm uninstall secure-image-api
    

    secure-image-api in above commands is the release name and came be named differently.

    Pro Tip 🤓: append --dry-run to above commands to preview the effects without applying.

Local Development

Local development for this component is made easy by using the included docker-compose file. This will start a local server that can be used for development on any of the components.

Create a local directory within the api sub-folder that the minio container will use to store data. When an album is uploaded it will appear in this directory.

mkdir minio_data

Create a .env file in the api sub-folder with the entries show below. See src/config/index.js and docker-compose.yaml to understand how they are consumed by the application:

NODE_ENV=development

# Local Docker
MINIO_ACCESS_KEY="xxxx"
MINIO_SECRET_KEY="yyyy"
SSO_CLIENT_SECRET="zzzz"
SESSION_SECRET="aaa"
APP_URL=https://f9d9fbb72386.ngrok.io
Name Optional Value
MINIO_ACCESS_KEY NO The minio access key (line username)
MINIO_SECRET_KEY NO The minio secret key (like password)
SSO_CLIENT_SECRET NO This comes from the client in the SSO Web UI
SESSION_SECRET NO Used to secure HTTP sessions
APP_URL NO The application (API) endpoint

Pro Tip 🤓:

  • Use openssl rand -hex 6 to generate MINIO_ACCESS_KEY, MINIO_SECRET_KEY, and SESSION_SECRET.
  • iOS prefers SSL due to AST. You an use npx ngrok http 8080 to setup a local proxy that will provide an external URL providing both http and https protocols.
  • Make sure the URL is registered in your SSO realm as a valid callback URL.

Now, bring up the docker stack / images using docker-compose:

docker-compose up

At this point your docker stack will be running. See the ProTip above about using ngrok as a proxy. The external URLs provided by this application can be given used for APP_URL as well as provided to the iOS and Android applications for local development work.