# Objects

How a role can be limited to some of a server's objects, on any server that declares its objects.

In short: An MCP server often reaches many databases or repositories with a single credential. With objects, a role covers every object or only the ones it names. A call such as `read_rows(database: "sales_us")` then passes only if a role of the caller covers sales_us. Otherwise the gateway refuses the call before any policy rule runs.


Anobjectisathingthataserver'stoolsacton,suchasadatabaseorarepository.Strazacanlimitaroletosomeobjectsofaserveronlywhentheserverdeclaresthem.##WhyaroleneedsobjectsA[role](https://docs.straza.ai/concepts/roles-and-access/index.md)namesthe[tools](https://docs.straza.ai/concepts/mcp-apps-and-the-gateway/index.md)itsholdersmaycallononeserver.Withasinglecredential,aserveroftenreachesmanythings,suchaseveryrepositoryaGitHubAppisinstalledon,oreverydatabaseintheserver'sconfiguration.Arolethatholdsawritetoolcouldthenwriteinallofthem.Objectslimittheroletotheonesitnames.##WhataserverdeclaresAserverdeclaresoneobjecttype.Foreachtoolitsayswhichargumentnamestheobject,orthatthetoolreacheseveryobjectornoneofthem.Aread-onlytoolliststheobjects,andStrazacallsititself,withacredentialkeptonlyforthatcallwhentheservertakesone.Diagram:Thewikiserverisinvented,sotheideadoesnotleanononeproduct.postgresisadaptive-pg-mcpwithitsrealdatabasesandrole,asthedemostackrunsitwiththeprofilepg.Twoserverssidebyside.Theinventedwikiserverdeclaresthetypespace,andarolecoveringthespaceengallowspage_editonengandrefusesitonlegal.Thepostgresserverdeclaresthetypedatabase,andarolecoveringsales_euallowsread_rowsonsales_euandrefusesitonsales_us.1.Eachserverdeclaresoneobjecttype,andwhichargumentofeachtoolnamesoneobject.2.Strazacallseachserver'slisttoolitself,withacredentialitkeepsforthatcallalone,andkeepsthelist.3.Arolecoverseveryobject,oronlytheobjectsitnames.4.Thegatewaycheckstheobjectacallnames.Acallonanobjectthatnoroleofthecallercoversisrefusedbeforeanypolicyrule.||wiki,inventedforthispage|postgres,whichrunsadaptive-pg-mcp||---|---|---||Objecttype|space,pluralspaces|database,pluraldatabases||Toolsthatnameone|`page_read`and`page_edit`,intheargument`space`|`read_rows`,`insert_rows`and12more,intheargument`database`||Thetoolthatliststhem|`space_list`|`list_databases`||Toolsthatreacheveryone|`space_list`and`search`|`list_databases`|PinningadeclarationkeepsacopyofitinStraza.Apersonpublishesthatcopyina[draft](https://docs.straza.ai/concepts/drafts/index.md),andStrazadecideswithit.Whattheserverreportswhileitrunscanonlynarrowacall,soaservercannotwidenitsownreach.Ifatoollaterdiffersfromthepinnedcopy,rolesonsomeobjectscannotusethattooluntilapersonpublishesanewcopy.##WhatarolecoversOnceaserver'sobjecttypeispinned,eachroleonthatserversayswhichobjectsitcovers.Aroleoneveryobjectcoverstheonestheserverliststodayandtheonesitlistslater.Arolethatnamesitsobjectscoversonlythose,andanobjectaddedlaterisnotcovereduntilapersonaddsit.Toolsthatreacheveryobjectatonce,suchasthelisttool,belongonlyinaroleoneveryobject,becausenothinglimitsthemtosomeobjects.Strazakeepseachnamedobjectwithitsidfromthelist,soarolestillcoversanobjectthatisrenamed.Anobjectdeletedandmadeagainundertheoldnameisanewobject.Arolethatnamedtheoldonedoesnotcoverit,butaroleoneveryobjectdoes.Whenaserverwithrolesispinnedforthefirsttime,thoserolescovereveryobject,sonobodygainsorlosesaccessatthatmoment.##Howthegatewaychecksacall1.Strazafindsthetoolamongthetoolsthesession'srolesreach.2.Itappliestheserver'sratelimit.3.Itreadstheobjectthecallnamesandlooksforaheldrolethatcoversit.4.The[policy](https://docs.straza.ai/concepts/policy-model/index.md)decidesthecall.5.Ifaruleasks,aperson[approves](https://docs.straza.ai/concepts/approvals-model/index.md)it,andtheapprovalappliesonlytothatobject.Theobjectcheckrunsbeforethepolicy,sonorulecanallowacallthecheckrefused,andnobodyisaskedtoapproveone.The[agent](https://docs.straza.ai/concepts/identities/index.md)getsamessagethatnamesonlytheobjectsitsownrolescover:```textStraza:page_editonlegalwasrefused:noneofyourrolesonwikicoversthatspace.Yourrolescoverpage_editoneng.Checkthespace'sname,oraskanadminforarolethatcoversit.```Anamethatnorolecoversandanamethelistdoesnotholdgetthesameanswer,soanagentlearnsnothingaboutobjectsitcannotuse.##WhatyourIGAseesEachroleappearsin[yourIGA](https://docs.straza.ai/evaluate/identity-and-your-iga/index.md)asaSCIMgroupthatsayswhatitcovers,intheformthetableshows.Acertifiercanreadthesevaluesbutcannotchangethem.|Role|Covers,asyourIGAshowsit||---|---||wiki-eng|`wiki:space"eng"`||aroleoneveryspace|`wiki:spaceevery`||postgres-sales-eu|`postgres:database"sales_eu"`|[midPoint](https://docs.straza.ai/guides/connect-identity/midpoint/index.md#check-the-imported-roles)showsthesevaluesintheCoverscolumnofitsStrazaapplicationroles.##WhereobjectsarecheckedOnlythegatewaychecksobjects.Alocaltoolthatahookdecidesnamesnoobject.TheservermakesthreepromisesthatStrazacannotcheck:acalltouchesonlytheobjectitsargumentnames,thenamemeansexactlyoneobjectatthemomentofthecall,andtheserveracceptscallsonlyfromthegateway,orchecksacredentialthatonlythegatewayholds.[Objectmarksforserverauthors](https://docs.straza.ai/reference/object-marks/index.md#promises)sayshowaserverkeepsthem,and[Limitaroletosomeobjects](https://docs.straza.ai/guides/serve-mcp-apps/limit-a-role-to-some-objects/index.md)showsthesetup.Thefourreachesapinnedtoolcanhave:Thereachofatooldecideswhichheldrolesmaycallit.|Reach|Whatthetooldoes|Whichheldrolemaycallit||---|---|---||Argument|Namesoneobjectinanargument|Arolethatcoversthatobject||None|Touchesnoobject,suchasatoolthatsayswhothecalleris|Anyrolethatmaycallthetool||All|Canreacheveryobjectatonce,suchasasearchacrossthem|Onlyaroleoneveryobject||Credential|Namesnoobjectandleavesthelimittothecredentialthecallcarries|Onlyaroleoneveryobject,becauseStrazadoesnotyetcheckwhatarole'sowncredentialreaches|Atoolthepinnedcopydoesnotnamecountsasreachalluntilapersondecides,soaroleonsomeobjectscannotcallatooltheserveraddslateruntilapersonhasdecidedwhatitreaches.Draftsrefuseatoolofreachallorcredentialinaroleonsomeobjects,beforeanyonecanpublishit.Edgecasesanexpertasksabout:Anobjectcreatedaminuteago,beforeanylistinghasseenit,iscoveredatoncebyaroleoneveryobject.Arolethatnamesitsobjectsdoesnotcoverituntilapersonaddsit.Strazalistseachserverevery10minutesandkeepsthelastgoodlist.Everyreplicaholdsthelistinmemory,soadecisionneverreadsthedatabaseforit.Whenarefusedcallnamesavaluethelistdoesnothold,Strazaasksforalistingsooner,atmostonceaminuteperserver.Strazatriestheheldrolesinnameorder,andthefirstrolethatcoverstheobjectgrantsthecall.The[auditrecord](https://docs.straza.ai/concepts/evidence/index.md)andthecredentiallookupnamethatrole.Arefusallistsatmosttencoveredobjects,thenhowmanymorethereare.Strazarefusesacallwhoseobjectargumentitcannotread,suchasamissingargumentoronethatisnotastring.Thisrefusalappliestoeveryrole,includingaroleoneveryobject.Afterthefirstpin,everyapprovalnamestheobject,soanapprovalgivenbeforethepinisaskedforagain.Whenaroleonsomeobjectsgrantsacall,Strazasendstheobject'sidfromitslistalongwiththecall.Theservercanthenrefuseanobjectthatwasdeletedandmadeagainunderthesamename.Anaccessrowonapinnedserverthatsaysnothingaboutobjectscoversnothing,andadraftrefusestoaddone.Removingthepinmakeseveryroleonthatserverreacheveryobjectagain.Aserver'sownadminmaygivearoleeveryobjectunlessthedeploymentreservesthatforaglobaladmin.Anoperatorcanturntheobjectchecksoffforadeployment.Thenonlyrolesoneveryobjectmaycallatoolthatnamesanobject,soturningthechecksoffneverwidensaccess.Next:[Policies](https://docs.straza.ai/concepts/policy-model/index.md)



