Need help with server?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

CovidShield
134 Stars 50 Forks Apache License 2.0 165 Commits 20 Opened issues

Description

Exposure Notification: Diagnosis Server implementation

Services available

!
?

Need anything else?

Contributors list

# 27,682
Ruby
Shell
kafka-c...
kafka
32 commits
# 223,957
slack
Terrafo...
hashico...
golang
19 commits
# 561,894
Shell
Scala
HTML
functio...
9 commits
# 1,037
Jenkins
css-fra...
schema-...
raku
8 commits
# 299,175
elixir-...
Elixir
Erlang
css-sel...
7 commits
# 297,931
HTML
Shell
splunk
slack
7 commits
# 131,745
unique-...
golang
Rust
Kuberne...
2 commits
# 239,604
Go
Shell
Kuberne...
Python
1 commit
# 335,187
Shell
Objecti...
C++
React N...
1 commit
# 35,140
XML
france
sentry
nuxtjs
1 commit
# 222,202
HTML
google-...
Go
Terrafo...
1 commit
# 258,138
HTML
typogra...
Shell
linting...
1 commit
# 86,906
k8s
loadbal...
Go
Lua
1 commit
# 27,194
Shell
Java
Android
appbarl...
1 commit

COVID Shield Diagnosis Server

Container Build

This repository implements a diagnosis server to use as a server for Apple/Google's Exposure Notification framework, informed by the guidance provided by Canada's Privacy Commissioners.

The choices made in implementation are meant to maximize privacy, security, and performance. No personally-identifiable information is ever stored, and nothing other than IP address is available to the server. No data at all is retained past 21 days. This server is designed to handle use by up to 38 million Canadians, though it can be scaled to any population size.

In this document:

Overview

Apple/Google's Exposure Notification specifications provide important information to contextualize the rest of this document.

There are two fundamental operations conceptually:

  • Retrieving diagnosis keys: retrieving a list of all keys uploaded by other users; and
  • Submitting diagnosis keys: sharing keys returned from the EN framework with the server.

These two operations are implemented as two separate servers (

key-submission
and
key-retrieval
) generated from this codebase, and can be deployed independently as long as they share a database. It is also possible to deploy any number of configurations for each of these components, connected to the same database, though there would be little value in deploying multiple configurations of
key-retrieval
.

For a more technical overview of the codebase, especially of the protocol and database schema, see this video.

Retrieving diagnosis keys

When diagnosis keys are uploaded, the

key-submission
server stores the data defined and required by the Exposure Notification API in addition to the time at which the data was received by the server. This submission timestamp is rounded to the nearest hour for privacy preservation (to prevent correlation of multiple keys to the same user).

The hour of submission is used to group keys into buckets, in order to prevent clients (the soon-to-be-released COVID Shield mobile app) from having to download a given set of key data multiple times in order to repeatedly check for exposure.

The published diagnosis keys are fetched—with some best-effort authentication—from a Content Distribution Network (CDN), backed by

key-retrieval
. This allows a functionally-arbitrary number of concurrent users.

Retrieving Exposure Configuration

Exposure Configuration, used to determine the risk of a given exposure, is also retrieved from the

key-retrieval
server. A JSON document describing the current exposure configuration for a given region is available at the path
/exposure-configuration/.json
, e.g. for Ontario (region
ON
):
$ curl https://retrieval.covidshield.app/exposure-configuration/ON.json
{"minimumRiskScore":0,"attenuationLevelValues":[1,2,3,4,5,6,7,8],"attenuationWeight":50,"daysSinceLastExposureLevelValues":[1,2,3,4,5,6,7,8],"daysSinceLastExposureWeight":50,"durationLevelValues":[1,2,3,4,5,6,7,8],"durationWeight":50,"transmissionRiskLevelValues":[1,2,3,4,5,6,7,8],"transmissionRiskWeight":50}

Submitting diagnosis keys

In brief, upon receiving a positive diagnosis, a health care professional will generate a One Time Code through a web application frontend (a reference implementation will be open-sourced soon), which communicates with

key-submission
. This code is sent to the patient, who enters the code into their (soon-to-be-released) COVID Shield App. This code is used to authenticate the Application (once) to the diagnosis server. Encryption keypairs are exchanged by the Application and the
key-submission
server to be stored for fourteen days, and the One Time Code is immediately purged from the database.

These keypairs are used to encrypt and authorize Diagnosis Key uploads for the next fourteen days, after which they are purged from the database.

The encryption scheme employed for key upload is NaCl Box (a public-key encryption scheme using Curve25519, XSalsa20, and Poly1305). This is widely regarded as an exceedingly secure implementation of Elliptic-Curve cryptography.

Data usage

The Diagnosis Key retrieval protocol used in COVID Shield was designed to restrict the data transfer to a minimum. With large numbers of keys and assuming the client fetches using compression, there is minimal protocol overhead on top of the key data size of 16 bytes.

In all examples below:

  • Each case may generate up to 28 keys.
  • Keys are valid and distributed for 14 days.
  • Each key entails just under 18 bytes of data transfer when using compression.
  • Key metadata and protocol overhead should in reality be minimal, but:
  • Assume 50% higher numbers than you see below to be on the safe side. This README will be updated soon with more accurate real-world data sizes.

Data below is current at May 12, 2020. For each case, we assume the example daily new cases is a steady daily recurrence.

Deployed only to province of Ontario

There were 350 new cases in Ontario on May 10, 2020. 350 * 28 * 18 = 170kB per day, thus, deploying to the province of Ontario at current infection rates would cause 7.1kB of download each hour.

Deployed to Canada

There were 1100 new cases in Canada on May 10, 2020. 1100 * 28 * 18 = 540kB per day, thus, deploying to Canada at current infection rates would cause 23kB of download each hour.

Deployed to entire United States of America

There were 18,000 new cases in America on May 10, 2020. 18,000 * 28 * 18 = 8.9MB per day, thus, deploying to the all of America at current infection rates would cause: 370kB of download each hour.

Deployed to entire world

If COVID Shield were deployed for the entire world, we would be inclined to use the "regions" built into the protocol to implement key namespacing, in order to not serve up the entire set of global diagnosis keys to each and every person in the world, but let's work through the number in the case that we wouldn't:

There were 74,000 new cases globally on May 10, 2020. 74,000 * 28 * 16 = 36MB per day, thus, deploying to the entire world at current infection rates would cause: 1.5MB of download each hour.

Generating one-time codes

We use a one-time code generation scheme that allows authenticated case workers to issue codes, which are to be passed to patients with positive diagnoses via whatever communication channel is convenient.

This depends on a separate service, holding credentials to talk to this (

key-submission
) server. We have a sample implementation we will open source soon, but we anticipate that health authorities will prefer to integrate this feature into their existing systems. The integration is extremely straightforward, and we have minimal examples in several languages. Most minimally:
curl -XPOST -H "Authorization: Bearer $token" "https://submission.covidshield.app/new-key-claim"

Protocol documentation

For a more in-depth description of the protocol, please see the "proto" subdirectory of this repo.

Deployment notes

  • key-submission
    depends on being deployed behind a firewall (e.g. AWS WAF), aggressively throttling users with 400 and 401 responses.
  • key-retrieval
    assumes it will be deployed behind a caching reverse proxy.

Platforms

We hope to provide reference implementations on AWS, GCP, and Azure via Hashicorp Terraform.

Amazon AWS

Kubernetes

Metrics and Tracing

COVID Shield uses OpenTelemetry to configure the metrics and tracing for the server, both the key retrieval and key submission.

Metrics

Currently, the following options are supported for enabling Metrics: * standard output * prometheus

Metrics can be enabled by setting the

METRIC_PROVIDER
variable to
stdout
,
pretty
, or
prometheus
.

Both

stdout
and
pretty
will send metrics output to stdout but differ in their formatting.
stdout
will print the metrics as JSON on a single line whereas
pretty
will format the JSON in a human-readable way, split across multiple lines.

If you want to use Prometheus, please see the additional configuration requirements below.

Prometheus

In order to use Prometheus as a metrics solution, you'll need to be running it in your environment.

You can follow the instructions here for running Prometheus.

You will need to edit the configuration file,

prometheus.yml
to add an additional target so it actually polls the metrics coming from the COVID Shield server:
...
    static_configs:
    - targets: ['localhost:9090', 'localhost:2222']

Tracing

Currently, the following options are supported for enabling Tracing: * standard output

Tracing can be enabled by setting the

TRACER_PROVIDER
variable to
stdout
or
pretty
.

Both

stdout
and
pretty
will send trace output to stdout but differ in their formatting.
stdout
will print the trace as JSON on a single line whereas
pretty
will format the JSON in a human-readable way, split across multiple lines.

Note that logs are emitted to

stderr
, so with
stdout
mode, logs will be on
stderr
and metrics will be on
stdout
.

Contributing

See the Contributing Guidelines.

Who Built COVID Shield?

We are a group of Shopify volunteers who want to help to slow the spread of COVID-19 by offering our skills and experience developing scalable, easy to use applications. We are releasing COVID Shield free of charge and with a flexible open-source license.

For questions, we can be reached at [email protected].

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.