I would like to share a project that I have been working on called open-balena-admin, which is a compilation of three separate but related projects: open-balena-ui, open-balena-remote and open-balena-postgrest. The
open-balena-admin platform consists of a web interface and back-end supporting services which integrate with
open-balena and provide the following functionality:
- Support for multiple organizations and users in open-balena
- Remote access to devices (ssh, vnc and http into host or containers)
- Fleet / device management (create fleets, add devices, manage variables / tags / labels)
- Support for creating and managing custom device types
- Device management dashboard
- Remote device diagnostics
open-balena-admin project includes
docker-compose build scripts, which mirror the
open-balena build process, and build instructions can be found on the github page. The project also includes
helm scripts for kubernetes deployment environments which follow the same format as bartversluijs’ helm project for open-balena.
Currently this project only scratches the surface of what is possible with this type of interface. It also has a number of gaps / issues which I could use help from the
open-balena community in addressing, specifically permissions and enhanced security. While I will continue to build it out and post updates, please do let me know if you are interested in contributing to this project as it would greatly accelerate the effort. Otherwise, I am happy to offer this back to the community which we have derived so much value from over the last few years.
This looks awesome!
Great work, I like the multi-tenant solution. How did you implement this, is it an extra layer on top of openbalena?
I can also see each user can be given different permissions?
open-balena-admin actually uses the native
open-balena-db database via a PostgreSQL REST interface. So any org or user that is created in
open-balena-admin can log in and execute commands via
balena-cli, make API calls via
open-balena-api, etc. Same thing goes for fleets / devices you add in
open-balena-admin, API keys you create, env vars, etc. - they are all just part of native
open-balena despite being managed by
open-balena-admin. For the users you create, you’ll need to make sure that they have sufficient permissions to perform the actions you are doing using the other interfaces, since
open-balena-api, etc. honor those permissions.
Damn David, this so impressive!
@dtischler @mpous @Maggie You gonna need to see this!
WOW!! This projects VERY impressive @drcnyc!
I will take a closer look at it today, and we’ll also make sure we let the community know as well!
And thanks for the ping @nmaas87
I’ve also dumped the database once to take a look at the structure. What a monumental task and it enables pretty useful features in openbalena. It’s also an amazing project from a security standpoint, now I don’t have to fiddle around with some scripts/the API to revoke an API key and can just use this nice web interface.
Do you know how to create a user that only has access to fleets and devices of a certain organization? If that is possible, it means multi-tenancy can be achieved which would be awesome.
This is incredible work, @drcnyc !
@nmaas87 @dtischler @pranavpeshwe I appreciate your kind words, but at the end of the day this is just icing on the cake, and none of this would be possible without
open-balena - the amazing product your team has built. And obviously your decision to make it available to the open source community. Thank you!
@GoogleIt what I found to be really helpful was the sbvr file in
open-balena-api, which once you get your head around it becomes a great roadmap. Regarding multi-tenancy, it’s really only partially implemented at the moment. You can create users that have all of the standard balena permissions - but these permissions are only relevant when utilizing the web interface of
balena-cli, which apply those permissions. I suspect what you are looking for is the ability to log in to the web interface and only see your own devices, etc. That will require interpreting those same permissions in
open-balena-ui, which currently the groundwork is there to do, but it needs some heavy lifting. For example, following a successful login,
open-balena-ui currently stores the permissions of the logged in user in the browser’s localStorage, along with the client side JWT secret to validate them. The
react-admin framework that
open-balena-ui utilizes has some nice permissioning features that could be utilized to interpret these permissions and hide/show areas of the ui appropriately. But we would also need to build this logic into the
open-balena-postgrest proxy (which currently just confirms the user is authenticated, and provides full access if they are), to ensure that back end calls are filtered based on those permissions as well. If you’ve got the interest and some spare time, I’d love some help with this! If not, it’s definitely high up on my to-do list…
Impressive work in that dashboard. I do really like how nicely the SSH terminal and the https “terminal” renders the device’s https application. Well done and nice to see you jumping into the SBVR file.
Just a little background on the SBVR file. It’s the data model description that is used by the open source project GitHub - balena-io/pinejs: Generate rest APIs from natural language models to automatically generate a full OData API from the data model and understand valid OData request to the database. Pinejs comes with a database level permission system, I can highly recommend to check the pinejs documentation for CustomServerCode.
Well done @drcnyc !
@fisehara I appreciate the additional guidance here. The SBVR format is great - and I saw how you guys are able to convert it directly into SQL code to generate the PostgreSQL database when API first starts up.
The challenge I had with using database-level authentication / authorization is that there is only one database user used by
docker user) regardless of which
open-balena user is making the call. Similarly, all of the database calls made by
open-balena-ui (via a custom
dataProvider that interfaces with
PostgREST) use the same
docker user - so authorization needs to be implemented above the database level. Interestingly,
PostgREST would actually prefer to utilize database-level permissions, as it works this way out of the box - but I had to build a proxy around
PostgREST to handle authentication / authorization because of the above issue - and right now everything is authorized once a user is authenticated, because authorization is not yet implemented at the
open-balena-ui or at the
open-balena are stored in the
user table within the
resin database, which I believe are separate and distinct from database-level users - so I’m stuck on how we could use database-level permissions when all database calls are using a single database user (regardless of which
open-balena user is making the database call).
@drcnyc amazing work and thank you for sharing with the community.
I have been using openBalena for three or four years and have made a very terrible looking interface for seeing a device’s state and starting/stopping services and often thought how great it would be to have a fully featured community driven UI.
I will now be deleting my UI effort and subscribing to you repos. Will try to contribute to your project where I can.
@dash I’m glad you like it! There are many areas that could use improvement / building out so I would definitely appreciate any contributions you are willing to make.
This provides much greater insight into the key contents of the database than manual querying. The device creation interface also automates much of the process for entering an already-provisioned device, and saved me at least a day. Thank you!
You are a star! I’ll definitely have a go at it in the coming days!