
Workday Integration System User Setup for RaaS OAuth Access
.jpg)
Summarise the blog with AI
Key takeaways
- OAuth access to a RaaS report runs through four objects: an ISU in an Integration System Security Group, the report shared with that ISU, an API Client for Integrations, and a refresh token bound to the ISU.
- The API client's scope must include whichever functional area owns Report Execution in that tenant; run View Domain to find it.
- Only Advanced custom reports can be web services, and the report must be shared with the ISU or Workday won't serve it.
- The refresh token's Workday Account field must name the exact ISU the report is shared with.
- The client secret is shown once, at registration, so move it into a secrets store immediately.
- Basic auth with the ISU's own username and password is the other supported route.
An OAuth client for Workday Reports as a Service (RaaS) can exchange its token cleanly and still fail to return the report. The problem sits upstream of the credential.
The API client's scope misses the functional area that runs reports. The report exists but was never shared with the identity calling it. The refresh token points at an admin account instead of the integration user it was built for. Each looks like a token problem. None of them are.
The four sections below build these objects in the order they have to exist, then a table and a one-call test that confirm they resolve to each other before you hand the credential to anyone else.
The integration system user and its security group
Everything in this sequence points back to one account: a dedicated ISU. Workday's task for creating it is named exactly that, Create Integration System User, which doubles as the search term you need in Workday Community, since much of Workday's documentation sits behind a Community login.
Use a dedicated, non-human account for this integration. RaaS exposes the underlying report as a read-only web service no matter what you grant it, so a broader identity buys nothing except one more login to justify in a security review.
Building the identity and its permissions is four steps, in order:
- Create the ISU. Run Create Integration System User, give the account a username and a strong password, and set it so it can't open a UI session. It exists only to call web services.
- Create its security group. Run Create Security Group, choose Integration System Security Group (Unconstrained), and add the ISU as the group's only member.
- Grant domain permissions. Run Maintain Permissions for Security Group on that group and add Get access to the domains that hold the report's data, such as Worker Data: Public Worker Reports. Add nothing it won't read.
- Activate the changes. Run Activate Pending Security Policy Changes. Until you do, the new permissions exist on screen but don't apply to any call.
The same reasoning applies to any credential you're handed on a customer's behalf: scope it to the minimum the integration will actually use, not to the most an admin was willing to grant.
None of this matters if the report the ISU is trying to reach was never exposed to it in the first place.
Expose the report to that identity
A correctly built ISU still can't run a report that hasn't been turned into a web service, or one that's a web service but was never shared with it. Before RaaS will serve it, the report has to satisfy three conditions:
- It's an Advanced report. Only Advanced custom reports can be exposed as web services.
- It's enabled as a web service. The report definition has Enable As Web Service checked, which is what gives it a callable URL.
- It's shared with the ISU. On the report's Share tab, add the ISU as an authorized user. This is the step most often skipped.
Once those three are set, the report's callable URL is under the report's related actions: run View Custom Report, then Web Service > View URLs. Skip the sharing step and the ISU still authenticates, but Workday won't serve it a report it wasn't given, which can go unnoticed until the customer asks why the integration has no data.
An ISU with a shared report can see the data. It still can't reach it through OAuth until something is authorized to request it on the ISU's behalf.
Register the API client and find its scope
The API client is what holds the OAuth credential, and its scope is the setting generic answers get wrong. You may see "Report as a Service" given as the functional area to select. The functional area that owns the Report Execution domain varies by tenant, so the only reliable answer is the one View Domain returns in the customer's tenant.
Registering the client is four steps:
- Confirm OAuth is on. In Edit Tenant Setup - Security, check that OAuth 2.0 Clients Enabled is selected.
- Find the functional area. Run View Domain on Report Execution and note the functional area the tenant assigns it.
- Register the client. Run Register API Client for Integrations (not plain Register API Client, which is for the authorization-code flow) and add that functional area under Scope (Functional Areas).
- Save the client ID and secret immediately. Workday shows the client secret once, on the confirmation screen, and never again.
That last step is the one people lose an afternoon to. A secret that exists on screen once belongs in a managed secrets store the moment it appears, the same principle OWASP's Secrets Management Cheat Sheet states for any credential: store it centrally, control who can read it, and make that access auditable. A ticket comment is not a secrets store.
A client with the right scope and a saved secret still isn't authorized as anyone. That's what the refresh token does.
Bind the refresh token to the same ISU
A refresh token generated under Manage Refresh Tokens for Integrations doesn't inherit an identity from the client requesting it. It gets one explicitly, from the Workday Account field on the token itself, and that field has to name the exact ISU the report was shared with. Leave it blank, or point it at whoever happened to be logged in as an admin, and the token exchanges cleanly, authenticates cleanly, and still can't run the report, because as far as Workday is concerned it isn't acting as the ISU at all.
Generating the token that actually acts as the ISU is three steps:
- Open the token task. From the API client's related actions, run Manage Refresh Tokens for Integrations.
- Name the ISU. In the Workday Account field, select the exact ISU the report is shared with, not your own admin account.
- Generate and store it. Click Generate New Refresh Token and move the token into the same secrets store as the client secret.
One setting deserves a deliberate choice: the registration form offers a Non-Expiring Refresh Tokens option. Never expiring is one less rotation to manage, but OWASP's Non-Human Identities Top 10 names exactly this pattern, a long-lived secret with no forced rotation, as what turns a single leak into standing access. RFC 9700 caps the damage somewhat, since a refresh token issued to a confidential client only works for that client, but a rotation schedule is still cheaper than an incident.
Four objects now exist and, in theory, point at each other. The only way to know they do is to make the call.
Verify the credential set before handoff
The only real verification is to exchange the refresh token for a bearer token and call the report URL with it, once. A failure at that point maps back to whichever step produced the piece that's wrong.
Workday's documentation gives the token endpoint a fixed shape: https://<HOST>/ccx/oauth2/<TENANT>/token, with your tenant's host and tenant ID substituted in. Exchange the refresh token there for a bearer token, call the report's web-service URL with it in the Authorization header, and a response with report rows is the only real confirmation that ISU, security group, report share, client scope, and token all resolved to the same identity.
That test confirms the credential works. It says nothing yet about how often, or through what, the data moves once something starts consuming it.
What happens after the credentials leave the tenant
RaaS has no push path. Nothing in Workday calls out when a record changes, so whatever consumes the report has to poll it on a schedule and treat each pull as the current state.
That's true no matter who holds the credential. The difference between platforms is how they use it once they have it. Bindbee authenticates with the same OAuth client you just built, using the ISU's refresh token, so it never holds the ISU's password or a scraped session, and it syncs every 24 hours by default, adjustable per connection.
Handing a client secret and a refresh token to any third party deserves the same scrutiny you'd apply to a payroll vendor. What a counterparty checks before it will accept the credential at all usually starts with how the platform stores it and who can read it. Bindbee's side of that is SOC 2 Type II and ISO 27001 certification, HIPAA and GDPR compliance, and data encrypted in transit (TLS 1.2 or higher) and at rest (AES-256).
The exact fields Bindbee's connection form asks for, and how they map to the client ID, secret, refresh token, and report URL you just built, are covered in Bindbee's Workday RaaS connection guide. If Workday RaaS is the integration you're building toward, see how Bindbee connects to it once this credential set exists.
Every piece of this setup traces back to the same test: does the ISU in the security group match the ISU the report is shared with, and match the account in the refresh token's Workday Account field? When all three point at one identity, the credential works the first time. When they don't, check which one drifted before you re-read the OAuth error.
Frequently asked questions
Can a Workday custom report be created through the API?
Plan on building it by hand with Workday's Create Custom Report task, the way Bindbee's connection guide does; nothing on this page depends on creating reports through an API. Once the report exists, the access sequence on this page, security group, web service, API client scope, and refresh token binding, applies the same way regardless of how the report was built.
Which functional area does a RaaS API client need in its scope?
The one that owns the Report Execution domain in that customer's tenant. It varies by tenant, so run View Domain on Report Execution and add the functional area it returns, rather than relying on a generic answer like "Report as a Service".
Why does my Workday OAuth token work but the report call fails or returns nothing?
Usually because one of the four objects points at the wrong identity: the refresh token's Workday Account isn't the ISU, the report was never shared with the ISU, or the API client's scope misses the Report Execution functional area. The verification table above maps each symptom to its step.
Can I use basic auth instead of OAuth for Workday RaaS?
Yes. Basic auth with the ISU's own username and password is the other supported route to a RaaS report. The ISU, security group, and report sharing steps still apply; only the API client and refresh token steps drop out.
Should Workday refresh tokens be non-expiring?
The registration form offers Non-Expiring Refresh Tokens, which means one less rotation to manage. OWASP's Non-Human Identities Top 10 flags long-lived secrets with no forced rotation as what turns a single leak into standing access, so a rotation schedule is usually the safer choice.



.jpg)


