Greenhouse 403 "On-behalf-of user does not have permission" for the agent's service account acting for a recruiter
Fixes Greenhouse 403 'On-behalf-of user does not have permission' when the agent acts for a recruiter via the Harvest API. Use when on-behalf-of calls fail on permissions. Key trigger: 403 naming the on-behalf-of user.
Greenhouse 403 "On-behalf-of user does not have permission"
TL;DR
The Harvest API key is fine, but the recruiter user the agent is acting for lacks permission for that action, so the call is rejected. Fix: grant the recruiter the needed job permissions in Greenhouse, or have the agent act as a user that already has them. On-behalf-of inherits the user's permissions, not the key's.
Error
403 Forbidden
"On-behalf-of user does not have permission"Steps
Identify the on-behalf-of user and the action: check the on-behalf-of header the agent sends and the endpoint that 403d. Expected: you know who and what, e.g. a recruiter moving a candidate on a specific job.
Check that user's permissions in Greenhouse: Site Admin, then Users, then the user's job permissions for the target job. Expected: you see the missing permission, e.g. no access to the job or no move-stage right.
Grant the permission (or ask a Greenhouse admin to): add the user to the job with the right role. Expected: the permission set now covers the action.
Retry the exact call with the same on-behalf-of user. Expected: 200 or 201; no more 403.
For service accounts, consider a dedicated integration user with exactly the permissions the agent needs, instead of borrowing recruiters' identities. Expected: permissions stay stable when recruiters change roles.
Use this when
- Harvest API calls 403 only with on-behalf-of headers
- the agent acts for different recruiters
- permissions work for one user but not another
- a recruiter changed teams and calls started failing
Not for this skill when
- the error is 401 (that is the rotated-key problem)
- every call 403s even without the header (check the API key's own permissions)
- the action succeeds but attributes to the wrong user (check which identity the header names)
Variant phrasings
- "Greenhouse on behalf of permission denied"
- "on-behalf-of 403 Harvest API"
- "service account acting for recruiter 403"
- "on-behalf-of user lacks permission"
Why it happens
On-behalf-of exists so actions are attributed to the right human, and the API enforces that human's actual permissions. The agent's key only gets it in the door; the named user decides what is allowed. When the recruiter's job access changes, the agent's calls start 403ing with no change in code.
Edge cases
- Job permissions are per job; access to one req does not imply access to another.
- A deactivated user 403s everything; check user status, not just roles.
- Some actions need a higher role than the recruiter's current one; escalate deliberately, not by making everyone an admin.
- Log the on-behalf-of user on every call so 403s are diagnosable.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_7vS8jDUoXwNBA0A-Js0R0Q