CSRF & auth
If you’ve worked with SAP OData before, CSRF is the #1 source of confusion. This page walks through DataMaker’s behaviour and the most common failure modes.
How DataMaker handles CSRF (the happy path)
For SAP OData V2 and V4, modifying requests need a CSRF token. The flow:
1. GET /service/ → 200 OK X-CSRF-Token: Fetch X-CSRF-Token: <token-A> sap-cookie: <session> sap-cookie: <session>
2. POST /service/Entity → 201 Created X-CSRF-Token: <token-A> (token-A is consumed but stays valid sap-cookie: <session> for the same session)
3. POST /service/Entity → 201 Created (re-uses token-A)
4. Session expires... POST /service/Entity → 403 CSRF validation failed
5. DataMaker auto-fetches new token, retries: GET /service/ → X-CSRF-Token: <token-B> POST /service/Entity → 201 CreatedDataMaker handles steps 1 and 5 transparently. You never set X-CSRF-Token yourself.
Failure: 403 CSRF token validation failed (persistent)
If retries don’t help, the token isn’t being recognised. Causes:
-
Auth backend changes the session per request. Some OAuth2 flows mint a fresh token per call; the CSRF token from request N is valid for session N, not N+1. Switch to
BasicAuthor a long-lived bearer. -
Cookie jar reset. If the connection is going through a proxy that strips cookies, the SAP backend treats every request as a new session. Configure the proxy to forward
sap-*cookies. -
Wrong endpoint for fetch. Some custom services don’t return a token from the service root. Override the fetch endpoint:
{"auth": { "type": "basic", ... },"csrf": { "fetch_path": "/some/other/path", "fetch_method": "HEAD" }}
Failure: 401 on GET $metadata but 200 on regular GET
Your auth works for data but not for metadata. Some SAP gateways apply different
rules to $metadata (especially in SAP Cloud Connector setups). Two fixes:
- Configure the gateway to allow
$metadatafor the same auth. - Provide a manually-uploaded metadata document via Connection → Metadata → Upload.
DataMaker uses the uploaded
$metadataand doesn’t fetch it at runtime.
OAuth2 client credentials: invalid_client
The token endpoint rejected your client_id / client_secret. Walk the chain:
- Curl the token endpoint with the same credentials and verify you get a token back.
- Check
Content-Type: application/x-www-form-urlencoded(notapplication/json). Some IdPs are picky. - For Azure AD, the
scopeparameter is required and most often is<resource>/.default.
OAuth2 token expired mid-scenario
DataMaker caches tokens until 60 seconds before their stated expires_in. If your
scenario runs longer than that, tokens are refreshed transparently.
If you’re seeing 401 on a long run, the IdP’s expires_in is likely lying. Some
servers say “3600s” but rotate at ~30 minutes. Wrap the push in a retry so each attempt
re-fetches a fresh token:
def with_reauth(call, attempts=3): for i in range(attempts): try: return call() except Exception: if i == attempts - 1: raise # the next attempt triggers a fresh token fetchBearer / API key shows up in logs
DataMaker doesn’t print your auth headers, but if you print() a request or response that
contains a token, it lands in the run log. Don’t print secrets: log a status code or a
redacted summary instead.
Two-factor / interactive auth
DataMaker doesn’t run interactive auth flows (no browser, no TOTP prompts). If your target system requires interactive auth, you have two options:
- Use the platform’s machine-to-machine auth (service accounts, client credentials).
- Manually obtain a long-lived token outside DataMaker and store it as a workspace secret. Refresh it on a schedule.
See also
- Connections → SAP OData for the connection setup.
- Scenarios → Logs & retries for retry patterns.