Question about SGW channel access

Hi team,

So I’m tinkering with my SGW access pattern and have a couple of questions. My documents looks like the following example:

  "created_at": "2018-02-12T08:17:12.3296000Z",
  "tenant": "CompanyA",
  "owner": "6fb24dd3-d5c5-4124-84d1-f2c52e1bab36",
  "title": "title",
  "type": "list"

My SGW sync function looks like this:
function(doc) {
access(doc.owner, doc.tenant);

When I have a new user (belonging to the same tenant (i.e. “CompanyA”) as the previous user), it won’t receive access until he creates a new document.

I want the new user, beloning to the same tenant, to sync all the documents in the channel. How do I achieve this? Do I have to create, and push a document, for this user if I want to access all the previous documents in the same channel?

The user would have to be granted access to the specific channel before they can start pulling/syncing from it. In your case the doc.owner is granted access so yes, unless that user’s document is processed by the sync function, they won’t get access to this channel.

  • Of course, the straightforward way is to pre-configure the list of users and associated channels in your config file.

  • Amore practical approach would be to use the SGW Admin REST API to pre-authorize users access to channels and/or assign roles
    Take a look at this documentation . This API would typically be executed on your server /web backend when a user registers or signs up with your system

  • Of course, if you associate a user profile document with a user when the user signs up, then when the user signs up, a new profile doc would get created for the user and that profile document would be processed by the sync function . You can authorize the user access to channel based on that user profile doc.

So several options available. Depends on your app needs.

I would like to use the second option (creating users via the Admin REST API). This is problematic because we are using an OpenID authentication solution and the SGW is looking for a username with the following format: [issuer]_[subject] (as described here), but the user created via the Admin REST API have the chosen Email. I.e. the user is not found and we get an unauthorized exception.

So unless we can fix this, we are forced to go with your 3:rd option (i.e. creating some sort of profile to get access). Maybe you can clarify this?

Thanks a lot!

We’re looking into your third option as well. In this scenario, we thought we could push some sort of “AccessTicket”-document, with the sole purpose of granting access for the user to the channel. This seems to work out.

Altough, we speculate there will be a lot of “AccessTickets”. Is it possible to set a TTL on these documents, the way you can do it in Couhbase Server (or is this option only for CB server)?

In CBL 1.x, there is a expirationDate field associated with a Document but what that does is a local purge of the document on CBL which isn’t what you need. There isn’t a built-in way to specify a TTL on documents created on CBL that will impact its lifetime on server . More on this here

Again , couple of options

  • once the document is pushed up from CBL, you could set up your web app to update the document via the SGW REST API to set a _exp field …

  • Or instead of creating the access doc via the app, once a user successfully registers with your system, you can create a “access profile” document via the SGW REST API by specifying the _exp field. Basically a combination o (2) and (3) from earlier post

  • You could have a process on your server that will manually examine the docs and periodically clean up the documents .

Note that purges are not replicated. So you would need probably need purge them locally on client as well (perhaps right after pushing up the access ticker doc and getting access, the client could locally remove that doc).

In short, look into leveraging the REST API on SGW to update or create doc with _exp.

Hi again,

Thanks for the information. We ended up making a document called “AccessTicket”, to ensure that the authenticating user got access in SGW. Then, we’re starting the replication and the user is shown a loading screen. When the replication process is done, the user is routed to the application.

What do you think about this approach? We’re checking the replication status with this method:

if((PullReplication.ChangesCount == PullReplication.CompletedChangesCount
    && PullReplication.Status == ReplicationStatus.Idle)
	&& !IsNavigating) 
	// Route to application...

This works fine in our development environment. Do you think this will suffice in production, or do you have any suggestions?


This should work. So what did you decide about purging the access docs ?

Any reason why you need the replication to be completed before user is routed to application (loading UI) ? You have anyway done successful OIDC authentication and all you are doing here is granting access to channel.
The very first time, there wouldn’t be any docs for user so you would not see any update to replicator status. So this should be almost instantaneous.
In subsequent launches, if there are documents for user , wondering if you have to make the user wait to fetch all documents before loading the app. Would probably be a better user experience to load the screen and then update the UI as and when the docs relevant to the view are fetched …

First off, we’ve set an expiration time of the document like this:

We will have a purge strategy later on to ensure we don’t have masses of access documents laying around.

Any reason why you need the replication to be completed before user is routed to application (loading UI) ?

It’s actually very important that the company specific documents are synchronized to the user’s device before he/she can use the application. The application looks, and works, differently for all companies, which is specified in the documents (configuration). These documents will be pre-made, so we won’t have any scenario where the user makes the first login without having any documents to sync. Each company have there own specific channels, which is why we don’t want to initiate a sync before we know what channel to get.