Questions about Netlify Identity Serverless functions

This is turning into a great documentation thread :grin: I ended up spending a significant amount of time digging into the Identity / Functions interplay here. Most of this stuff was written by OG Netlify in 2018/early2019 as far as I can tell. Lots of code digging :grin:


A few things to get through below but first let me ask a different question. Does having outbound web-hooks in the UI work better for you than having the same event-driven Function running? Presumably adding a web-hook in the UI just adds a function behind-the-scenes that listens for the same event and just POSTs the data straight out to whatever address you define in the UI. I’m wanting to understand if the outbound web-hooks UI presents a different / better workflow for you than making your own Event-based Functions :thinking:

EDIT: I wrote the above before your response came in (while I was writing the rest) – It would be very strange to me that the UI-based outbound web hooks have different event triggers than the event-triggered Functions. Very strange. I assume the UI-based hooks are just Functions under the hood… so I may check this out on a demo app. I’ve had a great experience with Identity and Functions overall but haven’t played with them much on 3rd party auth.


I want to approach the following as an overview of the Admin/User contexts with Netlify’s Identity (GoTrue) service. It’s critical to understand when designing your auth flows and patterns but really tough to find examples, specs, and docs on.

Actually yes, there is a way to get a list / index of your users! It’s actually built in but to get there we need to understand the difference between Admin context and User context. This is outlined as part of the readme for the gotrue-js package and briefly mentioned in the Functions & Identity Docs and even talked about a bit and implied in this very OG article from Biilman back when all this stuff was releasing. It’s worth taking time to read those, but I might recommend getting through all of this first.

Essentially, any time you’re interacting with Netlify’s Identity service, you’re considered in one of two contexts: an Admin context and a Client/User context. This is fully separate from the concept of user roles, so those don’t matter here. The Admin context resembles the process of logging into Netlify UI and having ultimate control over your site’s user. You’re not logged in as any of them, you’re interacting with the user database as a fully external, administrative person. The Admin context is defined and powered by Netlify Functions. For any site that has Identity enabled, Functions on that site will have a few fields added to the context object (a param of the Function) and one of those fields is an Admin token. It’s short lived authorization token that allows you to execute Admin level commands from your Function - like getting a list of all users. Running a Function (whether by hitting it manually or having it trigger via events [Identity or otherwise]) is the only way to get an Admin token for your GoTrue instance. Since we (the devs of the site) write the code for Functions, it’s considered safe code and granted the same rights to manage the user database as if we logged into the Netlify UI.

  • Getting user info (including user and app metadata)
  • Updating user info (includin…^^^)
  • Kicking off a user invite
  • Creating a new user (kicks off email confirmation)
  • Deleting a user
  • Getting a list of users (haven’t personally done this from the API yet; I think it returns the full object template which includes app_metadata and user_metadata for each user – no need to /GET each one after the index call)

are all available actions in the Admin context.

Conversely, when you’re interacting with Identity from a browser / or other Javascript space outside of a Netlify Function, you’re just a User and you are operating within the context of a logged-in user. The endpoints you can access are limited, you have to log in first, and you can only alter user_metadata (talked about further below).

Now, I’ll say this. When reading through the readme for the gotrue-js package under the “Admin Commands” section, it’s a little confusing that there’s a client-library call shown, then an example lambda method shown right below it. The client library wouldn’t be able to make that call, right? I just explained how only Functions get the auth token to make Admin calls! :laughing: But the admin commands are built into the client package; they’ll just fail unless you manually pass an Admin token from the Function back to the client specifically to do Admin-context actions on the client side. Generally you wouldn’t want to do that, but use cases do exist. Netlify’s own Dashboard UI is one of them :wink: Here’s what I mean:

For a pragmatic example, understand that when you or I use the Netlify Dashboard to manage the Identity on one of our sites, we’re actually using that very same GoTrue-js client aimed at the GoTrue instance sitting behind the site, and Netlify’s core APIs passed an Admin token to our client so that we could indeed manage our Site’s GoTrue instance from our client.

In general, don’t necessarily follow these examples to a tee. They illustrate a situation where you actually have two auth layers - exactly how Netlify works. You and I log into the Netlify Dashboard and get to act as Admins for the lower-layer GoTrue instances (sites). This model doesn’t work if you’re talking about a single-layer (one site; one GoTrue instance) without some strong guards. You generally don’t want to expose Admin tokens to clients that are users of the same instance. It can be dangerous.

Instead, use these as a loose guide for implementing Admin level functionality via Functions - not passing the Admin token back to the client :+1:t2: you can go a long, long way leveraging that well.

Phew, that’s a lot. :sleepy:


Some other things that should be called out when using Functions and Identity -

user_metadata can be updated directly by the logged in user from the client side, but app_metadata may only be updated from Admin context. Now, a key note here is that both buckets are visible on the client-side, so don’t store highly sensitive or non-user-specific data in app_metadata thinking it’s safe; it’s visible. It’s just read-only from the client. You may only update and/or alter that data from Admin context (e.g. within a Function). That can be used cleverly for sure :nerd_face: This is proved out and documented in one of Netlify’s demo repositories identity-update-user-data which is actually a fork of @futuregerald’s and also well described on the gotrue-js readme here:

Users can update their user_metadata field. To do this, pass an object to the attributes.data key with the fields you want to update. Updates to a users app_metadata must be performed from a secure environment, such as a Lambda function. For examples on updating user and app metadata, see netlify/identity-update-user-data.

Outside of that, there’s a react package (not netlify-identity-widget) that makes life easier too

This article “How to Build Authenticated Serverless JAMstack Apps with Gatsby and Netlify” was written by @swyx - who, though I don’t know all the fine-grain specifics, built a large portion of the Netlify Functions, Identity, and Dev stack (though is no longer with Netlify :frowning:). While it’s geared at Gatsby, the article gives insight into some of the cooler capabilities of Netlify Identity, including the last section “Authenticated Netlify Functions” which is great. Essentially, you can use an authedFetch out of the box to automatically inject your user token into your request so that the Function you hit (which has Admin context) will have a properly hydrated user object to see who called it. That can be helpful no doubt. Do note - while both the Netlify Identity Widget package and @swyx’s own react-netlify-identity packages are build on the gotrue-js library, they are separate wrappers.



Haha yes, I see that now. Hilarious. Mock data only for identity and, helpfully, authenticated requests to local functions! Nonetheless still helpful. Netlify Dev is still technically in a beta state I believe, so it’s incredible all the things it can do. Just something to keep in mind :nerd_face:


I hope that helps and makes sense. I know there’s a lot here but hopefully a solid read or two and things start to make more sense. :100:

3 Likes