0

Lets say we have a microservice architecture consisting of:

  • multiple frontend clients, e.g. an Android App, an iOS App, and a Javascript Web Frontend
  • a Java Spring (HTTP Rest) microservice to access user data
  • a Java Spring (HTTP Rest) microservice to access application data
  • a keycloak authentication microservice

Lets assume that all of this works fine with the backend microservices deployed in the cloud. Now, we want to create a desktop application. This desktop application should also work when the user does not have access to the Internet, given that he had Internet access before at some point.

Reusing the Javascript Web Frontend in the Desktop application is quite easy with Electron, that should not be a problem. In theory, we could ship the Electron app with the jar files of the Java Spring backend services, and let the Electron app start these in a background process (given that the user has Java installed). Then, after authenticating with the authentication microservice in the cloud, the app would have to download the user and application data and store it in a local database, e.g. a file-based SQLite DB. The backend microservices running locally would use this local DB as a source, therefore they are able to work without Internet access.

Is this a sensible approach for converting an existing web/mobile application to a desktop application with reasonable effort?

My thoughts on this are:

  • Reusing a lot of code is super good, especially because the tasks of the Java Spring microservices would be exactly the same locally as in the cloud

  • Requiring the user to have Java installed is not so good, it kind of ruins the nice Electron experience where everything is self-contained

  • In reality, there might be more microservices, including stuff like Consul, maybe requiring the user to have more stuff installed. Running all of that on the user's machine might be a overkill, also might be quite bad for performance

15
  • 1
    This is a question to ask the application's stakeholders - the issue about whether or not to deploy something on a user's own device is something which affects users and whoever is tasked with supporting those users, so needs to be driven by business need and stakeholders understanding the implications of the choices they have available – Ben Cottrell Apr 28 at 9:48
  • 1
    @BenCottrell: "the issue about whether or not to deploy something ... needs to be driven by business need and stakeholders" - that is true, but if I understand this correctly, the OP is not asking if those requirements make sense, but if the suggested architecture makes sense to realize these requirements. And the architecture of a system is usually not what the business side is going to decide on their own. – Doc Brown Apr 28 at 13:17
  • 1
    I took the freedom and reworded your question a little bit (which is IMHO a very valid one), to keep the nitpickers satisfied - hope this helps. – Doc Brown Apr 28 at 13:35
  • 1
    @RobertHarvey: you may have noted, I edited the "popularity" part out of the question. For me, this post looks like a valid question about software architecture, asking more for expertise than opinion on this topic. If you have any suggestions how this can be more streamlined to this site's format, feel free to suggest (or make some edits on your own). – Doc Brown Apr 28 at 13:54
  • 1
    @DocBrown: You already know my stance. Questions that include words like "sensible," "good," "best practice" or "most likely to win a beauty contest" are unanswerable unless the OP can state specific criteria or objectives." – Robert Harvey Apr 28 at 13:56
4
+100

Architecture

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...

Constraints

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.

1
  • Thanks for the detailed answer. "Architecturally speaking," was what I needed to hear. You address some key points. In fact, I do not plan on shipping the whole microservice architecture, but only a subset of it. Also, I already thought about this middle man, managing online/offline state, synchronising data. For additional features in the UI, I already have a concept, too: the main web frontend only will only be a subset of the desktop application. What are your thoughts on user authentication and data security with a local offline file-based db? – Sebu May 4 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.