Coder Social home page Coder Social logo

awslabs / fhir-works-on-aws-authz-smart Goto Github PK

View Code? Open in Web Editor NEW
31.0 8.0 20.0 857 KB

A SMART on FHIR v1.0.0 implementation of the FHIR Works on AWS framework, utilizing OAuth2/OIDC authorization server to authorize requests

License: Apache License 2.0

JavaScript 0.92% TypeScript 99.08%
hl7 fhir healthcare nodejs aws typescript fhir-works smart

fhir-works-on-aws-authz-smart's Introduction

fhir-works-on-aws-authz-smart

This GitHub repository has been migrated. You can now find FHIR Works on AWS at https://github.com/aws-solutions/fhir-works-on-aws.

Upgrade notice

Versions 3.1.1 and 3.1.2 of the fhir-works-on-aws-authz-smart package have been deprecated for necessary security updates. Please upgrade to version 3.1.3 or higher. For more information, see the fhir-works-on-aws-authz-smart security advisory.

Purpose

This package is an implementation of the authorization interface from the FHIR Works interface. It uses the Substitutable Medical Applications, Reusable Technologies (SMART on FHIR) specification v1.0.0 to authorize users. Requests are authorized if the requestor or the patient in context is referenced in the resource in question.

To use and deploy this component please follow the overall smart-mainline branch README

Assumptions

The following assumptions have been made while creating this package:

  • An OAuth2 OpenID Connect authorization server already exists and is used as, or in conjunction with, an identity provider.
    • The OAuth2 server complies with the SMART on FHIR specification
    • The OAuth2 server has a JSON Web Key Set endpoint used to get the key for verifying incoming access tokens
  • The identity provider has a user claim (either fhirUser or profile) representing who this user is in context to this FHIR server. This user must be represented by a fully qualified URL in the claim.
    • As an example, the fhirUser claim should look like: https://www.fhir.com/Patient/1234
    • When using user scopes it is assumed that the fhirUser will be in the access token to determine who the requestor is
  • launch scopes and contextual request will be handled by the authorization server.
  • Once launch context is given to the authorization server it will be included with a patient scope and the Patient's resourceType and id in the launch_response_patient claim within the access token.
    • As an example, the launch_response_patient claim should look like: Patient/id

Authorization

This packages uses SMART scopes and the references found in the resources as a way to determine access. Scopes are used to tell the authorization and resource server what access the requestor has. In addition, the references are used to do further authorization, in an attribute based access control model.

Scopes

This resource server supports SMART' v1.0.0 clinical scopes. There are some assumptions made on the authorization and resource server relationship:

  • For patient scopes, there must be a launch_response_patient claim in the access token.
  • For user scopes, there must be a fhirUser claim in the access token.
  • The access modifiers read and write will give permissions as defined in the incoming SMARTConfig.

The resource server also supports SMART's Flat FHIR or Bulk Data system scope. system scopes have the format system/(:resourceType|*).(read|write|*)– which conveys the same access scope as the matching user format user/(:resourceType|*).(read|write|*).

Attribute Based Access Control (ABAC)

This implementation of the SMART on FHIR specification uses attribute based access control. Access to a resource is given if one of the following statements is true:

  • The fhirUser making the request is considered an Admin (default configuration makes a Practitioner an admin).
  • The fhirUser making the request or the patient in context is looking up their own resource (verified via the resourceType and id).
  • The fhirUser making the request or the patient in context is referenced in the resource in which they are taking action on.

As an example below, the Patient resource is accessible by:

  • Admins of the system
  • Requests with the usage of the system scope
  • Patient/example: via resourceType and id check
  • Patient/diffPatient: because it is referenced in the link field
  • Practitioner/DrBell: because it is referenced in the generalPractitioner field
// Example Patient resource with references
{
  "resourceType": "Patient",
  "id": "example",
  "generalPractitioner": [
    {
      "reference": "Practitioner/DrBell"
    }
  ],
  "link": [
    {
      "type": "seealso",
      "other": {
        "reference": "Patient/diffPatient"
      }
    }
  ],
  "address": [
    {
      "period": {
        "start": "1974-12-25"
      },
      "city": "London",
      "use": "home",
      "line": ["221b Baker St"],
      "district": "Marylebone",
      "postalCode": "6XE",
      "text": "221b Baker St, Marylebone, London NW1 6XE, United Kingdom",
      "type": "both"
    }
  ],
  "deceasedBoolean": false,
  "name": [
    {
      "family": "Holmes",
      "given": ["Sherlock"],
      "use": "official"
    }
  ],
  "gender": "male",
  "active": true
}

Usage

Add this package to your package.json file and install as a dependency. For usage examples please see the deployment component's package.json

Configuration

The SMART specification gives a lot of room for interpretation between the resource and authorization server relationship. With this in mind we developed our SMART implementation to be flexible. The configurations currently available can be viewed in the SMARTConfig.

SMART on FHIR scope rules

Within the SMARTConfig you can see an example implementation of a ScopeRule. The ScopeRule says which operations a scope gives access to. For example, the user/*.write scope provides access to 'create' resource but not 'update' resource.

For an example usage of the SMARTConfig, please see authZConfig.ts in the deployment package.

Dependency tree

This package is dependent on:

Known issues

You can track the issues on the GitHub repository.

Security

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.

fhir-works-on-aws-authz-smart's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fhir-works-on-aws-authz-smart's Issues

Scopes are not filtered on search-type

Hi! I'm having an issue in this lines which changes on this #79

if (resourceType === '*' || resourceType === reqResourceType || reqOperation === 'search-type') {

This is my use case:

        const clonedScopeRule = emptyScopeRule();
        clonedScopeRule.system.read = ['search-type'];
        expect(
            filterOutUnusableScope(
                ['system/DocumentReference.read', 'system/Patient.read'],
                clonedScopeRule,
                'search-type',
                false,
                'Procedure',
            ),
        ).toEqual([]);

If the user claims for this scope system/DocumentReference.read system/Patient.read but ask for a Procedure resource, the filterOutUnusableScope mark both scope as usable and then the operation is allowed.

[Misc] token revocation

Hi!
I want to know if you have something about token revocation? I know that is a task for the authentication server but when a revoke a token i can still use it against the API because there is not any communication between the fhir server and the auth server.

Thanks

SMART Authz Verify Bulk Export 'cancel-export' and 'get-status-export' incorrectly

When the requester tries to verify their access token for cancel-export and get-status-export operations, the verification fails.

get-status-export and cancel-export doesn't have an export type associated with it.
https://github.com/awslabs/fhir-works-on-aws-interface/blob/ef6e2251476ac520e7395e608c79c56db0e6270e/src/utilities.ts#L95

isSmartScopeSufficientForBulkDataAccess expects exportType to equal system

const bulkDataRequestHasCorrectScope =

Determine what the required scopes for cancel-export and get-status-export should be. Should those two operations only require scopes to access the user's id? Later in the verification process we use the user's id to authorize that they can cancel an export or get an export's status.

Related: FHIR-509

[Bug] _include issue when system scopes are not set to *

Describe the bug
An issue occurs when we have specific system scopes specified (Ex. system/DocumentReference.read and system/Patient.read, no system/*.read it will only return the resource that was requested and it filters out all of the included resources.

Example: We request a DocumentReference and do an _include to get the Patient resource.

If we have system/DocumentReference.read and system/Patient.read as scopes, it will only return the DocumentReference resource. If we have system/*.read it will return both. It appears to be in the getValidOperationsForScope function in smartScopeHelper.ts. The hasAccessToResource function filters the included Patient out because only DocumentReference is in the usable scopes.

Expected behavior
The expected result would be for it to check against the full list of scopes to see if it was valid.

Making custom health card operations

My team is trying to make a SMART Health cards implementation using FHIR Works. As part of the implementation, we need an ability to create custom extended operations, so that we can issue health cards as part of a Patient request (POST /Patient/:id/$health-cards-issue). Has anyone done this before? Or can provide some guidance on how to accomplish such a task?

The pattern we're following is defined here:
https://smarthealth.cards/#via-fhir-health-cards-issue-operation

[Misc] Default configuration makes a Practitioner an admin

What's on your mind?
The default configuration makes a Practitioner an admin. Could you tell me how I can change the configuration in order to make a Practitioner not an admin ?

Thanks in advance

Versions (please complete the following information):

  • v2.2.2

Installation instructions

For installing this it says...
To use and deploy this component (with the other 'out of the box' components) please follow the overall README

...which doesn't make mention of the SMART auth.

I do notice a branch called authz-smart. Are the instructions to switch to that branch then run the install? Any other things to keep in mind?

Assumptions met but requests are unauthorized

I am using v3.1.1 from the deployment package version v2.4.0-smart from the smart-mainline branch. I created the example patient resource in the README and I have attempted a few ways to do a GET on the Patient resourceType.
 
Based on the README, my request should be accessible due to the claims in my access token. Also the scopes in my access token patient/Patient.read maps to scopeRule.patient.read operations. So I am unsure why my requests are coming back as unauthorized.

My claims:
"launch_response_patient": "Patient/example",
"fhirUser": "https://xxxxxxxx.execute-api.us-west-1.amazonaws.com/sandbox/Patient/example"
 
My Scopes:
  "scp": [
    "fhirUser",
    "openid",
    "patient/Patient.read",
    "launch/patient",
    "profile"
  ],

Request:
Request: GET https://xxxxxxxx.execute-api.us-west-1.amazonaws.com/sandbox/Patient/example?access_token=eyJ
 

 

Allow for the FHIRUserClaim and PatientContextClaim to be pulled from other than root of token

Is your feature request related to a problem? Please describe.
Our auth server only allows for these to be placed under the ext section of the token.

Describe the solution you'd like
Allow for a path to be placed as a variable or coded so it can easily be added or changed if needed for other auth servers.

Additional context
Currently it is like this const fhirUserClaim = decodedToken[this.config.fhirUserClaimKey]; for our auth server to work we would have to use const fhirUserClaim = decodedToken.ext[this.config.fhirUserClaimKey];

Restricting practitioner access to only DetectedIssue Resource if Patient belongs to certain organization

What's on your mind?
A practitioner is given admin access currently but we can remove it by setting adminAccessTypes = [] for that. Further, I have added a claim in the token as
patientOrgsClaim=Organization/<org_id_1>, Organization/<org_id_2>.

Now I want to restrict practitioners to have only access to DetectedIssue resource if Patient belongs to certain organization as the following API call:
{{API_URL}}/DetectedIssue?patient:Patient.organization=Organization/<org_id_1>,Organization/<org_id_2>

Any idea if that is possible and what would you suggest looking at to achieve this restriction on the practitioner?

Thanks.

Versions (please complete the following information):

  • v3.1.0

[Bug] Incorrect total value returned from authorizeAndFilterReadResponse

Describe the bug
When the authorizeAndFilterReadResponse function runs it does a check to determine whether the user access by the hasAccessToResource function. If they do not it removes it rum the array. The return shows a total of 4
"type": "searchset", "total": 4,
But in the entry section there are only 3 records.

Expected behavior
The total should match the number of entries being returned or potentially have another value that shows it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.