You authenticate to CyberArk’s PVWA API, get a session token back with HTTP 200, then immediately call GET /PasswordVault/api/Accounts and get a 401 Unauthorized. The token looks valid. You confirmed it’s being passed in the request. The account has the right permissions.
Here’s why it’s happening and how to fix it.
The Problem: Wrong Authorization Header Format
CyberArk’s PVWA API (v9.x and earlier) does not use the standard Bearer token format. Sending:
Returns 401 even with a perfectly valid token.
The correct format is the token value without the Bearer prefix:
This trips up most developers because every other modern API uses Bearer. CyberArk’s older API predates that convention and uses its own session token scheme.
Fix in curl
| |
Fix in Ansible
In your uri task:
| |
Fix in Python
| |
Fix in PowerShell
| |
The Token Might Also Have Surrounding Quotes
When CyberArk’s Logon endpoint returns the token, it comes back as a JSON string — which means the raw response body looks like:
Note the surrounding double quotes. If you’re not parsing the JSON properly, you end up with a token that includes literal quote characters:
And your Authorization header becomes:
Which also returns 401.
Fix in Python:
| |
Fix in Ansible:
| |
Verify What You’re Actually Sending
Add a debug step to confirm the header value before the API call:
| |
If the output starts with a"character, you have the quoting problem. It should start witheyJ(the beginning of a JWT) or a similar alphanumeric string.
Check Permissions Too
If the header format is correct and you’re still getting 401, check that the account has theAudit UsersorList Accountsprivilege on the PVWA. Specifically, the service account needs:
- In CyberArk v12+: Added to theVault Adminsor given theCyberArk REST APIpermission
- In older versions: Member of a group withRetrieve filesandList filesin the safe containing the accounts you’re querying
A 401 from the Accounts endpoint is almost always one of two things: wrong header format, or insufficient permissions. Check the format first — it’s the more common cause and takes 30 seconds to fix.
Summary
| Problem | Symptom | Fix |
|---|---|---|
Bearerprefix | 401 on all API calls | RemoveBearer, send token directly |
| Quoted token string | 401, token starts with" | Use.json()to parse, not.textor.content |
| Insufficient permissions | 401 despite correct token | Grant API access in CyberArk RBAC |