Multi-tenancy (multiple spaces in one server): any takers?

A while ago I refactored quite a bit to enable multi-tenancy in SilverBullet. This would allow one server to serve multiple spaces for perhaps different users without having to run an instance for each on e.g. different ports. I never really exposed this functionality though and I now hear some people may benefit from this.

So what I’d like to understand: who’s interested in this and what is their use case? And how would you imagine you would configure this, ideally? Right now everything happens mostly through environment variables but that may not scale very well.

5 Likes

I’m the one who asked about this on Discord, to explain a bit more of my use case and why this is something interesting to me. I have 3 main things I like to keep knowledge on:

  • Work
  • Recipes for cooking
  • Nerdy stuff, e.g. RPG campaings and such

The chances of me wanting to referencing one from the other are 0, I could spin up 3 silverbullet instances but then having the top bar allow me to navigate between them is troublesome because I’m using tailscale so the links would have to be different if I’m at home or not.

Another thing is that I wouldn’t be able to have my index reference stuff from all 3, for example if I want my index to gather all tasks from all spaces, which is why I’m thinking on them more as subspaces, where for example things on the main folder could reference things inside Work or Cooking, but things inside Work couldn’t reference things outside of it.

Another place where this would help is with not having to specify full path for things that are right next to one another if that’s a subspace, for example I could make each of my RPG campaigns their own subspace so I wouldn’t need to reference Nerdy/RPG/System/Campaign1/NPC/John instead I would do NPC/John if that Campaign is set as a subspace and on another campaign NPC/John would refer to another page without any risk of referencing an NPC from a different campaign inside it. It would also be nice if the header of the page only showed the path inside that subspace, so as to not get giant filenames that list every folder along the way, that being said moving stuff from one subspace to another becomes difficult but on the other hand if you need to move things between one subspace and other they’re not as independent as to each be it’s own subspace.

The way I think this would look good in the configuration is maybe with a subspaces config, e.g.

subspaces:
  - Work
  - Nerdy/RPG/System/Campaign1

Each of those subspaces would act as their own space and while inside them everything on the page would act relative to that base path. With the exception of the top bar since we want to have a way of exiting or switching subspaces. Although a custom top bar per subspaces sounds appealing, but I think that might be out of the scope of this.

2 Likes

Hello.
Today, I work as a system analyst for legally unrelated project teams.
For me, the implementation of the content isolation mechanism in SilverBullet is valuable because it allows you to store personal notes information
materials of active and frozen projects, do not fear leaks of confidential information and technical solutions of parallel projects. Content filling, isolated sites, can be done by copying files from the privileged directory, using the operating system, setting access rights. Today, using SilverBullei, I have to distill content into office package file formats and send them by e-mail. Often the materials are discussed by the members of the project team and they make adjustments, suggestions, comments. I suggest that in SilverBullet implement the model “user → many isolated projects” with publication on the main and support for guest access. Equal multi-user mode, it seems to me not viable for reasons of information security, especially since if necessary it can be easily reproduced by launching many copies of SilverBullet on different network ports.

IgorKa

Hi,
here are my two use cases:
UC1:
It would also improve sharing control.
Lets say I have my personal knowledge base for Technical stuff but I also have cooking recipes.
I want to have access to my technical knowldege base while I work without switching to another silverbullet instance but my cooking stuff stays unshared.

UC2:
I have my personal space but I also want my wife and my kids to have their own spaces that are spearated from each other.

Thx for your great work!

2 Likes

Ok various use cases here. Initially I was thinking the main use case would be different users using a single server with each their own space. In that scenario deciding which space to access could simply be based on the username. However that would be quite impractical if a single user wants to have access to multiple spaces and switch often (you’d have to log out and back in).

I see two solutions:

  • each space is hosted on its own hostname, e.g. sub domain. This would technically be the easiest for me to do, but probably a bit trickier for users since they’d have to configure dns, certificates for each host.
  • each space lives on a URL prefix (so not the root), e.g. /personal/index and /work/index this seems better for users but I’d have to a fair amount of work because I’m sure there are a bunch of places where it’s hardcoded that everything is loaded from the root.

Any other ideas?

I think there are two features that aren’t really the same.

  1. Actual multi-tenancy
  2. Subspaces per user

I like the subspaces idea. One use-case I can think of would be having a sort of “archive” subspace where I can put things I don’t need to access as often and won’t show up in searches/etc.

For actual multi-tenancy, tbh I don’t mind spinning up a second instance for a 2nd user. My main use-case for having multi-tenancy would be sharing specific notes with my wife, but I think that could be eventually be accomplished by using Federation instead?

each space lives on a URL prefix (so not the root)

For subspaces, this would be my vote. If you also want multiple users though, the url prefix would probably end up being /zef/personal/index etc

1 Like

This is exactly what I have now with a few Docker containers, with a subdomain and a port dedicated to each.

I think I don’t understand the reasons to do that, or they don’t apply to me. I use a single personal space as a silver bullet to all my note-taking needs. If I need to share it, the discussion about publishing (with $share, I think) seems to me more fitting.

I’d prefer silverbullet to keep clear of that, not only because of development time, but also adding another thing to misconfigure. This can be already done with other tools (Caddy, nginx, Cloudflare API for subdomains), for me it wouldn’t get any better — probably worse, since now I have all subdomains and ports configured for the entire server in one place, and after this I’d have to also figure them out in SilverBullet.

I like the simple elegance of current solution

This is the exact kind of multi-tenancy I want to ask for, but since nobody was mentioning it, I thought I misunderstood the question :sweat_smile:


An idea for that:

  1. Add permission system allowing extra users to access specific paths
  2. Add username/password authentication to Federation and possibly allow writes then
Detailed proposal

Add a permission system, where the space owner configured throug command line arguments has read/write permission on all notes, but add an ACCESS file which can grant permission for public or password-protected access to specific folders or pages. Special pages like ACCESS, SECRETS, and SETTINGS cannot be exposed this way. Example:

```yaml
# Common cooking database
- path: "Recipes/"
  publicRead: false # that's always default
  readWrite:
    - grandma
  readOnly:
    - brother
    - mom
    - dad

# Extremely simple way to publish some notes for your players
- path: "RPG/Saving the Princess/Story so far"
  publicRead: true
```

This would be accompanied by a section in this file, or maybe SECRETS with the following:

```yaml
extraUsers:
  - username: grandma
    password: UltraTopSecret
```

These users could access these pages the usual way, or from their own notes through authenticated Federating

Federation authentication could probably be done in a per-URL basis, like:

```yaml
federationPasswords:
  - url: family.md
    username: grandma
    password: UltraTopSecret
```

And then in a different space (possibly on a different server), a link like this could work: [[!family.md/Recipes]] with the right settings. I imagine editing external content to work something like Sync Mode?

Why I like these:

  • allow collaborating on notes with someone else, also on a different server
    • grant access to some folder in root essentially makes it like a subspace - all they can see has the same prefix
  • make it easier to share multi-template Libraries - just ask the author to mark this folder as publicRead instead of copying templates one by one from this forum

I think this works for every use case shown above except @Nibodhika - every link would still be Nerdy/RPG/System/Campaign1/NPC/John. But you’d still only see “John” rendered when reading text, unless you have your cursor there. Yes, there is still risk of inadvertent cross-referencing, but to me maintaining consistent adresses is worth this.

EDIT: I just realised this would be extremely messy with multiple users editing a note at the same time. Especially with current conflict resolution, which is really OK, as long as it’s one person and doesn’t happen too often.

1 Like

I agree with @Maarrk
There are already great tools that could give us these options which are experts on that realm.
I can also spin up as many containers as I may need and use subdomains and nginx NPM to create different spaces at will.

I fear this would overcomplicate SB. We could use this energy to enhance SB in other areas.

Ok, sorry about that. There’s indeed multiple things here.

The direction I’ve set my mind on for SilverBullet for now is the single user use case. That is: one person (but likely multiple devices) using SB for their own private use, not sharing that space with others. A lot of recent changes are unlocked by that direction, like space script which would be extremely hard to get right if you’d have to take into account permissions, deeper security etc. Also, supporting teams is a whole different ball game. Now we have to figure out authorization, permissions, how those permissions apply to objects and queries. Realistically I can only see that happen if somebody gives me a lot of money to kick of a team to work on this, not something I’ll pull off at nights and weekends.

That said: I am interested to support some way of collaboration, but externally: indeed through something like Federation. The idea would still be: you and I have our own private space with our own crazy setup, but we have a synchronization point where we both push and pull data from. Perhaps a single page, perhaps a folder. A lot of the building blocks for this are there, but the tricky part is the safe collaboration part, specifically real-time. This is all technically feasible, but another enormous engineering tangent in terms of development work. Some may remember that SB at some point had real-time collaboration (with the cursors, selection etc. all syncing) but that lead to a lot of complicated edge cases so I removed all that. A simpler system may involve explicit edit locking of some sort. Haven’t fully figured this out yet.

What I was aiming at with this topic was the “I have a need for multiple spaces, how do we make that easier?” use case. That could be because you yourself need multiple spaces (for whatever reason), or you indeed want to give this to your friends or family more easily.

More easily is key here, because all of this is indeed already possible. You can run an infinite number of SB instances at different ports, and use a virtual host setup to do mapping e.g. on host names.

Maybe for now we just keep it like it is. Maybe the community can help out with better documenting how people can set this up nicely rather than me spending a lot of engineering time building this in. For me it’s all about opportunity cost. I have limited time, where do I spend it? Perhaps this is not the most pressing topic right now.

3 Likes

This was my concern, that you would use your infinite time in something that it may not be as worth doing as other things, as there are good alternatives available and which are reasonable and well established.

I’d rather see you improve current features, like Space-scripts, templates, bugs, feature requests (the github issue has quite a nice list of ideas) and collect recipes/ideas for everyone to learn from them and use them.

2 Likes

Even though I kicked this whole thing asking a question on discord, I agree that the way I described it should not be a priority, and apparently the way others described it (i.e. multi-user) is not feasible so I understand if this is not acted upon now. I only recently started to use this so I don’t know which other areas might require attention, but this one is definitely not a critical one.

That being said, I think a discussion on how this should be implemented from the end-user point of view is worth it, then someone else might pick it up for implementation.

2 Likes

Hi, here is my points regarding this:

I started to use markdown in redmine and latter quite intensively used dokuwiki, both are developed an used for years and still maintained.
Latter I used it for my blog created by static page generator hugo
Then there was some pause in my content creation activities…

But now I had to rethink my approach to my notes and blog idea, because now again I often have to take notes both at my work and home and they are wandering around in different solutions, software and files. So I have at least to shrink them to two dedicated spaces: at work and home.
Then there came a lot of other info regarding other note-taking contexts, like contacts and calendar integrations etc. and AI. So I came to SB and was impressed with this live markdown approach.

While recently for my job notes&docs I still choose dokuwiki. The main reason was - that I have to limit info sharing and dokuwiki is very simple and is good at it by using users & groups. Their access rights of groups are possible to set per subspaces. And it is using page simple locks.
Probably there are some approaches that could be borrowed from dokuwiki, because it also is file based markdown wiki system. That’s why I still like dokuwiki and also why I am decided to use for my personal notes SB. :slight_smile:

brgds
J.

This is my desire also. Mostly I want to give read only access to others, which simplifies things somewhat. This would allow users to be specified in the frontmatter, and eliminates the issue of concurrent editing.

1 Like

Hi there! I am interested in this precisely, I would like to offer hosted gardens as a service in anagora.org and such a mode would fit the bill it seems.

What I have now: Silverbullet being served in edit.anagora.org. When you visit [[foo]] at anagora.org, there is an edit section that iframes edit.anagora.org/foo which opens Silverbullet in that page. It works, for one user (currently me).

What I’d like is to be able to embed e.g. edit.anagora.org/@bar/foo when user @bar is logged in, so that the same flow would open [[foo]] in the space of @bar (the Agora user). The Agora already keeps one git repository per participating user in disk (that is the participation model precisely) so it would be easy to get a map from user/space id to path.

My previous plan was to bring up a separate SB container per user, but that’s logistically much more intense clearly. Happy to collaborate on this as I can.

Thanks!

I looked at your website really quickly but, coupled with your description here… doesn’t it make the most sense to spin up an instance per user, regardless of what multi-tenancy/user features SB has? You already have separate data stores for your users anyway.