Feature Request Update: Page Level Permissions

Hi everyone!

For those of you who haven’t seen me around the community before, I’m Jason, a member of the engineering team that works on Coda at Superhuman. I wanted to share some insight on where we are with page-level permissions, since we’re aware it’s a popular feature request the community has raised frequently, and it has been too long since we gave you an update.

I want to be direct about where things stand. This is a highly complex effort that touches many parts of our product. To solve it well, we’ve staffed a single team to own this area end to end, across all aspects of our product: permissions, sharing model, calculations, and data storage.

As that team dug deeper into page-level sharing requests, it became clear that many are really about sharing a specific subset of data with specific people. For that to work reliably, securely, and at scale, the database foundation has to come first. This work addresses many of the issues customers feel most acutely today — including table scale, performance, cross-doc syncing, reliability, and bugs. It also lays the groundwork for page-level sharing in cases where data is involved. Because we’re now close to the beta of this new scalable database architecture, we’ve decided to keep the team focused on finishing it well.

I know this won’t be the answer many people were hoping for, and I understand that disappointment. We want to move both efforts forward in parallel, and that should become more possible as we get further through the database work. We’re committed to supporting this use case, but we believe this sequencing is the best way to ensure the highest-quality long-term solution.

Please continue to work with Ruggy to flag anything that’s on your mind as this develops.

Thanks for the update Jason.

Out of curiousity, what makes it so complex?

Each page has a unique Page ID. Does this not simplify sharing of pages/subpages as a first step before subset level sharing?

Thanks,
Chris

If I may presume to give a temporary answer: it is not simply about sharing a page.

That page may have a table. I might not want to share all the records in that table, with everybody that I share the page with. So the filter functionality needs to be managed. A person, may, or may not, be allowed to change the filters to further filter the table, but he should not be able to remove the filters that I put in place.

I may, may not, want the recipient to be able to add and/or remove columns that are visible.

That table may have hyperlinks to other tables, which I may, or may not, want to share with the recipients of the page.

I may, or may not, want people to access the content of that table with canvas formulas. I may, or may not, want to restrict people creating formulas, either in the table, or on the canvas, from accessing data in other tables.

Throw in packs and agents, and you have an EXTREMELY complex environment.

But, it’s just a ramble,

Rambling Pete.

Thanks for the update, Jason.

Any news is better than no news.

P

Thanks Piet, appreciate the input. The examples make sense.

I can see how it grows. In my mind, it simplifies to read/write/execute permissions.

Then it’s about building in the extra property to each object. So the page has a permissions property with a list of users and their permission level.

Similar for tables, and filters and buttons etc. Everything is allocated a permission level, which controls what each user can do with each object.

Then it’s about defining cascading permissions, which probably simplest to cascade down from parent. E.g. if user only has read permissions for a table then they won’t be able to hit the filter button but if they can execute then they can change filters but can’t edit (write) the data.

It grows with scale, but with my limited understanding it doesn’t appear to be unreasonably complex.

Except very often you want to give read access AND the ability to filter. Say you have expenses by category for a year. You want to allow people to filter by month or by category, but you do not want them to be able to change anything.

I suspect this could be achieved with Read + Execute permission. This way user could do everything except change the underlying values and data.

Thanks a lot for the update!

Many thanks for an update! Ofcourse increasing database scalability is priority number one!

I find it a bit worrying that, after all the acquisitions and all the “resources” poured into such a fundamental part of the product, we are still in the “future” beta phase for only a part of this entire feature. My trust in the future of the product has started to go lower and lower, and I started to migrate myself from the idea of “Superhuman” only as a workspace, as I see that quality of life parts of the product (not narrow use cases) seem to take years and years, which limits the product’s usability for some. I see the product as quite stale with huge lead times, which is unfortunate in today’s market.

For anyone wondering why page-level sharing is so hard to implement in Coda.

Since forever, the whole Coda doc was stored and loaded as a single¹ file.

(¹ — not strictly single; there were multiple separate files like fui-system and fui-allcanvas, but nonetheless, the entirety of the doc data was pretty much loaded as one big chunk).

A while ago, probably in the efforts of getting closer to ‘page-level sharing’, Coda started doing more sharding, i.e. splitting those files into page-specific canvases and grids. This helped with e.g. Time-To-First-Load: the page you requested would quickly load first, and then the rest of the doc would load in the background. You could witness this gradual loading in large docs, and especially on pages that have tables and views (those tables and views would be in the ‘loading’ state for a while).

However, it’s still not quite possible to shard everything into pages. Remember that a Coda doc is one large namespace, one large canvas. All things — tables, views, controls, formulas — exist within that single common canvas of a doc. Pages are nothing but a device to split that large canvas down into usable pieces visually — but it’s not meant to work like separate docs / separate canvases would. In Coda, Doc is an undivisible unit. That’s what made it possible to build all those highly automated and dynamic workflows in Coda. That’s, partly, why Coda Formula Language is far more superior to Notion’s one.

In Notion, it’s all different. There are no docs — there’s a workspace and then immediately pages. So it’s natural for Notion users to treat pages as docs on their own — e.g. have a separate page for Notes, a separate page for Finance Tracker, a separate page for Habit Tracker etc. In Coda, we use separate docs for that!

Besides, Notion’s page sharing is actually also broken. Notion separates page content from the table content that’s displayed in that page (possibly, in a filtered view). So while you’re technically sharing page’s content in Notion, you don’t automatically share the table data. And you CANNOT share only the data from the filtered view either — you have to share the whole base table so that it can be displayed in that shared page. So Notion makes you think that you, e.g., shared only a portion of your Clients table with a client when you shared their personal page with them — but in fact you leaked the whole table of Clients to them, and they can get to it quite easily. And guess what, there’s already a way to achieve the same (with the same caveat) in Coda using separate docs and sync pages. But also there are ways to achieve TRUE data filtering either (with Crossdoc / Sync Tables Pro and prospected Workspace Databases feature).

To sum up, my unpopular take:

Coda should NOT have page-level sharing for the feature’s sake.

Coda should NOT give in to demands of Notion users because Notion users are just clueless.

What Coda should rather do is better educate users how the product should be used and thought about.

Also, in Notion, each table is quite ‘unconnected’. References to other tables are limited to links and rollups — these simply get ‘precalculated’ and stored within the table. In contrast, in Coda you can have formulas calculating literally ANYTHING in a table, like a list of arrays where each array’s first element is a reference to one table and the second element is a reference to another table, e.g.:

Of course it’s not possible to just ‘extract’ such a table and share it individually, unlike Notion’s ones.

thanks @Paul_Danyliuk for sharing your insights.

I would have loved to read from the Coda team a more coherent approach linking back to already shared insights (the stages 3 and 4) and linking forward to how their ideas relate to the future they see.

I believe very much in the foundations of Coda (due to the table logic), also for AI Agents, but only if set up correctly and in this context I would have appreciated the insights of the Coda team.

I have just watched the Google I/O and their ideas are quite clear, I like that approach and would like to see such insights from the Coda folks as well. There was a time coda employees wrote interesting blog posts on serious topics, see here. Is it too much to ask to get some insights again?

Thanks for the update Jason.

Given that this offering of page level permissions security has been pushed sometime into the future due to complexity, it would now seem prudent to give doc makers at least a modicum of ‘security through obscurity’ for pages and data, which would be comparatively trivial to implement.

Please give doc makers the ability to turn off elements in the UI that currently allows any viewer to click and jump to pages that the doc maker has intentionally set to hidden.
These elements include clicking on any user’s avatar to tailgate to other pages and showing the doc map allowing viewers to jump to other pages.

Thanks for the detailed info Paul.

It’s going to be pretty hard to get users to adapt to Coda’s way of thinking. Most users aren’t as interested in the design and architecture or scrolling through forums like this on the weekend so might be a tough sell.

For the design and architectural background → where did you find this info?

i also realllly need to be able to turn of doc-wide search