PageSourceSearch

https://authress.io/knowledge-base/assets/js/355c6fcf.1f765661.js

js authress.io collected 2026-09-24 18:30:03 UTC 27,058 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkAuthressKnowledgeBase=self.webpackChunkAuthressKnowledgeBase||[]).push([[2872],{3905:(e,t,s)=>{s.d(t,{Zo:()=>l,kt:()=>d});var n=s(67294);function a(e,t,s){return t in e?Object.defineProperty(e,t,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[t]=s,e}function r(e,t){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),s.push.apply(s,n)}return s}function i(e){for(var t=1;t<arguments.length;t++){var s=null!=arguments[t]?arguments[t]:{};t%2?r(Object(s),!0).forEach((function(t){a(e,t,s[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(s)):r(Object(s)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(s,t))}))}return e}function o(e,t){if(null==e)return{};var s,n,a=function(e,t){if(null==e)return{};var s,n,a={},r=Object.keys(e);for(n=0;n<r.length;n++)s=r[n],t.indexOf(s)>=0||(a[s]=e[s]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n<r.length;n++)s=r[n],t.indexOf(s)>=0||Object.prototype.propertyIsEnumerable.call(e,s)&&(a[s]=e[s])}return a}var u=n.createContext({}),c=function(e){var t=n.useContext(u),s=t;return e&&(s="function"==typeof e?e(t):i(i({},t),e)),s},l=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var s=e.components,a=e.mdxType,r=e.originalType,u=e.parentName,l=o(e,["components","mdxType","originalType","parentName"]),p=c(s),d=a,m=p["".concat(u,".").concat(d)]||p[d]||h[d]||r;return s?n.createElement(m,i(i({ref:t},l),{},{components:s})):n.createElement(m,i({ref:t},l))}));function d(e,t){var s=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=s.length,i=new Array(r);i[0]=p;var o={};for(var u in t)hasOwnProperty.call(t,u)&&(o[u]=t[u]);o.originalType=e,o.mdxType="string"==typeof e?e:a,i[1]=o;for(var c=2;c<r;c++)i[c]=s[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,s)}p.displayName="MDXCreateElement"},34017:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>u,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var n=s(87462),a=(s(67294),s(3905));const r={sidebar_label:"Querying and displaying users",title:"Fetching and displaying user lists",description:"This guide reviews fetching users, querying tenants, and displaying user avatars in your application.",image:"./user-display-list.png",image_alt:"List of tenant users"},i=void 0,o={unversionedId:"usage-guides/querying-and-displaying-users/index",id:"usage-guides/querying-and-displaying-users/index",title:"Fetching and displaying user lists",description:"This guide reviews fetching users, querying tenants, and displaying user avatars in your application.",source:"@site/docs/90-usage-guides/09-querying-and-displaying-users/index.md",sourceDirName:"90-usage-guides/09-querying-and-displaying-users",slug:"/usage-guides/querying-and-displaying-users/",permalink:"/knowledge-base/docs/usage-guides/querying-and-displaying-users/",draft:!1,editUrl:"https://gitlab.com/rhosys/authress-public-kb/knowledge-base/-/blob/main/docs/90-usage-guides/09-querying-and-displaying-users/index.md",tags:[],version:"current",lastUpdatedAt:1772377859,formattedLastUpdatedAt:"Mar 1, 2026",frontMatter:{sidebar_label:"Querying and displaying users",title:"Fetching and displaying user lists",description:"This guide reviews fetching users, querying tenants, and displaying user avatars in your application.",image:"./user-display-list.png",image_alt:"List of tenant users"},sidebar:"tutorialSidebar",previous:{title:"Implementing signup and Onboarding",permalink:"/knowledge-base/docs/usage-guides/onboarding-users/"},next:{title:"Anonymous Auth / Shopper IDs",permalink:"/knowledge-base/docs/usage-guides/anonymous-auth-and-shopper-ids/"}},u={image:s(83027).Z},c=[{value:"Scenario",id:"scenario",level:2},{value:"User stories",id:"user-stories",level:3},{value:"Authress permissions model",id:"authress-permissions-model",level:2},{value:"Implementation steps",id:"implementation-steps",level:2},{value:"1. Get all users in a tenant",id:"1-get-all-users-in-a-tenant",level:3}
1,{value:"2. Get the tenant a user has access to",id:"2-get-the-tenant-a-user-has-access-to",level:3},{value:"3. Fetch users for multiple accounts",id:"3-fetch-users-for-multiple-accounts",level:3},{value:"4. Grant a user access to multiple accounts",id:"4-grant-a-user-access-to-multiple-accounts",level:3},{value:"5. When to use Authress:Tenants versus Accounts",id:"5-when-to-use-authresstenants-versus-accounts",level:3},{value:"6. Get all users that have access to a resource",id:"6-get-all-users-that-have-access-to-a-resource",level:3}],l={toc:c};function h(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},l,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"This guide focuses on how to build a user experience that potentially supports complex tenant and user management for your users via query and list endpoints using Authress ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/authorization/access-records"},"Access Records"),". Here, we pick up from the previous guide ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/usage-guides/onboarding-users/"},"Onboarding Users"),"."),(0,a.kt)("h2",{id:"scenario"},"Scenario"),(0,a.kt)("p",null,"You are extending your application to give your users the ability to configure their account. Users will want to specify who has access to their account's resources and to grant new access to existing members. For user invites and onboarding new users, check out the ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/usage-guides/onboarding-users/"},"Onboarding Users guide"),". This means we'll need to provide the users a dialog which includes users as well as their permissions via the available tenants. The result will be the right users have access to right resources in your Authress account."),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},"When the term ",(0,a.kt)("inlineCode",{parentName:"li"},"User")," is used in this guide, we refer to your application's users, one of your customers."),(0,a.kt)("li",{parentName:"ul"},"Likewise, ",(0,a.kt)("inlineCode",{parentName:"li"},"Account")," refers to your user's customer configuration in your application."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Authress account")," will always mean your account in the Authress management portal, used for configuration of your Authress account."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Authress tenant")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"tenant")," will refer the the Authress authentication configuration for logging a user in."))),(0,a.kt)("h3",{id:"user-stories"},"User stories"),(0,a.kt)("p",null,"There are multiple possible ways to fetch users and review access, so it helps to think in terms of concrete user stories. There are two core ",(0,a.kt)("inlineCode",{parentName:"p"},"user stories")," related to user management that we will tackle throughout this guide:"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},(0,a.kt)("strong",{parentName:"p"},"1. Assigning Permissions User Story")," - A user is the Account owner of a resource in your product. After inviting other users to the Account, the Account owner wants to configure the permissions other users have. Examples might be setting other users to also be owners of the Account, or granting them read only permissions. The Account owner will want to fetch a list of all users for the tenant, and then set the permissions associated with each of those users. Some admin users will have access to multiple tenants and the users in each of those tenants.")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},(0,a.kt)("strong",{parentName:"p"},"2. Reviewing Access User Story")," - The Account owner wants to achieve yearly compliance by ensuring only the right users have access to the resources owned by their Account. Frequently they'll want to fetch the list of users that have access to the Account, and review which users have which access.")),(0,a.kt)("p",null,"Inviting users is a flow handled in the ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/usage-guides/onboarding-users/#5-inviting-other-users-into-the-shared-account"},"Onboarding Users guide"),"."),(0,a.kt)("p",null,"The rest of the guide will review an implementation for how to deliver the above user stories. And since permissions are controlled by ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/authorization/access-records"},"Access Records")," in Authress, we'll see a heavy use of Access Records below. The pieces required are:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#1-get-all-users-in-a-tenant"},"1. Get all the users in a tenant")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#2-get-the-tenant-a-user-has-access-to"},"2. Get user accounts")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#3-fetch-users-for-multiple-accounts"},"3. List multiple accounts' users")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#4-grant-a-user-access-to-multiple-accounts"},"4. Grant access to multiple accounts")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#5-when-to-use-authresstenants-versus-accounts"},"5. Accounts versus Tenants")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#6-get-all-users-that-have-access-to-a-resource"},"6. Auditing user access"))),(0,a.kt)("h2",{id:"authress-permissions-model"},"Authress permissions model"),(0,a.kt)("p",null,"In this guide, we'll be discussing access to accounts, the users in an account, and the permissions those users have. This means it is important to review the following recommended ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/authorization/access-records"},"Authress access record model"),":"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Each user's permissions for an account will be stored in a single access record"),(0,a.kt)("li",{parentName:"ul"},"Since a user can have access to multiple accounts, we will create access records with ",(0,a.kt)("strong",{parentName:"li"},"IDs")," in the following format ",(0,a.kt)("inlineCode",{parentName:"li"},"rec_user_${userId}"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Accounts/{accountId}")," is the ",(0,a.kt)("inlineCode",{parentName:"li"},"resourceUri")," that represents the whole account resource. We will use access to ",(0,a.kt)("inlineCode",{parentName:"li"},"Accounts/{accountId}")," to represent access to an Application Customer Account.")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"Reminder: Authress resources are prefixed by the namespace ",(0,a.kt)("inlineCode",{parentName:"p"},"Authress:"),", access to change an ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/authentication/connecting-providers-idp/"},"Authress connection")," is ",(0,a.kt)("inlineCode",{parentName:"p"},"Authress:Connections/{connectionId}"),", and access to change the Authress configuration for ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/authentication/tenants"},"a tenant in Authress")," is ",(0,a.kt)("inlineCode",{parentName:"p"},"Authress:Tenants/{tenantId}
1"),". Access to ",(0,a.kt)("inlineCode",{parentName:"p"},"Accounts/{accountId}")," represents access for your users to a Customer Account, and access to ",(0,a.kt)("inlineCode",{parentName:"p"},"Accounts:Tenants/{tenantId}")," represents access to the Authress configuration.")),(0,a.kt)("h2",{id:"implementation-steps"},"Implementation steps"),(0,a.kt)("h3",{id:"1-get-all-users-in-a-tenant"},"1. Get all users in a tenant"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="(Application Service) Get all users in the tenant"',title:'"(Application',"Service)":!0,Get:!0,all:!0,users:!0,in:!0,the:!0,'tenant"':!0},"import { AuthressClient } from '@authress/sdk';\nconst authressClient = new AuthressClient({ authressApiUrl: 'https://auth.yourdomain.com' });\n\nconst userResponse = await authressClient.users.getUsers({\n        tenantId: accountId\n});\n\nconst userList = userResponse.data.users;\n/*\n        userList = [{\n                    name: 'User Name',\n                    userId: 'User ID',\n                    picture: 'https://www.gravatar.com/avatar/?d=identicon',\n                    email: '[email protected]'\n        }];\n*/\n")),(0,a.kt)("p",null,"The returned user list will only include users that have logged in through the tenant configuration specified by the ",(0,a.kt)("inlineCode",{parentName:"p"},"tenantId"),". Using this list allows you to populate default drop downs and displays that include multiple users. This API is restricted to service clients that have ",(0,a.kt)("inlineCode",{parentName:"p"},"users:read")," permission on ",(0,a.kt)("inlineCode",{parentName:"p"},"Authress:Users"),", For more information on the permissions that Authress APIs require review the ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/account-management/sso/#authress-management-resources"},"Authress management resources permissions"),"."),(0,a.kt)("p",null,"You'll notice in the above code block that there is no access check for whether or not users should be returned. And further we need to actually know which ",(0,a.kt)("strong",{parentName:"p"},"Account")," users we should display for the user. To do this we'll check that user's access using the Authress Authorization Check:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="(Application Service) User Authorization Check"',title:'"(Application',"Service)":!0,User:!0,Authorization:!0,'Check"':!0},"const userIdentity = await TokenVerifier('https://auth.yourdomain.com', userToken);\nawait authressClient.userPermissions.authorizeUser(userIdentity.sub, `Accounts/${accountId}`, 'accounts:read');\n")),(0,a.kt)("p",null,"In this case, when we know which customer account we want to fetch the users for, we can use the user's token to validate access to the specified account. The ",(0,a.kt)("inlineCode",{parentName:"p"},"accounts:read")," permission as well as the ",(0,a.kt)("inlineCode",{parentName:"p"},"Accounts/{accountId}")," are properties defined by you in your Authress Account, assigned to your users via access records, and then checked here."),(0,a.kt)("h3",{id:"2-get-the-tenant-a-user-has-access-to"},"2. Get the tenant a user has access to"),(0,a.kt)("p",null,"It isn't required to always know the user's tenant a priori. We can instead use the Authress User Permissions List endpoint to fetch the accounts the user has access to. Since your application will assign users access in accordance with the above ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/usage-guides/querying-and-displaying-users/#authress-permissions-model"},"permissions model"),", the relevant resources will be of the form ",(0,a.kt)("inlineCode",{parentName:"p"},"Accounts/account_001"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Accounts/account_002"),", etc..."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="(Application Service) Get customer account and tenant users"',title:'"(Application',"Service)":!0,Get:!0,customer:!0,account:!0,and:!0,tenant:!0,'users"':!0},"const userIdentity = await TokenVerifier('https://auth.yourdomain.com', userToken);\nconst resourceResponse = await authressClient.userPermissions.getUserResources(userIdentity.sub, 'Accounts', 10, null, 'accounts:read', 'INCLUDE_NESTED');\nconst accounts = resourceResponse.data.resources;\n\n// And then fetch the users for relevant account:\nconst userResponse = await authressClient.users.getUsers({\n        tenantId: accounts[0].resourceUri;\n});\n")),(0,a.kt)("p",null,"The result will be a list of users, which have logged in with that specific Authress Tenant, for each Tenant that matches a Customer Account for which the user has the ",(0,a.kt)("inlineCode",{parentName:"p"},"accounts:read")," permission. "),(0,a.kt)("div",{className:"image-md"},(0,a.kt)("p",null,(0,a.kt)("img",{alt:"Fetching multiple users from tenant",src:s(96340).Z,width:"1766",height:"470"}))),(0,a.kt)("h3",{id:"3-fetch-users-for-multiple-accounts"},"3. Fetch users for multiple accounts"),(0,a.kt)("p",null,"Some users in your application might have access to multiple customer ",(0,a.kt)("strong",{parentName:"p"},"Accounts"),". When populating a user related drop down selection, great care should be used in deciding whether or not to display users or resources across multiple tenants. The Authress recommendation is only display users or resources for one tenant at a time. This prevents administrative users from accidentally selecting the wrong users or the wrong resources. In any list that includes users or resources from multiple tenants, please ensure that the ",(0,a.kt)("strong",{parentName:"p"},"Account ID")," is clearly indicated in all displays."),(0,a.kt)("p",null,"For rare cases where a user admin is logged in that should be able to see multiple users from multiple tenants at the same time, but only a subset of all the users present in your Authress account, Interleaving the results from multiple ",(0,a.kt)("inlineCode",{parentName:"p"},"getUsers")," api calls is optimal:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="(Application Service) Get users for multiple customer accounts"',title:'"(Application',"Service)":!0,Get:!0,users:!0,for:!0,multiple:!0,customer:!0,'accounts"':!0},"const listsAsync = accounts.map(account => authressClient.users.getUsers({\n        tenantId: accounts.resourceUri;\n}));\nconst userResponseForTenants = await Promise.all(listAsync);\nconst paginatedUsers = userResponseForTenants.map(tenantResponse => tenantResponse.data.users).flat();\n\nreturn paginatedUsers;\n")),(0,a.kt)("h3",{id:"4-grant-a-user-access-to-multiple-accounts"},"4. Grant a user access to multiple accounts"),(0,a.kt)("p",null,"To actually grant a user permissions to multiple accounts, we can review the above ",(0,a.kt)("a",{parentName:"p",href:"/knowledge-base/docs/usage-guides/querying-and-displaying-users/#authress-permissions-model"},"permissions model")," to see that we should have a dedicated Access Record for the user."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="(Application Service) Grant user access to multiple tenants"',title:'"(Application',"Service)":!0,Grant:!0,user:!0,access:!0,to:!0,multiple:!0,'tenants"':!0},"await authressClient.accessRecords.createRecord({\n        name: `User: ${userId}`,\n        recordId: `rec_user_${userId}`,\n        users: [{ userId: userId }],\n        statements: [{\n                roles: ['Admin'],\n                resources: [\n                        { resourceUri: `/Accounts/account_001` },\n                        { resourceUri: `/Accounts/account_002` }\n                ]\n        }
1]   \n});\n")),(0,a.kt)("p",null,"When a user is assigned multiple resources, each of these resources will be returned in the earlier ",(0,a.kt)("inlineCode",{parentName:"p"},"getUserResources()")," request ",(0,a.kt)("a",{parentName:"p",href:"#2-get-the-tenant-a-user-has-access-to"},"above"),"."),(0,a.kt)("h3",{id:"5-when-to-use-authresstenants-versus-accounts"},"5. When to use Authress:Tenants versus Accounts"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"Authress:Tenants")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Accounts")," represent two different concepts in Authress:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Authress:Tenants")," is the Authress resource that represents the Authress tenant configuration in Authress. This configuration enables users to log in with their Corporate SSO IdP. Usually this configuration can only be changed by an Authress Account Admin or an ",(0,a.kt)("a",{parentName:"li",href:"/knowledge-base/docs/authorization/service-clients/"},"Authress Service Client")," that you have given sufficient access to. The ",(0,a.kt)("inlineCode",{parentName:"li"},"ID")," of the tenant matches your customer ",(0,a.kt)("inlineCode",{parentName:"li"},"Accounts")," and is the value passed as the ",(0,a.kt)("inlineCode",{parentName:"li"},"tenantId")," in both authentication requests as well as ",(0,a.kt)("inlineCode",{parentName:"li"},"user queries"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Accounts")," represents your application customers accounts. Authress actually doesn't need to know what your internal identifiers are called. Your application might call these ",(0,a.kt)("strong",{parentName:"li"},"tenants")," or ",(0,a.kt)("strong",{parentName:"li"},"customers")," or ",(0,a.kt)("strong",{parentName:"li"},"organizations"),". As long as all the above API calls and Access Records in Authress use a consistent ",(0,a.kt)("strong",{parentName:"li"},"resourceUri")," such as ",(0,a.kt)("inlineCode",{parentName:"li"},"Accounts/"),", then the functionality will work as expected. For this reason this guide uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Accounts/"),", however you could theoretically replace every instance of ",(0,a.kt)("inlineCode",{parentName:"li"},"Accounts/")," in this usage guide with ",(0,a.kt)("inlineCode",{parentName:"li"},"Organizations/")," and everything would still work as ",(0,a.kt)("inlineCode",{parentName:"li"},"Accounts")," is not a reserved concept in Authress, but rather one on the application side.")),(0,a.kt)("p",null,"Further, your end users are not usually given direct access to the ",(0,a.kt)("inlineCode",{parentName:"p"},"Authress:Tenants")," resource, because this would allow them to directly change the Authress configuration in a way that might not be preferred by your application. An example might be ",(0,a.kt)("inlineCode",{parentName:"p"},"DELETE Authress:Tenants/tenant_001"),". Deleting a tenant is likely something that you don't want to allow your users to do. It is common however to enable users the ability to update the tenant SSO configuration based on the needs of that customer. In these cases, Authress recommends to create a permission that matches this need, and assign it to users as necessary. An example might be:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="(Application Service) Update Authress Tenant configuration on behalf of an Admin User"',title:'"(Application',"Service)":!0,Update:!0,Authress:!0,Tenant:!0,configuration:!0,on:!0,behalf:!0,of:!0,an:!0,Admin:!0,'User"':!0},"import { AuthressClient } from '@authress/sdk';\nconst authressClient = new AuthressClient({ authressApiUrl: 'https://auth.yourdomain.com' });\n\nconst userIdentity = await authressClient.verifyToken(userToken);\n\nconst accountId = 'account_001';\nawait authressClient.userPermissions.authorizeUser(userIdentity.sub, `Accounts/${accountId}/SSO`, 'accounts:sso:update');\n\nawait authressClient.tenants.updateTenant(accountId, {\n        tenantLookupIdentifier: 'Tenant-Lookup-Identifier',\n        connection: {\n                connectionId: 'google'\n        },\n        domains: [{\n                domain: 'customer.domain.com'\n        }
1],\n        data: {\n                name: 'Tenant Name'   \n        }\n});\n\n")),(0,a.kt)("h3",{id:"6-get-all-users-that-have-access-to-a-resource"},"6. Get all users that have access to a resource"),(0,a.kt)("p",null,"As part of being an account admin, one of your users might require asking who are all the users that have access to a customer resource. That resource could be a specific document or element in your application, or it could be access to the whole tenant itself. An example might be who are all the account admin of my account? The goal could be display something similar to this:"),(0,a.kt)("div",{className:"image-md"},(0,a.kt)("p",null,(0,a.kt)("img",{alt:"List of tenant users",src:s(83027).Z,width:"499",height:"568"}))),(0,a.kt)("p",null,"To get the list, we can use the ",(0,a.kt)("inlineCode",{parentName:"p"},"resources.getUsers()")," endpoint and specify the resource that we want to see who has access to that resource."),(0,a.kt)("p",null,"In the case where an account admin would like to know which users have full account access, you might embed a call to Authress to generate that view above:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts",metastring:'title="(Application Service) Get users with active permissions to the account"',title:'"(Application',"Service)":!0,Get:!0,users:!0,with:!0,active:!0,permissions:!0,to:!0,the:!0,'account"':!0},"import { AuthressClient } from '@authress/sdk';\nconst authressClient = new AuthressClient({ authressApiUrl: 'https://auth.yourdomain.com' });\n\nconst accountId = 'account_001';\n\nconst userIdentity = await authressClient.verifyToken(userToken);\nawait authressClient.userPermissions.authorizeUser(userIdentity.sub, `Accounts/${accountId}`, 'accounts:users:read');\n\nconst resourceUsersResponse = await authressClient.resourcePermissions.getResourceUsers(`Accounts/${accountId}`);\n\nconst users = resourceUsersResponse.data.users;\n/*\n        users = [{\n                    userId: 'User ID',\n                    roles: [{ roleId: 'Admin' }, { roleId: 'Editor' }]\n        }];\n*/\n\n// And then optionally combine that with the user list endpoint:\nconst userResponse = await authressClient.users.getUsers({\n        tenantId: accountId\n});\n\nconst userPaginatedList = users.map(u => userResponse.data.users.find(userData => userData.userId === u.userId));\nreturn userPaginatedList;\n\n")),(0,a.kt)("admonition",{type:"info"},(0,a.kt)("p",{parentName:"admonition"},"One note related to permissions management for tenants is the usage of Authress Groups. Groups also can be given direct permissions as well. They help by creating a layer of indirection and abstraction for aspects that are commonly associated with a group. For instance, you might have a customer account where the customer admin keeps track of third party contractors. Rather than individual access for each contractor, you might allow that customer to create an Authress group for all their contractors.")))}h.isMDXComponent=!0},96340:(e,t,s)=>{s.d(t,{Z:()=>n});const n=s.p+"assets/images/fetch-users-e0d8e9cdf80e02bc546feb4b1277ca97.png"},83027:(e,t,s)=>{s.d(t,{Z:()=>n});const n=s.p+"assets/images/user-display-list-b8987ede27c36ad96f444e0ea3c3f70b.png"}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.