Permission Control


WebWidgets.io is designed to make it easy to build simple and lightweight web applications. Permission control is one of the most complex components of many applications. Since WebWidgets.io is designed to make it easy to build simple, lightweight web apps, we have developed a simple, two-tier permission system that we hope combines ease of use with sufficient flexibility to suit many use cases.

Simple Permission Control

The simple way to control who can read and write your Widget data is through the Permission Control tab in the Admin Console. This allows you to assign Read or Write permission levels to other WWIO user accounts. You can also assign a Widget to be publicly readable (we do not allow a public write option, for security reasons). A user with Write permission also has Read permission.

An important point about Simple Permission is that this setting controls access to any static asset data (images, JavaScript code files, etc) that may be located in the folder corresponding to the Widget.

Login Page Bouncing

When a user attempts to load a .wisp file in a Widget directory that they do not have Read permissions for, they are bounced to a global WWIO Login page. If the problem is simply that the user is not logged in, then the user can perform the login process and will then be directly forwarded to the original page they requested.

The Login page redirection provides a smooth user experience for a simple, single-DB scenario. However, there are situations where Widget cross-loading can cause unfriendly error messages if the permissions are not correctly configured. Consider a setup where a .wisp file in the folder for Widget A loads data from Widget B using a cross-load command. Then a user with Read permission for Widget A loads the page. Because the user has Read permission for A, the system does not initiate the login redirection. But if the user lacks Read permission for Widget B, they will see an unfriendly error message about permission. To prevent users from seeing this error, Widget developers should exercise caution when using the cross-load technique.

Fine-Grained Permissions

The Simple Permission system outlined above is very coarse: it assigns every user the same level of permission to every record in an entire Widget DB. For applications that require a more flexible approach to permissions, WWIO also offers a Fine-Grained (FG) Permission scheme. The FG approach allows developers to control permissions on the level of individual records, and assign permissions to user groups instead of specific users.

To create a table with FG permissions, the first step is to add a column named group_allow. This must be a string column (varchar or text in SQLite). This column must be populated with JSON data that follows a simple format of group :: permission. For example, the following snippet will create a new record, which will have Read permissions for fungroup and Write permissions for smartgroup:

function createNew() {

    const perminfo = { 'smartgroup' : 'write', 'fungroup' : 'read' } 

    const newrec = {
        'my_number' : 1,
        'group_allow' : JSON.stringify(perminfo),
    };
    const newitem = W.buildItem(MAIN_TABLE, newrec);
    // ... 
}

Every WWIO user is automatically considered to be a member of a single-user group specifically for them. The name of this group is I::[username]. So to assign Write permissions to the user 'dburfoot', you could write:

    const perminfo = { 'I::dburfoot' : 'write' }

    const newrec = {
        'my_number' : 1,
        'group_allow' : JSON.stringify(perminfo),
    };
    const newitem = W.buildItem(MAIN_TABLE, newrec);
    // ... 
}

This technique based on singleton user groups will be enough for applications that wish to assign permissions based on user lists. In particular, some applications may prefer to maintain their own user sets and/or group membership information.

Important point about the interaction between the Simple Permissions and FG Permissions: the FG logic applies only to the table(s) that contain group_allow columns. The control of asset data loading, login page redirection logic, and permissions to other tables in the same Widget DB, are still handled by the coarse DB-level permission described above. Thus, a best practice is to configure any DB that contains tables with FG permissions as Public Read. If you have other tables that are not FG-configured and you do not wish to mark as Public Read, create a different Widget DB.

Group Info Table

Developers and system admins typically prefer to assign permissions to groups instead of individuals. For this reason, WWIO also offers the ability to create groups and assign permissions to them. Any user who is a member of that group will get the access rights assigned to that group.

WWIO group membership info is represented essentially the same way as all other WWIO data: as a SQLite table. This table has a specific name: group_info. To create this table, run the following commands in the SQLite console:

CREATE TABLE group_info (id int, user_name varchar(100), group_name varchar(100), primary key(id))
CREATE INDEX __user_group_lookup ON group_info (user_name)

As you can see, the Group Info table has an important additional feature, which is an index on the user_name column. This is important for fast lookups of a user's group membership. Other than that column, the group table functions like any other Widget table. You can control the data in it by using standard Widget operations like syncItem.

As of May 2025, the Group Info table must be placed in the same Widget DB as the FG tables. Given the best practice mentioned above, that the FG DB should be configured as Public Read, this is potentially awkward because it means the group information will be publicly viewable. We are considering allowing an alternate location, such as a config DB.

Aux Group Table

Readers who are knowledgeable about database systems may have noticed an issue with the system described above: without an additional piece of infrastructure, the permission lookups would be quite slow. When a user loads an FG table, the system would have to scan the entire table and parse the Group Allow JSON for each record. This would be particularly onerous for applications which have large shared central tables.

To improve the speed of the permission lookup, WWIO uses an additional table behind the scenes. This table is created by the system, according to a naming convention: a FG-configured table named expense will have an auxiliary table named __aux_group_expense. Users and developers do not have to interact with this table, and in fact should not.

The Aux Group table is essentially a flattened representation of the Group Allow data for the table. When an update to an FG table arrives, the system automatically parses the Group Allow JSON and makes an appropriate update in the Aux Group table. The Aux Group table is indexed appropriately so that we can quickly find all the records in an FG table that a user has access to (based on the user's group membership).