This note explains how the Assistant authenticates against Autodesk Application Services on behalf of a signed-in user. It focuses on the three-legged OAuth flow we use today, how the resulting credentials are protected, and how they are injected into our APS API calls.
https://developer.api.autodesk.com, requesting the scopes viewables:read, data:read, data:create, data:search.http://localhost:8080) captures Autodesk’s redirect back to the Assistant.If Autodesk reports an error (for example, the user closes the browser window without completing consent), we bubble the error up so the UI can inform the user and they can retry.
Assistant uses the 3-Legged Authorization Code Flow with PKCE because it is the industry-recommended, secure, and user-friendly approach for native (installed) applications that access Autodesk Platform Services on behalf of a user. The PKCE for Public Clients flow does not require or use a client secret, making it ideal for desktop and mobile applications where securely storing secrets is not possible.
More details and Autodesk’s PKCE walkthrough: https://aps.autodesk.com/en/docs/oauth/v2/tutorials/get-3-legged-token-pkce/get-3-legged-token-pkce/
The 3-Legged OAuth with PKCE flow ensures that our Assistant only operates on behalf of the authenticated user and within the exact permissions that user has in Autodesk Platform Services.
When a user signs in and authorizes Assistant, Autodesk’s authorization server issues an access token that reflects the user’s own permissions and project memberships. This means:
No elevated access: Assistant cannot access any data, projects, or folders the user themselves cannot access.
Granular, project-level control: Access is automatically limited to the projects, hubs, and folders the user has been granted access to in Autodesk.
User-driven authorization: The user explicitly consents to the requested scopes during sign-in.
No shared or system-wide permissions: The application does not use a service account or client secret; it relies solely on the user’s own authenticated session.
In short, Assistant acts strictly within the boundaries of the user’s permissions, it never has broader access than the user who is signed in.
%LocalAppData%\Tokens, one encrypted file per token type.Authorization: Bearer <access_token> into every request and retries once if Autodesk returns 401 Unauthorized./project/v1/hubs). If Autodesk responds with 401 Unauthorized, we mark the token as invalid and prompt the user to sign in again.The OAuth redirect requires a free local port (8080). If that port is blocked the user will see a sign-in failure; in practice we have not seen conflicts, but the port can be adjusted if needed.
Autodesk credentials never leave the user's machine: we do not proxy the callback, nor do we send the tokens to our backend services.
Because DPAPI is tied to the Windows profile, tokens do not roam between machines and are invalid once the Windows user logs out.
The scopes we request are the minimum Autodesk recommends for reading and writing BIM 360/ACC data that our assisted workflows require. Any additional scope would need explicit review.
We initiate the OAuth process against https://developer.api.autodesk.com, requesting the scopes viewables:read, data:read, data:create, data:search.
Note: We intentionally do NOT request
account:read,account:write,user:read,code:all,data:write, or any admin / bucket management scopes. This keeps the integration strictly within the signed-in user's existing project-level permissions.
| Scope | Why We Request It |
|---|---|
viewables:read |
Retrieve Model Derivative manifests & thumbnails for previewing models. |
data:read |
Read hubs, projects, folders, items, versions, and publish status the user already has access to. |
data:create |
Create storage objects, folders, items, versions, and trigger publish commands (minimum scope Autodesk lists for these POST endpoints). |
data:search |
Execute scoped folder/project searches to help users filter large directories. |
This scope set reflects least-privilege for the currently implemented endpoints; we review periodically to ensure no unnecessary scope creep.
GET /project/v1/hubsGET /project/v1/hubs/{hubId}/projectsGET /project/v1/hubs/{hubId}/projects/{projectId}/topFoldersGET /data/v1/projects/{projectId}/folders/{folderId}/contentsGET /data/v1/projects/{projectId}/items/{itemId}GET /data/v1/projects/{projectId}/items/{itemId}/versionsPOST /data/v1/projects/{projectId}/storagePOST /data/v1/projects/{projectId}/itemsPOST /data/v1/projects/{projectId}/versionsPOST /data/v1/projects/{projectId}/commandsPOST /data/v1/projects/{projectId}/foldersGET /data/v1/projects/{projectId}/versions/{versionId}GET /data/v1/projects/{projectId}/folders/{folderId}/searchPUT /oss/v2/buckets/{bucketKey}/objects/{objectName}GET Buckets/Download/{bucketKey}/{objectName}GET /modelderivative/v2/regions/{region}/designdata/{urn}/manifestGET /modelderivative/v2/regions/{region}/designdata/{urn}/thumbnail