Best Of
Re: OCP Developer Workbench - API testing app
v 0.9.3: Debug instances!!
You can now debug running instances!! All you need it the running instance id (as long as it is not ended) and we will get the variables, current and past activities and model version and start a debugging session. If the running instance model is not the latest version, you will get a notification so that you don't overwrite the latest version. Finally, the debug session will not interact with the running instance, it will run the calls in separate instances.
Re: OTDS OAuth2 Token Exchange — "User cannot be impersonated in resource Content Server" error despite
Resolved — Full Working Solution (Content Server 23.1 + OTDS 23.1.8)
After extensive testing I was able to get OTDS-based user impersonation working with Content Server 23.1. Here is the complete solution for anyone else hitting this issue.
The Core Problem
The OAuth2 token exchange grant type (urn:ietf:params:oauth:grant-type:token-exchange) is not the right approach for impersonation in this context, even though OTDS partially supports it. Instead, you need to use the OTDS legacy REST authentication endpoints directly with an OTDS SSO ticket.
Two important clues that point to this:
- The
token-exchangegrant type does not appear in the OTDS OIDC discovery endpoint'sgrant_types_supportedlist at/otdsws/.well-known/openid-configuration - The KB article KB0717615 (legacy KB8295770) explicitly states that for OTDS-synced users you must use
/authentication/ticketforuseror/authentication/resource/ticketforuser
The Working Flow — 3 Steps
Step 1 — Get an OTDS SSO Ticket for the Service Account
Use the /authentication/credentials endpoint — NOT the OAuth2 /oauth2/token endpoint. This returns a legacy *OTDSSSO* or *VER2* format ticket rather than a JWT.
POST /otdsws/rest/authentication/credentialsContent-Type: application/json{ "userName": "YOUR-SERVICE-ACCOUNT@OAuthClients", "password": "YOUR-CLIENT-SECRET"}
PowerShell:
$auth = Invoke-RestMethod -Method Post ` -Uri "https://YOUR-OTDS/otdsws/rest/authentication/credentials" ` -ContentType "application/json" ` -Body '{"userName":"YOUR-SERVICE-ACCOUNT@OAuthClients","password":"YOUR-SECRET"}'
The response includes a ticket field starting with *OTDSSSO* or *VER2*. This ticket can be reused to generate multiple impersonated tickets until it expires (1 hour).
Step 2 — Get an Impersonated Ticket for a Specific User
POST /otdsws/rest/authentication/ticketforuserContent-Type: application/json{ "ticket": "TICKET-FROM-STEP-1", "targetResourceId": "YOUR-CS-RESOURCE-ID", "userName": "USERNAME@PARTITION-NAME"}
PowerShell:
$impersonated = Invoke-RestMethod -Method Post ` -Uri "https://YOUR-OTDS/otdsws/rest/authentication/ticketforuser" ` -ContentType "application/json" ` -Body (ConvertTo-Json @{ ticket=$auth.ticket targetResourceId="YOUR-CS-RESOURCE-ID" userName="USERNAME@PARTITION-NAME" })
Note: The userName must include the OTDS partition name appended with @. For example: myuser@Non-Sync Users - DEV. The exact spelling and case must match what appears in the OTDS admin console under Users & Groups. To get your Content Server Resource ID (no auth required): https://YOUR-CS/otcs/cs.exe?func=otdsintegration.getresourceid
Step 3 — Call Content Server with the Impersonated Ticket
Use a GET request with the ticket as an OTDSTicket header — not in the POST body.
GET /otcs/cs.exe/api/v1/nodes/2000OTDSTicket: IMPERSONATED-TICKET-FROM-STEP-2
PowerShell:
Invoke-RestMethod -Method Get ` -Uri "https://YOUR-CS/otcs/cs.exe/api/v1/nodes/2000" ` -Headers @{OTDSTicket=$impersonated.ticket}
Important: OTDS tickets are single-use. You must request a fresh impersonated ticket for each Content Server session. The Step 1 ticket can be reused until it expires to generate multiple impersonated tickets.
Required OTDS Configuration
Setting | Value | Where to configure |
|---|---|---|
OAuth client — Allow Impersonation | Enabled | OAuth Clients → your client |
OAuth client — Confidential | Enabled | OAuth Clients → your client |
Service account in otdsadmins group | Required — see note below | Users & Groups → otdsadmins@otds.admin → Add Member |
Access Role — User Partition | Add partition containing users to impersonate | Access Roles → Access to Content Server → User Partitions tab |
Access Role — Resources | Add Content Server resource | Access Roles → Access to Content Server → Resources tab |
CS Resource Impersonation | "Allow this resource to impersonate users" checked | Resources → Content Server → Actions → Impersonation Settings |
Critical — otdsadmins membership is required: The service account must be a member of the otdsadmins@otds.admin group. Without this you get error 1012: "Impersonator must be a resource or an OTDS administrator". The ticketforuser endpoint enforces this check — there is no way around it for OAuth client accounts. Adding the OAuth client to otdsadmins is the correct and necessary configuration.
Note: we tested whether creating a separate OTDS resource for the service account would work as an alternative to otdsadmins membership — it does not, because the authentication is still performed as the OAuth client identity, not as the resource. The otdsadmins membership is required.
Error Reference
Error | Cause | Fix |
|---|---|---|
1009 Invalid parameter | Username format wrong or OAuth client partition mismatch | Use |
1012 Impersonator must be a resource or OTDS administrator | Service account not in otdsadmins group | Add service account to otdsadmins@otds.admin group |
invalid_scope: User cannot be impersonated in resource | Resource impersonation not enabled, or using wrong grant type | Enable "Allow this resource to impersonate users"; switch to credentials endpoint approach described above |
1015 Replay detected | OTDS ticket reused — tickets are single use | Request a fresh impersonated ticket for each session |
Authentication Required (Bearer token) | Passing JWT to CS instead of OTDS SSO ticket | Use credentials endpoint (Step 1) to get SSO ticket, not OAuth2 token endpoint |
username/password required on CS auth | Passing ticket in POST body instead of header | Use GET request with OTDSTicket as header |
Reference
OpenText KB article KB0717615 (legacy ID KB8295770) — "Content Server - SDK - How to use Impersonate User using REST API to create an item as a specific user" — confirms that for OTDS-synced users, the OTDS /authentication/ticketforuser endpoint is the correct approach.
Re: Exstream CE 25.3 - PDF/UA - not passing PAC test
Sure will check this and get back to you
Re: Exstream CE 25.3 - PDF/UA - not passing PAC test
I can share on a ticket may be but not here publicly. :(
Re: Exstream CE 25.3 - PDF/UA - not passing PAC test
Hi Prince,
I will check on this and get back to you
Re: Logs files on servers
Hi.
- Yes, these files are stored with the extension *.tmp but are actually printfiles that hasn't been able to reach its destination. so if you don't need to send them to 'wanted destination' you can delete them… actually the whole folder can be deleted.
- if you don't use these *trc-files for anything, there is no problem deleting them. the Exstream-service doesn't 'lock' them.
//Stig ;-)
Re: Logs files on servers
Hi there,
The undeliverable files are most likely spool files that could not reach their destination. They could be pointing to old printer servers or old printers.
They could also be other output files that could not reach their network destination.
You should be aware of why these files are being created as someone may be missing them :-)
When it comes to the *trc files you should troubleshoot them separately as they are custom files unique to your project.
You will see in the log files any “undeliverable” entries and possibly the reason why.
You may want to add a housekeeping task that removes anything like this that is more than X days old.
Good luck!
Vyv
Re: Exstream CE 25.3 - PDF/UA - not passing PAC test
Hi Madhukar,
uhhh, you might have made my day. I'll curiously wait for that. Thank you so much for this info!
Re: Exstream CE 25.3 - PDF/UA - not passing PAC test
Hi Tobi,
The changes are not available in the latest hotfix. We are planning to release a new hotfix in a few weeks. I will update here once it is released. You can test it then.

