Get the signed-in worker with workers/me
In an Extend page, call the worker endpoint with me in place of an ID: workers/me returns the signed-in user's own worker record, and Workday's tutorial describes me exactly that way, as the current user's ID. There is no predefined app variable that holds the user's worker ID; userTimeZone and languageCode exist, but the identity comes from this call.
{
"name": "currentWorker",
"baseUrlType": "workday-staffing",
"url": "workers/me",
"authType": "sso"
}
Workday's samples use both the Staffing and the Common service for this; one of them calls common/v1/workers/me through a general data provider. Either way the response's id is the worker's Workday ID and descriptor is their display name. If you also need the user's time zone for formatting, the Common service's userInfo endpoint returns it, and the userTimeZone variable already holds the preferred one.
"authType": "sso" sends the call as the signed-in user, which is what makes me resolve to them.
Filter records by them with a query parameter
Once you have the ID, filter the business object's collection on the field that holds the worker. Extend generates query parameters for every indexed field, and every SINGLE_INSTANCE field is indexed automatically, so a requester field targeting WORKER gives you ?requester=:
{
"name": "myRequests",
"baseUrlType": "app",
"url": "<% 'equipmentRequests?requester=' + currentWorker.id %>",
"authType": "sso"
}
Workday's Employee Relations sample does the same to load a user's own preferences record, userPreferencesBO?worker= plus the ID from workers/me. The request still runs under the business object's domain security, and with more than one query parameter the user must have access to the instances returned by all of them. The same index serves custom report filters and the WHERE clause of WQL queries, so the worker field is also the one to filter on there. With secureByTarget set on it (below), Workday also adds an "is [business object name] accessible" filter to the business object's data source.
Filter on the server like this rather than loading everything and filtering in script. Workday's samples do use list:filter(data, 'assignedTo.id', currentUserData.id) for an "Assigned to me" view of data already loaded, and that is fine for switching views on a page. It isn't a control: the page has already fetched every record the user's security allows, and anything that calls the API directly can read them.
Stamp the current user when records are created
The same ID fills "requested by" and "created by" fields, so the filter has something to match. Bind it in the outbound endpoint that creates the record, as Workday's examples do:
{
"name": "createRequest",
"baseUrlType": "app",
"url": "equipmentRequests",
"httpMethod": "POST",
"authType": "sso",
"values": [
{ "outboundPath": "requester.id", "value": "<% currentWorker.id %>" }
]
}
To show the user as the default in a worker prompt while letting them pick someone else, set both values and selectedValues to [currentWorker]; the brackets turn the single record into the list those attributes expect. The worker search guide adds the search part.
When "only their records" is a security requirement
If people must not be able to see each other's records at all, express that in security, not in the URL. Set "secureByTarget": true on the requester field:
{
"id": 2,
"name": "requester",
"label": "Requester",
"type": "SINGLE_INSTANCE",
"target": "WORKER",
"secureByTarget": true
}
With contextual security on a field, the business object's REST API returns only the instances the processing user is contextually secured to view, whatever the URL asks for. Then, in the domain's security policy, add the groups who should see records through that worker. Contextual security also changes what groups you may use: if no SINGLE_INSTANCE field in the app has secureByTarget, Workday allows only public and unconstrained groups on the app's domains; once one does, any security group type is allowed, so self-service and role-based groups evaluated against the requester become options. The secureByTarget guide covers multiple targets and how they combine.
The same applies to tasks. A task with "secured": true and a business object context shows its related action only on instances the user is contextually secured to. Workday says that task's domain security policy shouldn't then contain any unconstrained groups.
Check it as two different people
- Create a record as user A and confirm the
requesterfield holds A's worker ID by reading the record back withGET /equipmentRequests/{id}. - Open the "My requests" page as A, then as user B. A sees the record; B doesn't.
- If you added
secureByTarget, have B open a page that requests A's record by its ID withGET /equipmentRequests/{id}. The record should not come back. If it does, the domain policy contains a group that reaches A through some other context, or an unconstrained group.
Step 3 is the one that separates a filter from a control, and it needs a second real user. kiweely can run the page in a test tenant as each of those roles and read the records back as each of them, so the result shows what Workday's security actually allowed rather than what the page displayed.
Sources checked
- Display Information on a View Page
- Reference: Predefined App Variables
- Example: Query Parameters in Business Object API Requests
- Reference: Business Object API Requests
- Concept: Allowed Security Group Types for Extend Apps
- Extend Business Process Event REST API
- Add Tasks with Business Object Context
- Concept: instanceList