Skip to content

Commit 3e9d2cd

Browse files
committed
feat: add auth network options
1 parent 55de34c commit 3e9d2cd

14 files changed

Lines changed: 2536 additions & 1974 deletions

docs/FAQ.md

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,218 @@ packages = ["your_package"]
7272

7373
For more detailed information about package discovery and configuration, refer to the [official setuptools documentation](https://setuptools.pypa.io/en/latest/userguide/package_discovery.html).
7474

75+
### Q: Why am I getting timeouts or "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed" errors?
76+
77+
The UiPath CLI automatically works with your corporate network setup, including proxy servers and security tools like ZScaler, by leveraging your system's native SSL certificate store.
78+
79+
#### Proxy Configuration
80+
81+
Configure these environment variables to route CLI traffic through your corporate proxy:
82+
83+
//// tab | Linux/macOS Bash
84+
85+
<!-- termynal -->
86+
```bash
87+
> export HTTP_PROXY=http://proxy.company.com:8080
88+
> export HTTPS_PROXY=https://proxy.company.com:8080
89+
> export NO_PROXY=localhost,127.0.0.1
90+
> uipath auth
91+
⠋ Authenticating with UiPath ...
92+
✓ Authentication successful.
93+
```
94+
95+
////
96+
97+
//// tab | Windows PowerShell
98+
99+
<!-- termynal -->
100+
```powershell
101+
> $env:HTTP_PROXY="http://proxy.company.com:8080"
102+
> $env:HTTPS_PROXY="https://proxy.company.com:8080"
103+
> $env:NO_PROXY="localhost,127.0.0.1"
104+
> uipath auth
105+
⠋ Authenticating with UiPath ...
106+
✓ Authentication successful.
107+
```
108+
109+
////
110+
111+
//// tab | Windows CMD
112+
113+
<!-- termynal -->
114+
```cmd
115+
> set HTTP_PROXY=http://proxy.company.com:8080
116+
> set HTTPS_PROXY=https://proxy.company.com:8080
117+
> set NO_PROXY=localhost,127.0.0.1
118+
> uipath auth
119+
⠋ Authenticating with UiPath ...
120+
✓ Authentication successful.
121+
```
122+
123+
////
124+
125+
#### Proxy Authentication
126+
127+
//// tab | Linux/macOS Bash
128+
129+
<!-- termynal -->
130+
```bash
131+
> export HTTP_PROXY=http://username:password@proxy.company.com:8080
132+
> export HTTPS_PROXY=https://username:password@proxy.company.com:8080
133+
> export NO_PROXY=localhost,127.0.0.1
134+
> uipath publish
135+
⠋ Fetching available package feeds...
136+
✓ Package published successfully!
137+
```
138+
139+
////
140+
141+
//// tab | Windows PowerShell
142+
143+
<!-- termynal -->
144+
```powershell
145+
> $env:HTTP_PROXY="http://username:password@proxy.company.com:8080"
146+
> $env:HTTPS_PROXY="https://username:password@proxy.company.com:8080"
147+
> $env:NO_PROXY="localhost,127.0.0.1"
148+
> uipath publish
149+
⠋ Fetching available package feeds...
150+
✓ Package published successfully!
151+
```
152+
153+
////
154+
155+
//// tab | Windows CMD
156+
157+
<!-- termynal -->
158+
```cmd
159+
> set HTTP_PROXY=http://username:password@proxy.company.com:8080
160+
> set HTTPS_PROXY=https://username:password@proxy.company.com:8080
161+
> set NO_PROXY=localhost,127.0.0.1
162+
> uipath publish
163+
⠋ Fetching available package feeds...
164+
✓ Package published successfully!
165+
```
166+
167+
////
168+
169+
/// tip
170+
**For IT Administrators**: Add these environment variables to your Group Policy or system configuration:
171+
172+
```bash
173+
HTTP_PROXY=http://your-proxy.company.com:8080
174+
HTTPS_PROXY=https://your-proxy.company.com:8080
175+
NO_PROXY=localhost,127.0.0.1,*.company.com
176+
```
177+
///
178+
179+
/// warning
180+
The CLI uses a local HTTP server for the authentication callback. You must **exclude localhost** from your proxy using `NO_PROXY=localhost,127.0.0.1` or authentication will fail.
181+
///
182+
183+
##### Troubleshooting
184+
<!-- termynal -->
185+
```bash
186+
> # Test proxy connectivity
187+
> curl -v --proxy $HTTP_PROXY https://cloud.uipath.com
188+
* Trying 192.168.1.100:8080...
189+
* Connected to proxy.company.com (192.168.1.100) port 8080
190+
✓ Connection successful
191+
192+
> # Test localhost exclusion
193+
> curl --proxy $HTTP_PROXY http://localhost:8080
194+
* Bypassing proxy for localhost
195+
✓ Direct connection to localhost successful
196+
```
197+
198+
#### SSL Certificates
199+
200+
The UiPath CLI automatically uses your system's certificate store (Windows Certificate Store, macOS Keychain, Linux ca-certificates). Corporate certificates installed via Group Policy or IT tools will be automatically recognized.
201+
202+
##### Troubleshooting SSL Issues
203+
204+
If you encounter SSL certificate errors:
205+
206+
1. **Disable SSL verification** (for testing only):
207+
208+
//// tab | Linux/macOS Bash
209+
210+
<!-- termynal -->
211+
```bash
212+
> export UIPATH_DISABLE_SSL_VERIFY=true
213+
> uipath auth
214+
⠋ Authenticating with UiPath ...
215+
✓ Authentication successful.
216+
```
217+
218+
////
219+
220+
//// tab | Windows PowerShell
221+
222+
<!-- termynal -->
223+
```powershell
224+
> $env:UIPATH_DISABLE_SSL_VERIFY="true"
225+
> uipath auth
226+
⠋ Authenticating with UiPath ...
227+
✓ Authentication successful.
228+
```
229+
230+
////
231+
232+
//// tab | Windows CMD
233+
234+
<!-- termynal -->
235+
```cmd
236+
> set UIPATH_DISABLE_SSL_VERIFY=true
237+
> uipath auth
238+
⠋ Authenticating with UiPath ...
239+
✓ Authentication successful.
240+
```
241+
242+
////
243+
244+
2. **Use custom certificate bundle** (if needed):
245+
246+
//// tab | Linux/macOS Bash
247+
248+
<!-- termynal -->
249+
```bash
250+
> export SSL_CERT_FILE=/path/to/company-ca-bundle.pem
251+
> export REQUESTS_CA_BUNDLE=/path/to/company-ca-bundle.pem
252+
> uipath publish
253+
⠋ Publishing most recent package...
254+
✓ Package published successfully!
255+
```
256+
257+
////
258+
259+
//// tab | Windows PowerShell
260+
261+
<!-- termynal -->
262+
```powershell
263+
> $env:SSL_CERT_FILE="C:\certs\company-ca-bundle.pem"
264+
> $env:REQUESTS_CA_BUNDLE="C:\certs\company-ca-bundle.pem"
265+
> uipath publish
266+
⠋ Publishing most recent package...
267+
✓ Package published successfully!
268+
```
269+
270+
////
271+
272+
//// tab | Windows CMD
273+
274+
<!-- termynal -->
275+
```cmd
276+
> set SSL_CERT_FILE=C:\certs\company-ca-bundle.pem
277+
> set REQUESTS_CA_BUNDLE=C:\certs\company-ca-bundle.pem
278+
> uipath publish
279+
⠋ Publishing most recent package...
280+
✓ Package published successfully!
281+
```
282+
283+
////
284+
285+
75286
---
76287

77288
*Note: This FAQ will be updated as new information becomes available. If you continue experiencing issues after following these solutions, please contact UiPath support.*
289+

pyproject.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath"
3-
version = "2.0.73"
3+
version = "2.0.74"
44
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.10"
@@ -15,6 +15,7 @@ dependencies = [
1515
"pathlib>=1.0.1",
1616
"rich>=13.0.0",
1717
"azure-monitor-opentelemetry>=1.6.8",
18+
"truststore>=0.10.1"
1819
]
1920
classifiers = [
2021
"Development Status :: 3 - Alpha",
@@ -48,6 +49,9 @@ dev = [
4849
"ruff>=0.9.4",
4950
"rust-just>=1.39.0",
5051
"pytest>=7.4.0",
52+
"pytest-asyncio>=1.0.0",
53+
"pytest-httpx>=0.35.0",
54+
"pytest-trio>=0.8.0",
5155
"pytest-cov>=4.1.0",
5256
"pytest-mock>=3.11.1",
5357
"pre-commit>=4.1.0",
@@ -61,8 +65,6 @@ dev = [
6165
"mkdocs-open-in-new-tab>=1.0.8",
6266
"toml>=0.10.2",
6367
"inflection>=0.5.1",
64-
"pytest-httpx>=0.35.0",
65-
"pytest-trio>=0.8.0",
6668
"types-toml>=0.10.8",
6769
]
6870

src/uipath/_cli/_auth/_client_credentials.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import httpx
55

6+
from ..._utils._ssl_context import get_httpx_client_kwargs
67
from .._utils._console import ConsoleLogger
78
from ._models import TokenData
89
from ._utils import parse_access_token, update_env_file
@@ -91,13 +92,11 @@ def authenticate(
9192
}
9293

9394
try:
94-
with httpx.Client(timeout=30.0) as client:
95+
with httpx.Client(**get_httpx_client_kwargs()) as client:
9596
response = client.post(token_url, data=data)
96-
9797
match response.status_code:
9898
case 200:
9999
token_data = response.json()
100-
# Convert to our TokenData format
101100
return {
102101
"access_token": token_data["access_token"],
103102
"token_type": token_data.get("token_type", "Bearer"),

src/uipath/_cli/_auth/_portal_service.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import click
66
import httpx
77

8+
from ..._utils._ssl_context import get_httpx_client_kwargs
89
from .._utils._console import ConsoleLogger
910
from ._models import TenantsAndOrganizationInfoResponse, TokenData
1011
from ._oidc_utils import get_auth_config
@@ -16,7 +17,6 @@
1617
)
1718

1819
console = ConsoleLogger()
19-
client = httpx.Client(follow_redirects=True, timeout=30.0)
2020

2121

2222
class PortalService:
@@ -27,6 +27,8 @@ class PortalService:
2727
domain: Optional[str] = None
2828
selected_tenant: Optional[str] = None
2929

30+
_client: Optional[httpx.Client] = None
31+
3032
_tenants_and_organizations: Optional[TenantsAndOrganizationInfoResponse] = None
3133

3234
def __init__(
@@ -39,13 +41,32 @@ def __init__(
3941
self.access_token = access_token
4042
self.prt_id = prt_id
4143

44+
self._client = httpx.Client(**get_httpx_client_kwargs())
45+
46+
def close(self):
47+
"""Explicitly close the HTTP client."""
48+
if self._client:
49+
self._client.close()
50+
self._client = None
51+
52+
def __enter__(self):
53+
"""Enter the runtime context related to this object."""
54+
return self
55+
56+
def __exit__(self, exc_type, exc_value, traceback):
57+
"""Exit the runtime context and close the HTTP client."""
58+
self.close()
59+
4260
def update_token_data(self, token_data: TokenData):
4361
self.access_token = token_data["access_token"]
4462
self.prt_id = get_parsed_token_data(token_data).get("prt_id")
4563

4664
def get_tenants_and_organizations(self) -> TenantsAndOrganizationInfoResponse:
65+
if self._client is None:
66+
raise RuntimeError("HTTP client is not initialized")
67+
4768
url = f"https://{self.domain}.uipath.com/{self.prt_id}/portal_/api/filtering/leftnav/tenantsAndOrganizationInfo"
48-
response = client.get(
69+
response = self._client.get(
4970
url, headers={"Authorization": f"Bearer {self.access_token}"}
5071
)
5172
if response.status_code < 400:
@@ -72,6 +93,9 @@ def get_uipath_orchestrator_url(self) -> str:
7293
return f"https://{self.domain}.uipath.com/{account_name}/{self.selected_tenant}/orchestrator_"
7394

7495
def post_refresh_token_request(self, refresh_token: str) -> TokenData:
96+
if self._client is None:
97+
raise RuntimeError("HTTP client is not initialized")
98+
7599
url = f"https://{self.domain}.uipath.com/identity_/connect/token"
76100
client_id = get_auth_config().get("client_id")
77101

@@ -83,7 +107,7 @@ def post_refresh_token_request(self, refresh_token: str) -> TokenData:
83107

84108
headers = {"Content-Type": "application/x-www-form-urlencoded"}
85109

86-
response = client.post(url, data=data, headers=headers)
110+
response = self._client.post(url, data=data, headers=headers)
87111
if response.status_code < 400:
88112
return response.json()
89113
elif response.status_code == 401:
@@ -137,6 +161,9 @@ def ensure_valid_token(self):
137161
update_env_file(updated_env_contents)
138162

139163
def post_auth(self, base_url: str) -> None:
164+
if self._client is None:
165+
raise RuntimeError("HTTP client is not initialized")
166+
140167
or_base_url = (
141168
f"{base_url}/orchestrator_"
142169
if base_url
@@ -148,7 +175,7 @@ def post_auth(self, base_url: str) -> None:
148175

149176
try:
150177
[try_enable_first_run_response, acquire_license_response] = [
151-
client.post(
178+
self._client.post(
152179
url,
153180
headers={"Authorization": f"Bearer {self.access_token}"},
154181
)

0 commit comments

Comments
 (0)