Skip to content

feat(core): acquire license once per app sign-in [APPS-38002] - #799

Open
lucarachiteanu wants to merge 25 commits into
mainfrom
feat/session-scoped-license-acquire
Open

lucarachiteanu wants to merge 25 commits into
mainfrom
feat/session-scoped-license-acquire

Conversation

@lucarachiteanu

@lucarachiteanu lucarachiteanu commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

The Studio Web license is what provisions a user's personal robot, so it belongs to the user's login, not to one service. Today Functions.invoke acquires it on every call and fails when it can't — tying licensing to one project type and running it even when the SDK is used inside a coded function.

Licensing moves into core as part of the sign-in sequence, for interactive users only: the SDK acquires when it holds no credential of its own — a coded app signing its user in, or one whose host (Action Center, an embedding frame) supplies the user's token. A PAT, client credentials, the environment contract or a coded function's robot token never provision anyone's robot. The claim is written to the session store before the request starts and kept until sign-out, so it runs at most once per user, tenant and session across SDK instances and reloads. Completing the OAuth sign-in waits for it to settle, so an app redirecting right after sign-in cannot cut it short; it never fails sign-in, a failure is logged and not retried, and the server answers for a missing robot.

invoke no longer touches licensing, and Functions.acquireLicense and the refreshLicense option are removed — the Functions service is @experimental, so this is within its contract. Session storage now goes through one SessionStore that never throws; OAuth sign-in still stops before the redirect when it cannot store its PKCE state, as it did when storage threw.

🤖 Generated with Claude Code

@lucarachiteanu lucarachiteanu changed the title feat(core): acquire the studio web license once per app sign-in feat(core): acquire the studio web license once per app sign-in [APPS-38002] Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

This PR changes the public API in a breaking way

Existing consumer code may stop compiling. If that is intended, it needs a release note and a major version bump — not a patch. If it is not, keep the old signature as a deprecated overload.

What changed
Public API changes versus origin/main:

  changed: 0   removed: 4   added: 0   stability-tag only: 0

REMOVED — consumers can no longer reference these
  FunctionInvokeOptions :: refreshLicense   [functions, root]
      was  ?:boolean
  FunctionServiceModel :: acquireLicense   [functions, root]
      was  (options?:FunctionAcquireLicenseOptions):Promise<StudioWebLicense>  @internal
  Functions :: acquireLicense   [functions]
      was  (options?:FunctionAcquireLicenseOptions):Promise<StudioWebLicense>
  Functions :: constructor   [functions]
      was  (instance:IUiPath)

A removal or a signature change needs a release note and the matching version
bump. Parameter renames and members moved onto a base type are not breaking.

::error::4 breaking change(s) to the public API. See the report above.

@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://UiPath.github.io/uipath-typescript/pr-preview/pr-799/

Built to branch gh-pages at 2026-10-07 11:45 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@claude

This comment has been minimized.

@lucarachiteanu
lucarachiteanu force-pushed the feat/session-scoped-license-acquire branch from 8d9c9f8 to 26c83c3 Compare October 2, 2026 13:50
@claude

This comment has been minimized.

@lucarachiteanu
lucarachiteanu force-pushed the feat/session-scoped-license-acquire branch 2 times, most recently from 0d15d6e to 282b5f3 Compare October 6, 2026 12:04
Comment thread src/core/licensing/session-license.ts Outdated
@claude

This comment has been minimized.

@claude

This comment has been minimized.

@claude

This comment has been minimized.

1 similar comment
@claude

This comment has been minimized.

@claude

This comment has been minimized.

Comment thread src/services/orchestrator/functions/functions.ts Outdated
@claude

This comment has been minimized.

@claude

This comment has been minimized.

1 similar comment
@claude

This comment has been minimized.

Comment thread src/core/licensing/session-license.ts Outdated
@claude

This comment has been minimized.

@claude

This comment has been minimized.

@claude

This comment has been minimized.

1 similar comment
@claude

This comment has been minimized.

@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
86.3% Coverage on New Code (required ≥ 90%)

See analysis details on SonarQube Cloud

@claude

This comment has been minimized.

@claude

This comment has been minimized.

@claude

This comment has been minimized.

1 similar comment
@claude

This comment has been minimized.

@lucarachiteanu
lucarachiteanu marked this pull request as ready for review October 7, 2026 09:48
@lucarachiteanu
lucarachiteanu requested a review from a team October 7, 2026 09:48
@claude

This comment has been minimized.

1 similar comment
@claude

This comment has been minimized.

…ed claim until sign-out

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@claude

This comment has been minimized.

@claude

This comment has been minimized.

1 similar comment
@claude

claude Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

@lucarachiteanu lucarachiteanu changed the title feat(core): acquire the studio web license once per app sign-in [APPS-38002] feat(core): acquire license once per app sign-in [APPS-38002] Oct 7, 2026
Comment thread src/core/uipath.ts
new ApiClient(internalConfig, executionContext, tokenManager),
SessionStore.open() ?? new MemoryStore(),
);
tokenManager.onTokenChange((tokenInfo) => license.onTokenChange(tokenInfo));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean on every coded app sign in we will make an acquire license call? (at least once)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we try to do it at most once ( exclusing a very basic retry policy, with a timeout that accounts for p99)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ties coded apps and SW (coded functions) always. I dont think we should do that. Can we somehow intelligently do it only when Functions is called?

@vnaren23 vnaren23 Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many apps which are just meant to appear as dashboard. In such apps acquiring a license is unnecessary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That depends on where the coded app fetches the information from. The AcquireLicense call does reuse a SW endpoint, but its not scoped to it. Moreover, the issue surfaced from calling a trigger that reuses the caller identity. But the path that makes the user run into this issue is much more broad, e.g: any SDK call that starts a job as the signed-in user can hit 1230

I can make the call fire once a function invoke is done, but it should still be tied to a signed in user instance.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants