Vuforia Chalk integration with Windchill shows permission denied errors for part viewing

Hi all,

We’re running Windchill 11.2 M030 and trying to integrate Vuforia Chalk so our field technicians can view part structures and associated documents via the AR session. The Chalk app is authenticating successfully against our Windchill SSO (SAML2), but once a session is established and a technician attempts to navigate to a specific part in the product structure, we get a 403 permission denied error in the Chalk overlay.

The error returned from the Windchill REST API call is:

HTTP 403 Forbidden
{
  "errorCode": "AUTHZ_FAILURE",
  "message": "User does not have READ access to WTPart (ufid: OR:wt.part.WTPart:12345@org.acme.windchill)"
}

The users in question have the ‘Viewer’ role in the relevant product context and can access the same parts without issue through the standard Windchill web UI and even through the Windchill Mobile app. The problem seems isolated to the Chalk integration path specifically.

We’ve configured the VuforiaChalkConnector.properties file as documented, pointing to our Windchill server and providing the OAuth2 client credentials. The service account we’re using for the connector has ‘Site Administrator’ access.

Has anyone seen this pattern before where Chalk passes through the end-user identity but the authorization check fails even though the user has appropriate product-level access? Could there be an OAG policy or dynamic role rule interfering here? We’re not sure whether this is a Windchill policy issue or something specific to how Chalk proxies user credentials.

Any pointers would be appreciated.

This is a well-known pain point in Vuforia Chalk + Windchill OAuth2 setups. Let me lay out the complete root cause and resolution steps based on what we worked through on a similar engagement.

Root Cause: By default, the Vuforia Chalk connector authenticates to Windchill using its own client credentials (client_credentials OAuth2 grant). When it then queries Windchill REST endpoints for part data, the effective principal in Windchill’s access evaluation is the connector service account — not the end technician. Even if the service account is a Site Admin, Windchill’s OAG policies evaluate against the resolved WTUser mapped from the token subject. If no proper delegation chain is established, the fallback behavior in 11.2 M030 is to return 403 rather than silently elevate.

Solution — Enable OAuth2 Token Exchange (RFC 8693):

  1. PingFederate side: Create or update the OAuth2 client registration for your Chalk connector to include the urn:ietf:params:oauth:grant-type:token-exchange grant type. Configure the actor_token_type as urn:ietf:params:oauth:token-type:jwt and map the subject_token claim to the end-user’s identity from your SAML assertion. The issued delegated token should include the technician’s uid as the sub claim.

  2. Windchill wt.properties changes (restart Method Server after editing):

wt.federation.oauth2.tokenexchange.enabled=true
wt.federation.oauth2.trustedClientIds=chalk-connector-client-id
wt.federation.oauth2.subjectClaimAttribute=uid

The subjectClaimAttribute must match the LDAP attribute Windchill uses to resolve WTUser participants — in most deployments this is uid but verify against your LDAP directory configuration in ldap.properties.

  1. Chalk Connector configuration (VuforiaChalkConnector.properties):
windchill.oauth2.grantType=token_exchange
windchill.oauth2.actorTokenEndpoint=https://<pingfed-host>/as/token.oauth2
windchill.oauth2.clientId=chalk-connector-client-id
windchill.oauth2.clientSecret=<secret>
windchill.oauth2.scope=windchill.read windchill.partstructure

Ensure the windchill.partstructure scope is defined in your PingFederate scope management and mapped appropriately.

  1. Windchill Access Policy Review: After enabling token exchange, retest. If 403 persists, run a quick access policy audit. Navigate to Site > Utilities > Access Control Management and use the ‘Evaluate Access’ tool specifying the affected user and the WTPart ufid. This will show you exactly which policy rule is denying access and at which level (product, library, or domain).

  2. OAG Dynamic Role Check: If you have custom OAG policies on WTPart lifecycle states, make sure that the ‘In Work’ or ‘Released’ state ACLs include the ‘Viewer’ dynamic role with at least READ permission. In 11.2 M030, a regression was introduced where externally-authenticated principals can miss dynamic role assignment if the WTOrganization of the user doesn’t match the container organization. Check MethodServer.log for DynamicRoleEvaluationException entries.

Verification: After applying changes, enable debug logging temporarily:

WTLogger.setLevel(wt.access.AccessController, DEBUG)

This will print the full access evaluation chain to MethodServer.log and confirm the correct WTUser principal is being resolved from the delegated token.

This resolved the identical 403 pattern for us across Windchill 11.2 M030 with PingFederate 11.x. Hope it helps.


This draft is based on general Windchill knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.

We hit something similar when first rolling out Vuforia integration. One thing to check: when Chalk makes REST calls on behalf of the user, it may be passing the OAuth2 token from the connector service account rather than delegating the actual end-user identity. In that case the authorization check runs against the service account, not the technician. Check your Chalk connector logs for which identity is being presented in the Authorization header when the 403 fires.

Also worth verifying whether you have any OAG (Object Authorization Gateway) policies scoped to the ‘WTPart’ type that might be restricting access based on lifecycle state or organization. In 11.2 M030 there were some changes to how dynamic role evaluation works with external OAuth2 clients — if the incoming principal doesn’t resolve cleanly to a Windchill participant, the evaluation can fall back to a deny. Check the MethodServer.log around the timestamp of the 403 for lines referencing AccessController or WTAccessControlHelper.

Tested this on Windchill 12.1 with Vuforia Chalk 9.x — switching from client_credentials to on-behalf-of OAuth2 flow immediately resolved the OAG permission denied errors for part viewing.

Thanks both. @plm_infra_rdunmore — I checked the Chalk connector logs and it does look like the token being presented is the connector service account token, not the individual user’s delegated identity. But I’m not clear on how to configure Chalk to pass through on-behalf-of (OBO) tokens to Windchill. Our IdP is PingFederate. Is there a specific Windchill OAuth2 profile that needs to be enabled to support token delegation from Chalk? I haven’t found clear guidance in the PTC documentation on this specific flow.

For the OBO flow to work you need to configure a Token Exchange grant type in your PingFederate OAuth2 client registration for the Chalk connector, and Windchill needs to have the wt.federation.oauth2.tokenexchange.enabled property set to true in wt.properties. Additionally, check that the Chalk client ID is listed in wt.federation.oauth2.trustedClientIds. Without that whitelist entry, Windchill will reject the delegated token even if the IdP issues it correctly. Also make sure the scope requested includes windchill.read.