How can I distribute zrok.exe in a safe way?

How can I distribute zrok.exe in a safe way?

Ok, I don't know if I'll be able to be clear in what I'm trying to do, but I'll try.

I have a server application, a backend, that runs within my clients' local network, I have several clients that use this same application. But each has its own self-hosted instance. In cases where this application needs to be accessed via the internet, and to avoid NAT configurations on the router, use of VPN and things like that, I am testing with Zrok. My idea is to distribute zrok.exe along with my application, and make the execution of zrok commands automated. So to start the application I execute:

zrok enable XXXXXXX (if not already enabled)

zrok reserve public http://localhost:3000 (if not already reserved)

zrok share reserved

And everything works as expected.

But then I'm noticing some details that worry me.

I wouldn't want to have to create a new account for each customer I serve with this solution, so I would use the same zrok enable for everyone. I think this token could only be known by my application.

But I noticed that after running zrok enable on a computer, this token can be easily viewed using the zrok status --secrets command, or by accessing the environment.json file in the user's .zrok folder.

I also noticed that when running the zrok overview command, I am getting the environments and shares information for everything that belongs to my account, and not just the information regarding the machine I am running.

So here are some questions:

Is there any way to use the zrok share reserved command and pass the enable command token at the same time, so that this token is not accessible so easily?

Is there a command similar to the overview, or filter, that only returns information relating to the host that is executing the command

I hope I was clear!

And thanks again for your attention.

1 Like

Hello!

I would definitely not recommend reusing a single account token (the token provided to zrok enable) for multiple users. It would be much better to have a separate account token for every user in your application. That's how zrok was designed to be used.

I don't know that I've got an easy answer for you with regard to making the account signup any easier if you're using the hosted service instance at zrok.io, but if you're self-hosting, then creating a new account for the user is simply a matter of inserting a row into zrok's accounts table. In general, it sounds like you might need a different workflow for onboarding your users.

I'm not sure that there's a good way to really secure a single account token shared amongst multiple users. And if you're not self-hosting, then you're going to run up against the environment and shares limits anyway... I believe both are currently limited to 35 on zrok.io. So, after 35 shares, you won't be able to create more within a single account.

The zrok overview command is designed to enumerate the contents of a single account. That is by design. zrok refers to a single zrok enable (an account on a machine) as an "environment".

There is not currently an easy way to pass all of the necessary details (it's not just the account token, it's also the environment details, etc.) to run zrok share reserved without that structure being present on disk. You can override the HOME environment variable on linux/macos and a different environment variable on windows, and you could temporarily write the contents to disk, to run the command, and then remove it after the command is launched.

zrok is not really currently designed to try to defend the account token from the user. It's considered the user's secret.

No, there is not currently an overview command with an environment scope. In a future version, we'll be looking at more flexible inventory calls in the API.

I don't know if we have an SDK language that matches your application... but you might also consider taking a look at the SDK and possibly building something more tailored to what you're trying to accomplish. The zrok CLI itself uses the SDK, so it's a very good example of what's actually happening in the software.

Thanks @michael.quigley ,

His words cleared up some doubts and helped me better rethink the path I wanted to follow. I will adopt the idea that each customer must have their own account to use the network.

1 Like

Really glad I could help!

If you need to brainstorm any more on it, feel free to reach out. Would be happy to discuss further...

And if you run into anything problematic, we might be able to make adjustments to zrok if it makes sense to...

Ok @michael.quigley, some things that would help me integrate my applications with the zrok executable. Because these applications are developed in Delphi, which does not have an official SDK like C#, Pyton, etc., so my application is using shell commands to interact with zrok.exe and execute the necessary commands to share the endpoint.

I would like the invite command to be able to be called without requiring the user to enter the two email fields and press submit, so I could do the invite through my interface, through a single shell command.

Another thing would be to be able to pass as a parameter to rzok.exe, the path to be used for the environment files such as .zrok\environment.json.
Currently it is using the USERPROFILE environment variable, this hindered me a little when I needed to have more than one application, and consequently more than one zrok running on the same server, with different environments, and also when running zrok as a Windows service, because then the USERPROFILE variable may not contain the same path as when zrok is not running as a service. I managed to overcome this by modifying the USERPROFILE variable before each execution of zrok commands, but it was somewhat laborious due to the way in which Delphi interacts with the Windows API to execute shell commands. If I could specify where zrok should read the environment settings from, it would be easier.

Thanks!

The best way to accomplish this in your application is to just call the /api/v1/invite endpoint directly from your code without shelling out to zrok.exe. It's a simple HTTP POST that takes an email address in a JSON object:

Unfortunately that's probably not going to be something we'll address until we get to the next major revision of zrok (the v0.5.x series). Using USERPROFILE (or HOME on unix-like systems) is the best and most reliable way to set that path across all platforms.

Hope the first one helps. Sorry the second one will be a while before we can address it.