Is it possible to do authorization / access control in FHIR store?
Let me show one example:
The insurance company receive clinical information from 3 different partners, but the company need to create a different role for each one.
So, the first partner can GET any patients and POST only encounter resource.
Second partner can GET several patients and POST encounters and conditions resources.
Third partner can GET some patients and PUT some elements in conditions resource
Each partner would be responsible for authenticating the insurance company. This might be through mutual TLS certificate verification, OAuth or some other means. Once the insurance company has authenticated, the clinical system would determine what 'authorization' the company had. Every data source has full control over determining what a given requester has authorization to receive. Ideally, the server will expose a distinct CapabilityStatement to the requester after they've authenticated that reflects what they are allowed to do. Any requests that are not permitted will result in an appropriate error or will result in the data returned being appropriately filtered. The determination of what sort of filtering happens is managed by internal business rules and is not defined by FHIR, though in some cases, FHIR resources such as Contract or Consent may include terms that will influence the filtering.
Related
Let's say we have a simple food delivery app. Where client order the food, then restaurant start preparing the food and gives it to the courier who delivery it to the client.
So here we have three different domains and each of this domain have their own order:
client - here client order the food and have the status of the food in preparation | in delivery | delivered
restaurant - here restaurant got its order and has their own status in queue | in preparation | ready to pick up
courier - courier has only two status delivering | delivered
Moreover each of this domain has their own price and other attribute about order:
client - total price (food price + delivery cost + fee)
restaurant - price of food, time of production to give a hind to the client when food will be delivery
courier - cost of delivery
All I want to highlight is that each of the domain has its own order aggregate, so according to DDD we have to keep it in different aggregates even in different microservices:
client - /orders/:id provides the general status of the order and total price to the client.
restaurant - /restaurants/:restaurantId/orders/:id provides the status of the food in restaurant domain and cost.
courier - /couriers/:courierId/orders/:id provides information how much courier earn from this order and how long it took to delivier
But now I met another problem, because client order combines information from other domains (is food still in restaurant or it's being delivery) so I have to gather this information when client asks about its order, but it means that client doesn't have its domain (its own aggregate, total price, discount etc), but if I create order aggregate for the client then I will not keep all information about order in one place (when restaurant give the food to the courier it should also change status of the order in client domain) what is not really according to microservices, because we keep information about the same order in different microservices.
Should I just create one order domain or should I split it to different domain and make these domains communicate between, when something will change in one domain?
One useful approach is to leverage domain events. When the restaurant's view of the state of the order changes, an event describing that change is published. The other services can then update their model of the event (assuming that that change is relevant to that service).
So for instance, we might have:
user creates order via the client service => OrderCreated event emitted
restaurant service consumes OrderCreated event, translates the order for the restaurant (e.g. uses the prices which the delivery app pays the restaurant vs. the prices the delivery app charges the user) => OrderSentToRestaurant event emitted
courier service consumes OrderCreated and begins trying to figure out which courier will be assigned the order and the approximate transport time from pickup to delivery => DeliveryLatencyEstimateMade event emitted
client service consumes OrderSentToRestaurant and updates its order status (for presentation to the user) to in preparation
courier service ignores OrderSentToRestaurant
restaurant service ignores DeliveryLatencyEstimateMade event
client service consumes DeliveryEstimateLatencyEstimateMade and updates its model (delivery time remains unknown)
restaurant informs restaurant service of expected completion time => OrderReadyForPickupAt event emitted
courier service consumes OrderReadyForPickup, refines courier assignment decisions
client service consumes OrderReadyForPickupAt event, combines with the latest latency estimate to present a predicted delivery time to the user
and so forth. Each service is autonomous and in control of its data representation and free to ignore or interpret the events as it sees fit. Note that this implies eventual consistency (the restaurant service will know about when the order is expected to be ready for pickup before the courier or client services know about that), though microservice autonomy already effectively ruled out strong consistency.
When looking at aggregate design in each bounded context (BC), you have to include only the data required to provide the functionality that belongs to that BC. The fact that the restaurant endpoint needs to return some extra data is not a good enough reason to add that data to the order aggregate in that BC.
You can resolve the need for more data in different ways:
The API client can call multiple endpoints to fetch all the data it needs
The API can implement Data Aggregation, by internally querying multiple BCs/microservices and combining them to produce a single more complete response object
Create Read models, which store data from multiple sources into a single "table" in a way that simplifies querying and returning this data. This approach is more complex, but it's very useful when you need to filter and sort by fields belonging to multiple BCs, which is not possible with the previous two approaches.
Another consideration to make is double-checking if your boundaries are correct. Do you really need a Client BC? What business logic does it implement? Maybe Orders are created directly into Restaurant and there is no Client order? Client order could just be a "façade" providing all Restaurant orders belonging to a single client Id?
As a final note, I completely agree with Levi Ramsey's answer that events are the right way to coordinate the different aggregates. They would also be used to create the read models I mentioned above.
I'm in the early stages of integrating Square payments. It makes sense in my application to allow users to save their card details, as we expect multiple small transactions. Square calls this feature 'cards on file'.
As part of this process you create a customer and a related card in Square's system; IDs for these will be held in my system and associated with my users; that way when they come to pay again they can select the option of using a card on file. The API to actually charge the card simply takes these two IDs and an amount.
What worries me is that my database is holding all the data necessary to charge a customer's card; I could write a script which just charges all of my customers an amount of money - naturally a hacker with access to my data could do the same thing.
I wasn't expecting to have this level of risk in my system - my assumption was that Square would have isolated me from this (via some sort of user challenge for missing data - e.g. the CCV number). It seems the safe option is to not use the 'card on file' feature and have the user re-enter every time.
Is this right, or have I completely misunderstood something here?
In order to charge a card, your Square access token is required along with the card ID. It's best practice to store that access token as an environment variable in order to limit the security risk. If someone gains access to the card IDs in your database, they won't be able to charge any of the cards without that access token that's associated with your developer account.
I did miss something - as any charge made on a customer's saved card is credited to my account (as configured in the Square portal), the only beneficiary of any fraudulent charge would be be me. A hacker could not get access to funds and therefore the risk is limited in scope.
Obviously if I was a fraudulent company there would be a risk to users - it seems the EU isn't happy with this and changes coming this year will require additional information to be captured from the user at the point of sale.
Strong Customer Authentication
In the context of a Microservice architecture, a single business operation can require collaboration between two or more services.
Suppose we have an Order Management Service and a Product Catalog Service.
When the user adds an order item to an order, the Order Management Service will persist a OrderItem object which have the following attributes among many others :
OrderItem
+ Id
+ ProductId
+ ProductName
In order for the Order Management Service to fill the ProductName attribute, we have 4 choices as I see it :
Choice 1 : ProductName is given by the client app as it probably already has this data from previous requests
Choice 2 : If the architecture uses an Api Gateway, the gateway will be responsible for retrieving the ProductName from the Product Catalog Service then provide it to the Order Management Service.
Choice 3 : The Order Management Service will call directly the Product Catalog Service and asks him for the ProductName givent a product id.
Choice 4 : The Order Management Service has a duplicate (but not exhaustive) product informations in its own database and these datas will be updated each time an update event is received from the Product Catalog Service.
Among these 4 choices, the n°1 seems not ok to me as we can't trust the client to give us a correct and updated value of ProductName.
I would like to have your opinion about what you think the best choice is and why !
Thanks !
Riana
Choice 1 : ProductName is given by the client app as it probably already has this data from previous requests
Like you said, it is not the best idea because the client may have stale information. Maybe acceptable if the product information changes infrequently and/or you have a secondary verification at order processing.
Choice 2 : If the architecture uses an Api Gateway, the gateway will be responsible for retrieving the ProductName from the Product Catalog Service then provide it to the Order Management Service.
IMHO, this is not a good idea. By doing so your domain/business logic will leak into the API Gateway. The gateway now knows the relationship between Orders and Products. This API gateway configuration/scripting will need to be maintained and introduces additional coupling.
Choice 3 : The Order Management Service will call directly the Product Catalog Service and asks him for the ProductName givent a product id.
This is my preferred choice. Though I do not recommend "direct" synchronous calls. Perhaps a retrieval of the ProductName via a messaging mechanism (message queue, event bus). Chained synchronous calls will reduce the availability of your services. You can find more information at Microservice Messaging Pattern.
Choice 4 : The Order Management Service has a duplicate (but not exhaustive) product informations in its own database and these datas will be updated each time an update event is received from the Product Catalog Service.
Data duplication is generally frowned upon unless there is a really good reason for it. In this case I don't see any. Why bother splitting the databases into two for each of the services yet duplicate the data between them? Also, to have the data updated each time an update event is received indicates that some kind of event/messaging infrastructure is available, in that case, why not just use messaging?
This duplication may be justifiable for high volume, low latency look ups, but it is a slippery slope that may end up with duplicated data all over your services. Imagine the repercussions of a length or type/format change of the ProductName string...
I have an app that uses Parse as its backend, and has Stripe integration. On Parse, I store a Stripe customer id on my User class, and I have a custom class that has a charge token associated with it, so that a customer can create a service request, and when a provider accepts and fulfills that request, they can have the charge be sent to their recipient id.
A user could cancel the service request, or a provider could show up to the user's property and find that the property is unserviceable for various reasons. In this event, we have a cancellation fee that the users are charged.
I want to make sure that if the cancellation fee is charged, it gets charged to the same card that the user used to request the service. I noticed that when I fetch all of the cards from a customer id, they always show up in the same order, but when I add a card, it doesn't always add it to the end of the array that gets returned when I fetch cards. So, if I just stored the index of the card, a user could add a new card, and it would possibly take the place of the one that was being charged for the service. If I charged a card based on the index for a cancellation, it could charge the incorrect card. Would it be PCI compliant to store the cardID used to create the charge token on the Parse object that contains information about the service, so when I call my functions to create cancellation charges, I'm charging the same card?
Thanks for anyone who can provide some information on this.
The only sensitive data that you want to avoid handling is your customers' credit card number and CVC; other than that, you're welcome to store any other information on your local machines.
As a good rule, you can store anything returned by our API. In particular, you would not have any issues storing the last four digits of your customer's card number or the expiration date for easy reference.
from: https://support.stripe.com/questions/what-information-can-i-safely-store-about-my-users-payment-information
does api validate balanced payment
social security number
address
account number
legal name
EIN
Date of birth
if yes, then how??
There are a two separate validation processes, one that occurs on the Customer resource and then on the Funding Instrument.
1) Customer
For customer identity verification: https://docs.balancedpayments.com/1.1/overview/resources/#customer-identity-verification
The customer identity verification is run through a 3rd party identification service each time the customer resource information is saved or updated, and is pertinent to underwriting merchants that are being paid out to.
2) Funding Instrument
For address verification: https://docs.balancedpayments.com/1.1/overview/resources/#address-verification-service-avs
Furthermore the Name, CVV, Postal_code, and Country Code fields are critical to reducing both fraud and declinations. These fields are checked by the banks, but do not result in hard failures. More info can be found here: https://docs.balancedpayments.com/1.1/overview/best-practices/#reducing-declined-transactions
Please note that even if a customer object has name or address data this is not passed on to the card object when associated.