dataverse_retrieve_access_origin
Find out why a user or team has access to a specific Dataverse record by revealing whether access comes from object ownership or explicit shares, teams, or hierarchy grants.
Instructions
Answer "WHY does this principal have access to this record?".
Calls the unbound RetrieveAccessOrigin function, which explains where a principal's rights over one specific row come from — object ownership, or the Principal Object Access (POA) table that backs explicit shares and team or hierarchy grants.
This is the companion to dataverse_retrieve_principal_access, which returns only the access MASK (which rights: Read, Write, Delete, …) and cannot say where those rights came from. When you are debugging "why can this user see this record?" or "why can't they?", the mask is the symptom and this is the cause. Use dataverse_audit_user_access for the wider picture (roles, teams, effective privileges) and dataverse_get_role_privileges for what one role permits in general rather than on one row.
Inputs:
object_id — the record's own GUID.
logical_name — the SINGULAR lowercase logical name of that record's table ('account', not 'accounts'). This is deliberately not the entity set name the record-access tools take.
principal_id — a systemuser id or a team id. No other principal type is accepted; use dataverse_list_users / dataverse_list_teams.
RESPONSE SHAPE (verified live). Dataverse answers with ONE scalar string property, Response — never a collection, in a raw body of roughly 286 bytes. It is surfaced as access_origin, with access_origin_source naming the property it was read from, and the payload (minus the @odata.* envelope) rides along under raw_response so you can check that for yourself. There is no count: the answer is never list-shaped. Should a future platform change move the answer somewhere unrecognizable, normalized is false, nothing is fabricated, and raw_response is the whole answer.
HTTP 200 DOES NOT MEAN "HAS ACCESS" — READ THE STRING. Three materially different outcomes all come back as a successful call with normalized true, and they are distinguishable ONLY by the English prose inside the string. The text is passed through verbatim and deliberately NOT classified into a boolean: pattern-matching platform prose is fragile and locale-dependent, and a wrong security verdict is worse than none. Observed live in ONE org — these wordings are observations, not a documented platform contract, so treat the list as incomplete and never match on it:
Access exists, with the reason. Two forms seen, both meaning "owner" — "PrincipalId is object owner ()" on a user- or team-owned row, and "PrincipalId is member of organization () who is object owner ()" on an ORGANIZATION-owned row (see the org-owned note below for why that answer is the same for every principal).
NO access at all — "Access origin could not be found. Access does not come from POA table or object ownership."
The record DOES NOT EXIST — still HTTP 200, carrying the platform's "Does Not Exist" exception text inside the Response string. A bad object_id is NOT a 404 from this function, so an unread string looks exactly like a successful answer. Do not report that the principal has access unless the string says so.
Other live-confirmed behaviour:
An unknown but grammar-valid logical_name is a clean HTTP 400 [0x80041102] "... was not found in the MetadataCache", surfaced through the standard {"error": true, "message": ...} envelope. Confirm the name with dataverse_list_tables.
On an ORGANIZATION-owned table (solution, role, …) the answer is the same for every principal, because ownership resolves at organization level. That is correct platform behaviour, not a defect — discrimination between principals shows up on user- and team-owned rows.
A nonexistent principal_id is not validated against an org-owned row: it returned the same generic ownership text as a real one. Confirm the principal exists with dataverse_get_user / dataverse_get_team first.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |