Replies: 1 comment
|
I think the best approach would be to leave this decision up to the developer. If a developer selects a column they don't have permission to access, they should be able to decide how Appwrite handles it ( It would also be useful to define what value should be returned when the user doesn't have permission to access the column. For example, if a column is a boolean, the developer might want it to always return Rather than simply returning However, the configured fallback value should still be validated against the column's type. For example, a boolean column could reasonably return either I would also recommend supporting both levels, table-level and row-level. This would provide a lot of flexibility while still allowing developers to choose the behavior that makes the most sense for their application. |
Uh oh!
There was an error while loading. Please reload this page.
Hey everyone 👋
We're adding column-level permissions to Appwrite Databases, and there's one design decision I'd like your input on before we lock anything in:
Should column permissions live on the table, or on each row?
The answer changes the API, the Console UI, how queries behave and what it costs to run. More detail below. If you only have a minute, skip to the questions at the end.
The problem
Permissions today decide whether you can see a row, never which parts of it. If a row has a column some readers shouldn't see (salary, email, phone, internal notes), you currently have to move that column into its own table, give that table its own permissions, and join the two back together in your app.
What's the same either way
columnSecurityflag, next torowSecurity. If you don't turn it on, nothing changes, including performance.updatelets a role change only that column.deletestays row-level.Rough API shape, not final:
Option A: table-level
Column grants are set on the table. Row permissions still decide which rows you see. The table decides which columns of those rows you see.
In other words, who can see a column depends on your role, never on the row.
As a signed-in user who isn't in HR:
HR gets full rows and can filter, sort and aggregate on
salary.Another way to shape this option is to set permissions on the column itself:
Good
Not so good
Option B: row-level
Column grants can be set on the table and on individual rows, the same way row permissions work today.
In other words, it's
rowSecurity, extended down to columns.As any other user:
The owner gets the full row.
Good
rowSecurity: the table and the row accept the same permissions.Not so good
sum('salary')only adds up the rows where you can read salary.columnSecurityis opt-in, a table only gets migrated when it's turned on, but it's still a lot more work to ship.Side by side
Option C: A now, B later
Ship table-level first, with a permission format that already carries an optional column. If real use cases need row-level, we add it later without a breaking change.
How others do it
GRANTs per role, at table level. Selecting a column you weren't granted fails,SELECT *included. Supabase calls this an advanced feature and recommends most people use RLS with a separate table instead (docs).Every product we looked at pairs a row filter with a column list set on the table. None of them do per-row column grants. That's why I'm especially keen to hear from you if you'd need B.
Questions
null, or cause an error when you ask for them explicitly withQuery.select()?Permission.read(role, 'column'),Permission.read(role, ['a', 'b']), or permissions set on the column itself?create: should a role be allowed to create rows but only set certain columns, or shouldcreatestay row-only?columnSecurityoff: this drops the column restrictions, so a column grant then applies to the whole row and access widens. Is that what you'd expect, or should we block turning it off while column grants still exist?Prototypes
If you want to dig in:
All reactions