Architecturally speaking, this is in fact a good system.
When you zoom out a microservice architecture to the platform level what you have is (hopefully) a very modular and resilient monolith connected by a communication medium. Taking all of that and wrapping it up with a bow for a desktop machine is definitely possible, and will probably make for a decently architected desktop app.
That being said...
The first set of issues to handle are scale and resourcing - A desktop does not a server-farm make.
You can address this in part by:
- not shipping the entire platform to the user desktop
- substituting in lighter weight components
Not shipping the entire platform to the user desktop is obvious if the main thrust of the app relies on:
- Terabytes of data,
- hundreds of specialised processors,
- a super-secret trade secret,
- and/or expensive to licence software components.
This is where it make sense to ship a middle man which operates a cache and some smarts for manging this offline state. The problem is how you synchronise this data when you go back online.
- Does the cache win?
- Does the server?
- Is it a mix of both?
- Does the user get a say, and if so how? This is an interface that's not part of the normal UI you are shipping.
Substituting in lighter weight components, can make a real performance difference. Obviously that enterprise grade sharded sql server farm, is overkill for most users. Substituting in SQLite, or another more portable engine is not just a good idea, but necessary. This will be much harder if you've bought into proprietary sql dialect™. Perhaps you need to provide different "repository" implementations within you services to abstract this away.
Privacy & Security
There is also the difference of the desktop being Not Your Machine. Which opens up the can of worms about user privacy.
As a website your app operated in a sandbox, with heavy sets of restrictions on what it could and couldn't do. Even what it could and couldn't see. The servers ran on Your Machine where monitoring and data collection are just good sense.
That isn't going to work for you as a desktop app. You have access to a lot more information. Information about the users computer, and about the user themselves like: their files, OS, contacts, internet access, CPU load, and stored credentials.
Worse you have access to more capabilities like: their printer, monitors, file system, and a network connection that isn't locked down. What before you had for free by being sandboxed, you are now going to have to enforce yourself, like being a good citizen in the File system, and not spamming the printer.
You are going to need to reconfigure, if not comb out all of these data feeds, ensuring that you aren't inadvertently snooping. Along with enforcing those good desktop citisen policies.
- On Your Machine, this is just good practice.
- On Not Your Machine, its malware.
Authentication and Authorisation
Keep Authentication on your own servers, don't even try to localise it. Any attempt necessarily means leaking information about the users password/certificate/magic string to the local machine which if its like most user machines, is very insecure.
Authorisation though, now that's a different picture. You can wrap the authorisations up inside a serialised token, and sign it with the servers private key. You probably are already doing this for at least the web app to the api, perhaps even through the microservices to the back-end services. Leverage that, or put it in place.
If you add a public key to the token, (the server keeping the private key). Data returned by the API can be encrypted on a record level. This way you can allow a stream to to the local app to ship data for two or more users. You can be certain that the specific user has access to the specific data because only that user has the key. Keep that data in this encrypted state at rest too.
You can additionally use the stored key to encrypt locally generated data for shipping to the server. The server can then prove that the specific user created that data. And locally your own app can prove what it made, what it received, and by whom. Any injected data will simply not be correct.
If encrypting the data isn't that important, use a signed secure hash instead. This way changes to the data can be noticed, as can data inserted by other processes.
To make this as fool proof as possible the token needs to be encrypted at rest on the users machine using the local encryption primitives leveraging the local user management of the machine. This ensures a copied database cannot be copied away and trivially decrypted.
Unfortunately this does not make it impossible for someone to manipulate the local database. The local machine security, the certificate, and the application logic are all stored on the local machine.
- A user can decrypt their certificate manually
- A user can create a new local account and encrypt their own certificate locally and place it in the database
- A user can delete hashes and replace it with their own signed hash
- A user can manipulate the program logic itself, by editing the binary, or debugging it.
So the short of it is:
- Don't ship data to the local machine/Web app that you don't want anyone else on that machine from accessing.
- Verify any and all data coming back from that machine/web app when it hits your servers, don't presume the microservices in front have verified anything.
Note: I'm not a security expert, they will be much more aware of the pitfalls, and strategies for encrypting/hashing/signing data. The above is a broad stroke description of a multi-user financially orientated application with a local database and cloud service.
Of course if the data isn't your data, and isn't sensitive from your own perspective. There isn't any reason to not just keep it in the clear and leverage the local OS permissions and user management. Each OS is a little different on how to do this, but you can usually make it only read/writeable from the current user account. If it needs encryption, the local OS usually offers a key management, or a service for encrypting data with a local secure key.