Is there any way to display Grist without tools and other things you don´t want the end user to access?

If possible, they should be able to see ONLY the left menu.

users that shouldn´t have access to a lot of stuff are able to see everything if they click on Primary Data!!!

Access rules should work reliably on Raw Data (as well as on API endpoints any any other way to access data). In fact, Raw Data is a good place to test that access rules restrict data permissions in the way you intend.

But they are working elsewhere.

Like, if I log with a different user, I can´t see ANY record on the PDCA table. But I can click on Raw Data and see everything

here… PDCA Table being viewed by Editor type of user… no record visible

Denied Access to Code

but then… Raw Data, same PDCA table.

Really, the tools menu shouldn´t even be available for non admin users…

I didn´t find in the help if there is a way to create a 4th type of role, that would fit between Viewer and Editor. I want user to view or make changes to the document data, but NOT to structure or formulas.

I noticed the user here (help page for Access Rules) doesn´t even have access to Raw Data option.

Access rules should work reliably on Raw Data (as well as on API endpoints any any other way to access data). In fact, Raw Data is a good place to test that access rules restrict data permissions in the way you intend.

I see the problem. Is that sometimes you make INDIRECT access rules.

In my table, users are linked to companies.

The PDCA records are also linked to companies.

I have access rules to companies. Users can only see the companies they are linked to.

And therefore, since widgets are linked, users can only see the data linked to the companies they can see.

But the when accessing RAW DATA, they are able to well, access DIRECTLY the raw data instead of a widgets linked to a table with acess rules.

I think that makes it even more important to be able to hide the Raw Data from common users. Because MANY times, users might want to hide data based on other means, not on direct rules based on that table.

Glad you found the issue. So you are right, with access rules, you need to restrict access to each table separately.

It may help to deny access by default, then add access explicitly to each table, to make sure nothing is slipping through undetected.

We could try to automatically create (or suggest) additional rules to apply to linked tables. That could be tricky, since there are many different ways to link data.

Regarding the 4th role, you can achieve something similar by giving users “Editor” permission (which allows data AND structure changes), then removing the “Structure” permission in the Access Rules page:

Hiding the raw data page would make it harder for a user to discover any data they shouldn’t see, but a savvy user could still use the API to get at anything permitted by the rules. Today, raw data pages are helpful to the creator using “View As” to explore the effect of rules, though you are right, for users you are trying to limit, offering “Raw Data” page feels wrong.

So you make a good point about the tools menu generally. It could perhaps be hidden entirely in some cases, or owner could have an option to hide it from all non-owners or certain roles (similar to the option to limit structure changes).

1 Like

THIS!!!

I think more of the tools could with time be hidden. For many end users, having all those extra icons on the screen, as well as the rightside edit menu, is quite confusing EVEN if they ultimately can´t do nothing with it, being able to access those, mess with them, just to be blocked when trying to save the change, is very confusing and frustrating.

Believe me, I HAVE seen users explore the extra icons. Human curiosity. And they get really lost with the extra icons.

For the internal Grist version we are using in my company (something completely different than the case above, which is a personal project), I am using much more than recommended the iframes because the iframes can hide the menus. Users have a much easier time using Grist in iframes without the menus than with the original interface with tools, edit menu that can be viewed, etc.

2 Likes

Related feature request here: Add possibility to mask lateral columns to simplify uses for beginners · Issue #1266 · gristlabs/grist-core · GitHub

1 Like

We faced a common challenge with our self-hosted Grist instance: how to hide specific administrative tools from users with “Editor” roles while leaving them visible for “Owners.” The goal was to make this happen automatically and reliably, without any user intervention or modifications to Grist’s core files.

Our solution is centered on a reverse proxy that acts as a smart middleman between the user and the Grist application. Instead of providing instructions, here’s a breakdown of the key working parts that make this system function.


The Working Parts

1. Nginx as the Reverse Proxy

The entire system is anchored by nginx running as a reverse proxy. All incoming web traffic is routed to nginx first. Its job is to forward requests to the Grist container and, crucially, to manipulate the content of the responses before they are sent back to the user’s browser.

2. The Content Injection Engine

The core of the logic is handled by nginx’s sub_filter module. When Grist sends back an HTML page, nginx scans the content for a specific tag—</head>—and replaces it with our custom code followed by the original </head> tag. This is how we inject our logic seamlessly into every page Grist serves.

nginx.conf snippet:

sub_filter '</head>' '<style>...</style><script>...</script></head>';
sub_filter_once on;

3. Role Detection with JavaScript

The injected code starts with a small JavaScript block. Its sole purpose is to determine the user’s access level. It makes an asynchronous API call to Grist’s /api/orgs/current endpoint, which returns the user’s role without requiring a page reload.

JavaScript snippet:

(async () => {
    try {
        const response = await fetch("/api/orgs/current");
        const data = await response.json();

        // If the user isn't an owner, we apply our class
        if (data.access !== "owners" && data.access !== "owner") {
            document.body.classList.add("role-editors");
        }
    } catch (error) {
        console.error("Failed to detect user role:", error);
    }
})();

4. The Visual Hiding Mechanism (CSS)

Rather than having the JavaScript directly hide elements, which can be messy and slow, the script’s only job is to add a class (role-editors) to the <body> tag. Our injected CSS rules then use this class to hide the tools. This separates the logic (role detection) from the presentation (hiding elements), making the system cleaner and more efficient.

CSS snippet:

body.role-editors [data-test-id="tools-raw"],
body.role-editors [data-test-id="access-rules"] {
    display: none !important;
}

By combining these four working parts, we created a robust and maintainable solution. The system is external to Grist, so it survives updates, and all the logic is centrally managed in a single nginx configuration file, providing a clean and reliable way to handle UI access control.