Skip to content

Commit

Permalink
Merge branch 'master' into propose-allergyintolerance-create-hook
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacvetter authored Jun 16, 2023
2 parents cd1465a + 39f2c86 commit d2c103d
Show file tree
Hide file tree
Showing 39 changed files with 4,271 additions and 1,216 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Publish docs

on:
push:
branches: [ master ]
pull_request:
types: [opened, synchronize] # This will trigger the workflow only when a PR is opened or updated with new commits

jobs:
build:

runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2

- name: Set up Python 3.6
uses: actions/setup-python@v2
with:
python-version: 3.6

- name: Setup dependencies
run: pip install -r requirements.txt

- name: Generate docs
run: mkdocs build --verbose --clean --strict

- name: Deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
cname: cds-hooks.org
23 changes: 0 additions & 23 deletions .travis.yml

This file was deleted.

Binary file added Argonaut CDS Hooks Security Risk Assessment.pdf
Binary file not shown.
27 changes: 15 additions & 12 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,33 +40,36 @@ The committers are individuals who are recognized by merit and have a demonstrat

The current committers on the project are:

- [Kevin Shekleton](https://github.com/kpshek) (PMC Chair)
- [Josh Mandel](https://github.com/jmandel)
- [Matt Berther](https://github.com/mattberther)
- [Isaac Vetter](https://github.com/isaacvetter)
- [Brett Marquard](https://github.com/brettmarquard)
- [Bryn Rhodes](https://github.com/brynrhodes)

- [Isaac Vetter](https://github.com/isaacvetter)
- [Josh Mandel](https://github.com/jmandel)
- [Vadim Peretokin](https://github.com/vadi2)

### Project Management Committee

Members of the PMC are committers who are also responsible for governing the CDS Hooks project. The PMC has primary responsibility for development of the CDS Hooks community. This includes evangelism, organizing Connectathons, and other forms of community building. The PMC also reports progress to the community and defines target feature sets for releases.
Members of the PMC are committers who are also responsible for governing the CDS Hooks project. The PMC has primary responsibility for development of the CDS Hooks community. This includes evangelism, organizing Connectathons, and other forms of community building. The PMC also reports progress to the community and defines target feature sets for releases. Emeritus PMC members are recognized for their significant contributions to CDS Hooks and are not able to cast votes. Emeritus PMC members may be reinstated at any time upon a unanimous PMC vote.

The PMC also is responsible for the project governance and process (including this policy).

The current PMC members are:

- [Kevin Shekleton](https://github.com/kpshek) (PMC Chair)
- [Josh Mandel](https://github.com/jmandel)
- [Matt Berther](https://github.com/mattberther)
- [Isaac Vetter](https://github.com/isaacvetter)
- [Brett Marquard](https://github.com/brettmarquard)
- [Bryn Rhodes](https://github.com/brynrhodes)
- [Isaac Vetter](https://github.com/isaacvetter)
- [Josh Mandel](https://github.com/jmandel)
- [Vadim Peretokin](https://github.com/vadi2)


Emeritus PMC members are:
- [Kevin Shekleton](https://github.com/kpshek)


### PMC Chair

The PMC Chair is a PMC member and committer who takes on the primary responsibility of ensuring the health of the project and community. The PMC Chair Additionally, the PMC Chair maintains logistical resources such as the domain name, hosting resources, and mailing list.

The current PMC Chair is [Kevin Shekleton](https://github.com/kpshek)
The current PMC Chair is - [Isaac Vetter](https://github.com/isaacvetter)

### Contributors

Expand All @@ -84,7 +87,7 @@ The community refers to the collective set of individuals and parties contributi

Any existing committer may nominate a contributor as a new committer on the project. The nominee should have a demonstrated history of contributions and commitment. Contributions can come in many forms such as code, issues, documentation, and community engagement. A nominee must receive a unanimous vote from the PMC. Upon being accepted, the PMC Chair will grant the nominee write access to the CDS Hooks repositories and announce the new committer to the mailing list.

Any PMC member may nominate a current committer to the join the PMC. The nominee should have a demonstrated history leadership in support of the community, and must receive a unanimous vote from the PMC.
Any current PMC member may nominate a current committer to the join the PMC. The nominee should have a demonstrated history leadership in support of the community, and must receive a unanimous vote from the PMC.

## Contributions

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src="https://github.com/cds-hooks/docs/raw/master/logo.png">
</p>

# CDS Hooks
# CDS Hooks

[![Build Status](https://api.travis-ci.org/cds-hooks/docs.svg)](https://travis-ci.org/cds-hooks/docs)

Expand Down Expand Up @@ -58,4 +58,4 @@ Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
limitations under the License.
Binary file removed deploy_key.enc
Binary file not shown.
61 changes: 61 additions & 0 deletions docs/best-practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Implementation Best Practices

This page serves as best practice guidance for CDS Hooks implementers. The best practices outlined here are not mandatory implementation rules; rather, they are suggested guidance. This is a living, in progress document and the best practices outlined here should not be considered absolute or complete.

## Security

The CDS Hooks security model requires thought and consideration from implementers. Security topics are never binary, are often complex, and robust implementations should factor in concepts such as risk and usability. Implementers should approach their security related development with thoughtful care.

The CDS Hooks specifications already provides some guidance in this space. The information here is supplemental to the existing specification documentation.

The CDS Hooks security model leverages several existing RFCs. These should be read and fully understood by all implementers.

- [rfc7519: JSON Web Tokens (JWT)](https://tools.ietf.org/html/rfc7519)
- [rfc7517: JSON Web Key (JWK)](https://tools.ietf.org/html/rfc7517)
- [rfc7515: JSON Web Signature (JWS)](https://tools.ietf.org/html/rfc7515)
- [rfc7518: JSON Web Algorithms (JWA)](https://tools.ietf.org/html/rfc7518)

### CDS Clients

Implementers of CDS Clients should:

**Maintain a allowlist of CDS Service endpoints that may be invoked.**

Only endpoints on the allowlist can be invoked. This ensures that CDS Clients invoke only trusted CDS Services. This is especially important since CDS Clients may send an authorization token that allows the CDS Service temporary access to the FHIR server.

**Issue secure FHIR access tokens.**

*If* a CDS Clients generates access tokens to its FHIR server, the tokens should:

- Be unique for each CDS Service endpoint.
- Be very short-lived.
- Provide the minimum necessary access for the CDS Service. This includes both SMART scopes as well as the patient(s)/data that can be accessed.

**Audit CDS Service's access to data***

Regardless of the use of prefetch or more typical FHIR RESTful APIs, CDS Clients should audit and report on data access.

### CDS Services

#### JWT

Upon being invoked by a CDS Client, the CDS Service should first process the given JWT to determine whether to process the given request. In processing the JWT, CDS Services should:

1. Ensure that the `iss` value exists in the CDS Service's allowlist of trusted CDS Clients.
2. Ensure that the `aud` value matches the CDS Service endpoint currently processing the request.
3. Ensure that the `exp` value is not before the current date/time.
4. Ensure that the `tenant` value exists in the CDS Service's allowlist of trusted tenants (may not be applicable to all CDS Services).
5. Ensure that the JWT signature matches the public key on record with the CDS Service. See additional notes below.
6. Ensure that the `jti` value doesn't exist in the short-term storage of JWTs previously processed by this CDS Service.

Once the JWT has been deemed to be valid, the `jti` value should be stored in the short-term storage of processed JWTs. Values in this storage only need to be kept for the maximum duration of all JWTs processed by this CDS Service. If the CDS Clients are adhering to best practices, this should be no more than an hour.

Verifying the JWT signature is a critical step in establishing trust of the caller of the CDS Service. As part of the allowlist of trusted CDS Clients, information on the public key(s) used by the CDS Client should also be stored. In some cases, this public key may be shared out-of-band. In other cases, the public key may be available at a remote endpoint and cycled on a regular basis. It is this latter case in which CDS Services should maintain their own rotating cache of public keys for the CDS Client.

CDS Services should never store, share, or log JWTs to minimize the risk of theft and replay attacks. Information within the JWT (for instance, `iss`, `tenant`, `jti`) can be logged safely and is especially useful for analytics.

If a CDS Service deems a JWT to be invalid for any reason, it should not leak the details of why the JWT failed validation back to the caller. If the caller were a malicious threat actor, leaking detailed information as to what was invalid may give the threat actor guidance on how to shape future attacks. Instead, responding to the request with a HTTP 401 Unauthorized response status code without any additional information is recommended.

#### FHIR Access

CDS Services should never store, share, or log the FHIR access token (`fhirAuthorization.access_token`) given to it by the CDS Client. The access token should be treated as an extremely sensitive, transient piece of data.
8 changes: 8 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Change Log

## CDS Hooks 1.1
### Non-compatible (breaking) changes
The CDS Hooks project team strives to not brek backward compatibility between versions of the CDS Hooks specifications to aid both in interoperability
and to prioritize existing implementations. In cases where this isn't possible, changes made in the CDS Hooks 1.1 specification that break backward compatibility are documented below.

* CDS Clients may now paginate search results in prefetch. Previously, CDS Clients were not permitted to return partial search results using the [typical FHIR pagination mechanism](https://www.hl7.org/fhir/http.html#paging). When using prefetch, CDS Services should expect to receive continuation links which enable access to the remainder of the search results over REST.
Binary file added docs/cheat-sheet/CDS Hooks Cheat Sheet.pages
Binary file not shown.
Binary file added docs/cheat-sheet/Cheat Sheet - Sept 2019.pdf
Binary file not shown.
5 changes: 5 additions & 0 deletions docs/cheat-sheet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# CDS Hooks Cheat Sheet

Whether for general development or distribution at events, it's helpful to have a concise "cheat sheet" as a reminder of essential structures and syntax. The [Markdown version](./cheat-sheet.md) in this folder is meant to provide the *source of truth content* for such a doument, leaving further formatting and arrangement up to the consumer.

A rendered version created by [Firely](https://fire.ly/) based on the markdown is also available within this folder and linked to in the navigation section.
186 changes: 186 additions & 0 deletions docs/cheat-sheet/cheat-sheet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# Overview

![alt text](https://raw.githubusercontent.com/cds-hooks/docs/master/docs/images/overview.png "Overview Diagram")

# Links

* Spec: https://cds-hooks.hl7.org/1.0/
* Sandbox: http://sandbox.cds-hooks.org/
* Quick Start: https://cds-hooks.org/quickstart/

# CDS Service Discovery

`GET {baseUrl}/cds-services`

## Response Body

services - An array of **CDS Service**s

### CDS Service: ###

Field | Optionality | Summary
------|-------------|------------
`hook` | REQUIRED | hook this service should be invoked on
`title` | RECOMMENDED | human-friendly name of this service
`description` | REQUIRED | description of this service
`id` | REQUIRED | {id} portion of service URL: {baseUrl}/cds-services/{id}
`prefetch` | OPTIONAL | Object containing key/value pairs of FHIR queries that this service is requesting the CDS Client to include on service calls

## Example

<pre>
{
"services": [
{
"hook": "hook-noun-verb",
"title": "CDS Service Example",
"description": "An example of a CDS Service that returns a card",
"id": "patient-greeter",
"prefetch": {
"patientToGreet": "Patient/{{context.patientId}}"
}
}
]
}
</pre>

# CDS Service Request

`POST {baseUrl}/cds-services/{id}`

## Request Body ##

Field | Optionality | Summary
------|-------------|------------
`hook` | REQUIRED | hook that triggered this CDS Service call
`hookInstance` | REQUIRED | UUID for this hook call
`fhirServer` | OPTIONAL | base URL for CDS Client’s FHIR server
`fhirAuthorization` | OPTIONAL | structure with **FHIR Authorization** information for the above url
`context` | REQUIRED | hook-specific contextual data
`prefetch` | OPTIONAL | FHIR data prefetched by the CDS Client

### FHIR Authorization ###

Field | Optionality | Summary
------|-------------|------------
`access_token` | REQUIRED | OAuth 2.0 access token
`token_type` | REQUIRED | fixed value: `Bearer`
`expires_in` | REQUIRED | lifetime in seconds of the access token
`scope` | REQUIRED | scopes the access token grants to the CDS Service
`subject` | REQUIRED | OAuth 2.0 client id of the CDS Service’s auth server registration

## Example ##

<pre>
{
"hook": "hook-noun-verb",
"hookInstance": "d1577c69-dfbe-44ad-ba6d-3e05e953b2ea",
"fhirServer": "https://fhir.client.com/version",
"fhirAuthorization": {
"access_token": "opaque-token",
"...": "&ltsnipped for brevity&gt"
},
"context": {
"userId": "Practitioner/example",
"...": "&ltsnipped for brevity&gt"
},
"prefetch": {
"patientToGreet": {
"resourceType": "Patient",
"...": "&ltsnipped for brevity&gt"
}
}
}
</pre>

# CDS Service Response Body

Field | Optionality | Summary
------|-------------|------------
`cards` | REQUIRED | an array of **Card**s with a combination of information, suggested actions, and links

## Card

Field | Optionality | Summary
------|-------------|------------
`summary` | REQUIRED | <140-character summary sentence for display to the user inside of this card
`detail` | OPTIONAL | optional detailed information to display (GitHub Flavored Markdown)
`indicator` | REQUIRED | urgency/importance of what this card conveys (`info/warning/critical`)
`source` | REQUIRED | grouping structure for the **Source** of information displayed on this card
`suggestions` | OPTIONAL | array of **Suggestion**s for changes in the context of the current activity
`selectionBehavior` | OPTIONAL | intended behavior of the suggestions. If suggestions present, value must be `at-most-one`
`links` | OPTIONAL | array of **Link**s to suggest an app or other additional information

## Source

Field | Optionality | Summary
------|-------------|------------
`label` | REQUIRED | short, human-readable label to display source of the card’s information
`url` | OPTIONAL | optional absolute URL to load to learn more about the organization or data set
`icon` | OPTIONAL | absolute url for an icon for the source of this card (100x100 pixel PNG without any transparent regions)

## Suggestion

Field | Optionality | Summary
------|-------------|------------
`label` | REQUIRED | human-readable label to display for this suggestion
`uuid` | OPTIONAL | unique identifier for auditing and logging suggestions
`actions` | OPTIONAL | array of suggested Actions (logically AND’d together)

## Action

Field | Optionality | Summary
------|-------------|------------
`type` | REQUIRED | type of action being performed (`create/update/delete`)
`description` | REQUIRED | human-readable description of the suggested action
`resource` | OPTIONAL | FHIR resource to create/update or id of resource to delete

## Link

Field | Optionality | Summary
------|-------------|------------
`label` | REQUIRED | human-readable label to display
`url` | REQUIRED | URL to GET when link is clicked
`type` | REQUIRED | type of the given URL (`absolute/smart`)
`appContext` | OPTIONAL | additional context to share with a linked SMART app

## Example

<pre>
{
"cards": [
{
"summary": "&lt140 char Summary Message",
"detail": "optional GitHub Markdown details",
"indicator": "info",
"source": {
"label": "Human-readable source label",
"url": "https://example.com",
"icon": "https://example.com/img/icon-100px.png"
},
"suggestions": [
{
"label": "Human-readable suggestion label",
"uuid": "e1187895-ad57-4ff7-a1f1-ccf954b2fe46",
"actions": [
{
"type": "create",
"description": "Create a prescription for Acetaminophen 250 MG",
"resource": {
"resourceType": "MedicationRequest",
"...": "&ltsnipped for brevity&gt"
}
}
]
}
],
"links": [
{
"label": "SMART Example App",
"...": "&ltsnipped for brevity&gt"
}
]
}
]
}
</pre>
Loading

0 comments on commit d2c103d

Please sign in to comment.