Automatically setting user roles at scale in Glide

Programmatically written Role values satisfy visibility conditions but fail Row Owner matching — manually written values work for both

Hi everyone, a bit of a read but would appreciate all the help!

Background:

Single Glide app. One published app, three role-based views: Customer, Seller, Admin. Users table has a Role column configured as the User Profile role field. Role-based tab visibility and Row Owners both reference this column.

The specific setup:

Items table:

  • Row Owner column: Customer Access (plain text, hardcoded value “Customer” on every row)
  • This Row Owner is what controls which users can see item listings on the Discover screen

Users table:

  • Role column: configured as User Profile role field
  • Values: “Admin”, “Seller”, or “Customer”

What works perfectly:

  • User with Role = “Admin” (manually set in data editor) → sees correct screens :white_check_mark:
  • User with Role = “Seller” (manually set in data editor) → sees correct screens :white_check_mark:
  • User with Role = “Customer” (manually set in data editor) → sees all items on Discover :white_check_mark:
  • User with Role = “Customer” (written by Make via Glide API set-columns-in-row) → tab visibility conditions work correctly, correct tabs show and hide :white_check_mark:

What fails:

  • User with Role = “Customer” (written by Make via Glide API) → Row Owner matching fails, Discover screen shows zero items :cross_mark:
  • User with Role = “Customer” (written by Glide Workflow Set Column Values) → Row Owner matching fails, Discover screen shows zero items :cross_mark:

Key observations:

  1. The Role value looks identical in the data editor for both manually-set and programmatically-set users — same capitalisation, no spaces, no hidden characters confirmed
  2. Make-written Role = “Customer” correctly satisfies tab visibility conditions but fails Row Owner matching — this suggests the value itself is correct, but something about how it was written affects Row Owner matching specifically
  3. Only the designated User Profile Role field satisfies Row Owner matching — we tested writing “Customer” to a separate plain text column and setting it as a Row Owner on Items — this failed regardless of whether the value was manually written or programmatically written
  4. The issue is reproducible consistently across multiple test users and multiple approaches

Everything we have tried and ruled out:

  • Writing Role via Make API (set-columns-in-row) — value appears correctly, visibility works, Row Owner fails
  • Writing Role via Glide Workflow Set Column Values — same result
  • Writing to a separate plain text column as Row Owner — confirmed only User Profile Role field works for Row Owner matching
  • Changing Role to Multiple Texts type — breaks existing Admin and Seller setup, not viable
  • Empty Row Owner on Items — invisible to all users, not viable
  • Removing Role configuration from User Profile settings to make it a plain text column — breaks existing role-based access for Seller and Admin, not viable

The core problem: We cannot manually set Role = Customer for every new customer at scale. We need a programmatic method (Make, Glide Workflow, or any other supported method) to write Role = Customer to new users in a way that satisfies Row Owner matching.

Specific questions:

  1. Why does the source of the write (manual vs programmatic) affect Row Owner matching when the value is identical?
  2. Is there any supported programmatic method to write to the User Profile Role field that Glide treats the same as a manual data editor write for Row Owner matching purposes?
  3. If not, what is the recommended architecture for a multi-role app where new customers are assigned a role programmatically at scale?

Maybe Jeff’s explanation and Darren’s video in the thread below will shed some light.

  1. I quote @Jeff_Hager (from the thread below):

When you intentionally build a role-changing feature on the backend, you as the developer have far more control over the logic and who is allowed to run it. It’s no longer about somebody tampering with API calls. It’s about deliberately creating a controlled process and enforcing strict conditions around when and how it can execute.

I think it depends what you mean by manual and programmatic:

  • manual inside the data editor: should work
  • manual from inside the app and client side: won’t work
  • manual from inside the app and server side: should work
  • programmatic: good question
  1. See @Darren_Murphy’s video. He uses Make (though not demonstrated in the video) as well as the webhook trigger (demonstrated in the video) and the manual trigger.

  2. If you have an onboarding flow, an action on a button triggerd by a customer could write the appropriate role. Not exactly programmatic, but a forced manual setting of the role unbeknownst to the user.

It shouldn’t matter at all, except that client-side writes are not supported and will be reversed if attempted.

Yes, writing via API and server side workflows are both supported.

Exactly what you have described. I’m a little puzzled that it’s not working for you, especially the following:

The above should work. In fact it does work, as I’ve done it many many times. I’d like to see more details of your specific setup, something can’t be right.

The above is expected, assuming a client side (user interaction) workflow.

Thank you Darren and Nathanael. Your input has given us some sort of peace of mind, but a little frustration lingers.

Here are the specifics of our Make setup:

  1. Button on Welcome screen triggers a Glide Webhook action
  2. Webhook payload sent: row_id (from screen’s row context)
  3. Make receives webhook → Edit Row module → targets Users table → writes Role = Customer using set-columns-in-row
  4. The Row ID being sent is the signed-in user’s Row ID from the Users table
  5. Role = Customer appears correctly in the data editor after Make runs
  6. Tab visibility conditions work correctly for the user (correct tabs show/hide)
  7. But Row Owner matching fails — items with Customer Access = ‘Customer’ are not visible to this user

One observation: when we manually overwrite Role = ‘Customer’ in the data editor for the same user, Row Owner matching works instantly. The value looks identical — same capitalisation, no spaces.

Is there something specific about how Make’s Edit Row module writes to the Role column that could cause this?

Would you consider trying with Glide’s webhook instead of Make’s? At least as a test?

Is this in the builder, the published App, or both?
If you haven’t tested in the published App, please do so.

No, not as far as I’m aware. As I said earlier, it’s always worked perfectly for me. Although, I don’t use this method anymore, as it’s much simpler with a server side workflow.

Really appreciate the prompt responses!

@nathanaelb

We followed your suggestion and attempted to use Glide’s webhook-triggered server-side workflow instead of Make. The webhook receives the payload correctly (confirmed — jsonBody shows row_id and role values). We set up a Users loop filtered by Row ID, with a Set Column Values step writing Role from the webhook payload. However, when wiring the button to trigger this workflow, Glide only shows dropdown fields for passing parameters — we cannot pass the row_id and role values as named parameters directly. Glide AI suggested building a JSON Object column to store the payload first, then passing that column to the workflow. This feels like an unnecessarily complex workaround for passing two simple values. Are we missing a simpler way to pass parameters from a button to a webhook-triggered workflow?

@Darren_Murphy

Tested in both builder preview and published app — Row Owner matching fails in both. Make writes Role = Customer successfully, value appears correctly in the data editor, but items remain invisible to that user in the published app. Only resolves when we manually overwrite the exact same value in the data editor. No difference in the value — same capitalisation, no spaces, confirmed multiple times.