fix: cyberark allow setting ssl verfiy to false (#17433)

This commit is contained in:
Ishaan Jaff
2025-12-03 18:54:31 -08:00
committed by GitHub
parent e29acb2f64
commit f035984dd7
2 changed files with 43 additions and 9 deletions
@@ -41,6 +41,7 @@ CYBERARK_CLIENT_KEY="path/to/client.key"
# OPTIONAL
CYBERARK_REFRESH_INTERVAL="300" # defaults to 300 seconds (5 minutes), frequency of token refresh
CYBERARK_SSL_VERIFY="true" # defaults to true, set to "false" to disable SSL verification (for self-signed certificates)
```
**Step 2.** Add to proxy config.yaml
@@ -172,6 +173,24 @@ If these commands work successfully against your CyberArk instance, then CyberAr
- The `CYBERARK_API_BASE` URL is accessible from your LiteLLM instance
- Your API key or certificates have the necessary permissions in CyberArk
### SSL Certificate Errors
If you encounter SSL certificate verification errors like:
```
RuntimeError: Could not authenticate to CyberArk Conjur: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain
```
This typically occurs when your CyberArk Conjur instance uses a self-signed certificate. You can disable SSL verification by setting:
```bash
CYBERARK_SSL_VERIFY="false"
```
:::warning
Disabling SSL verification is insecure and should only be used for testing or development environments with self-signed certificates. For production, configure your certificate chain properly or use certificate-based authentication with `CYBERARK_CLIENT_CERT` and `CYBERARK_CLIENT_KEY`.
:::
## Video Walkthrough
This video walks through using CyberArk Conjur as a secret manager with LiteLLM. We create a virtual key in the LiteLLM Admin UI and verify it exists in CyberArk. Then we rotate the secret key and verify it exists in CyberArk.
@@ -16,6 +16,7 @@ from litellm.llms.custom_httpx.http_handler import (
from litellm.proxy._types import KeyManagementSystem
from .base_secret_manager import BaseSecretManager
from .main import str_to_bool
class CyberArkSecretManager(BaseSecretManager):
@@ -32,6 +33,11 @@ class CyberArkSecretManager(BaseSecretManager):
self.tls_cert_path = os.getenv("CYBERARK_CLIENT_CERT", "")
self.tls_key_path = os.getenv("CYBERARK_CLIENT_KEY", "")
# SSL verification - can be disabled for self-signed certificates
# Set CYBERARK_SSL_VERIFY=false to disable SSL verification
ssl_verify_env = str_to_bool(os.getenv("CYBERARK_SSL_VERIFY"))
self.ssl_verify: bool = ssl_verify_env if ssl_verify_env is not None else True
# Validate environment
if not self.conjur_api_key and not (
self.tls_cert_path and self.tls_key_path
@@ -52,6 +58,11 @@ class CyberArkSecretManager(BaseSecretManager):
f"CyberArk secret manager is only available for premium users. {CommonProxyErrors.not_premium_user.value}"
)
if not self.ssl_verify:
verbose_logger.warning(
"CyberArk SSL verification is disabled. This is insecure and should only be used for testing with self-signed certificates."
)
def _authenticate(self) -> str:
"""
Authenticate with CyberArk Conjur and get a session token.
@@ -71,13 +82,16 @@ class CyberArkSecretManager(BaseSecretManager):
try:
if self.tls_cert_path and self.tls_key_path:
# Certificate-based authentication
http_client = httpx.Client(cert=(self.tls_cert_path, self.tls_key_path))
# Certificate-based authentication - need custom client for cert
http_client = httpx.Client(
cert=(self.tls_cert_path, self.tls_key_path),
verify=self.ssl_verify,
)
resp = http_client.post(auth_url, content=self.conjur_api_key)
else:
# API key authentication
http_handler = _get_httpx_client()
resp = http_handler.post(auth_url, content=self.conjur_api_key)
http_handler = _get_httpx_client(params={"ssl_verify": self.ssl_verify})
resp = http_handler.client.post(auth_url, content=self.conjur_api_key)
resp.raise_for_status()
@@ -117,8 +131,8 @@ class CyberArkSecretManager(BaseSecretManager):
policy_yaml = f"- !variable {secret_name}\n"
try:
client = _get_httpx_client()
resp = client.post(
client = _get_httpx_client(params={"ssl_verify": self.ssl_verify})
resp = client.client.post(
policy_url,
headers={
**self._get_request_headers(),
@@ -180,6 +194,7 @@ class CyberArkSecretManager(BaseSecretManager):
async_client = get_async_httpx_client(
llm_provider=httpxSpecialProvider.SecretManager,
params={"ssl_verify": self.ssl_verify},
)
try:
@@ -227,11 +242,11 @@ class CyberArkSecretManager(BaseSecretManager):
if self.cache.get_cache(secret_name) is not None:
return self.cache.get_cache(secret_name)
sync_client = _get_httpx_client()
sync_client = _get_httpx_client(params={"ssl_verify": self.ssl_verify})
try:
url = self.get_url(secret_name)
response = sync_client.get(url, headers=self._get_request_headers())
response = sync_client.client.get(url, headers=self._get_request_headers())
response.raise_for_status()
# CyberArk Conjur returns the raw secret value as text
@@ -278,7 +293,7 @@ class CyberArkSecretManager(BaseSecretManager):
"""
async_client = get_async_httpx_client(
llm_provider=httpxSpecialProvider.SecretManager,
params={"timeout": timeout},
params={"ssl_verify": self.ssl_verify},
)
try: