Skip to main content

Configuring Developer Tools with Netskope SSL Inspection

  • February 12, 2026
  • 5 replies
  • 11146 views

jforrest
Netskope Employee
Forum|alt.badge.img+12

 

Comprehensive Guide to Configuring Developer Tools with Netskope SSL Inspection

Last Updated: May 2026

Disclaimer and Advisory

This document and the guidance contained herein are provided by Netskope for informational purposes only and are intended to assist developers and administrators in configuring third-party tools to operate with the Netskope platform.

  • "As-Is" Information: The information, scripts, and configuration examples are provided on an "as-is" basis. While Netskope makes a reasonable effort to ensure the accuracy of this information at the time of publication, we make no warranties, express or implied, regarding its completeness, accuracy, or suitability for any particular purpose.

  • Third-Party Systems: The software, libraries, and tools discussed in this document are not owned, controlled, or maintained by Netskope. The configuration, commands, and behavior of these third-party systems are subject to change at any time without notice by their respective owners. Netskope assumes no responsibility for errors, omissions, or outdated information related to these third-party systems.

  • Use at Your Own Risk: The use of any information or scripts from this guide is done at your own discretion and risk. You are solely responsible for adequate protection and backup of your data and equipment. By following this guidance, you agree that you will be solely responsible for any damage to your computer system, loss of data, or disruption of service that may result from such activities.

  • No Alteration of Agreements: This document does not modify, enlarge, or otherwise amend any of your rights or obligations under your master subscription agreement with Netskope. All entitlements regarding warranties, support, and maintenance for the Netskope service are governed solely by that agreement.

Netskope's goal is to reduce operational friction when using our platform. This document is a good-faith effort to aid in that process, but it should not be considered a substitute for the official documentation of the third-party products mentioned. Always consult the primary documentation for each tool for the most current and accurate configuration details.

1. Introduction

This guide provides comprehensive instructions for configuring common command-line (CLI) tools, programming languages, and development frameworks to work correctly with Netskope's SSL Interception. It also provides strategic guidance for deploying and managing SSL decryption for developer teams.

2. Strategic Approach to SSL Decryption for Developer Teams

A successful SSL decryption deployment requires balancing security objectives with developer productivity. A well-planned strategy can minimize disruption and build trust with your technical teams.

Proactive Strategies (During Deployment & Expansion)

  • Phased Rollout: Avoid enabling decryption for all developers at once. Start with a small, tech-savvy pilot group. This allows you to identify and resolve common issues with a more forgiving audience.

  • Pre-populate Exception Lists: Before deploying to the pilot group, proactively create SSL bypass policies for well-known developer service categories. This includes common code repositories, package managers, and API endpoints known to use certificate pinning. Use the Netskope-defined categories below to create broad but relevant exceptions:

    • Development Tools: This is the most critical category and covers services used for source code management, CI/CD, and other development processes.

    • IaaS/PaaS: Essential for developers working with public cloud providers. This category covers the APIs and service endpoints for major platforms.

    • Content Server: Often includes content delivery networks (CDNs) that host developer libraries and assets.

    • File Repositories / Cloud Storage: Catches services used to host software artifacts, binaries, and large datasets.

  • Establish Clear Communication Channels: Announce the rollout schedule in advance. Clearly explain what SSL decryption is, why it is being implemented, and how developers can request an exception. Provide a link to this guide.

  • Developer Onboarding: As part of onboarding new developers, provide them with this guide and the pre-generated certificate bundle file to ensure their environment is set up correctly from day one.

Reactive Strategies (When Issues Arise)

  • Establish a Fast-Track Exception Process: When a developer's workflow is blocked, time is critical. Create a simple and rapid process for requesting an exception, such as a dedicated Slack channel or a high-priority service desk ticket queue. The goal is to unblock the developer first and analyze the root cause later.

  • Empower the Help Desk: Equip your front-line support with this guide and the troubleshooting steps listed in the appendix. They can often diagnose if an issue is related to a missing CA bundle before escalating to the network security team.

  • Use Temporary Exceptions: Grant temporary, time-based exceptions to unblock a developer immediately. This provides breathing room to investigate whether a permanent, more narrowly-scoped policy (e.g., for a specific hostname) is required.

3. First Steps: Generating Your Certificate Bundle

Before configuring any tools, you must have a PEM-formatted certificate bundle that includes the Netskope Root CA.

⚠️ Important Note on Secure Configuration: If your tenant has Secure Configuration or Secure Enrollment enabled, the legacy unauthenticated API methods for downloading certificates will return a {"status":"error","msg":"Method Not Allowed"} error. You must use the local extraction method or the authenticated v2 API method below.

Method 1: Extract from OS Trust Store (Client Installed)

If the Netskope Client is already installed on the machine, the certificates are in the local trust store. This is the most reliable method when Secure Configuration is enabled.

macOS/Linux:

Bash

security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain /Library/Keychains/System.keychain > /tmp/nscacert_combined.pem

Windows (PowerShell):

PowerShell

((((gci Cert:\CurrentUser\Root) + (gci Cert:\LocalMachine\Root) + (gci Cert:\CurrentUser\CA) + (gci Cert:\LocalMachine\Root)) | Where-Object { $_.RawData -ne $null } ` | Sort-Object -Property Thumbprint -Unique ` | % { "-----BEGIN CERTIFICATE-----", [System.Convert]::ToBase64String($_.RawData, "InsertLineBreaks"), "-----END CERTIFICATE-----", "" }) ` -replace "`r","") -join "`n" ` | Out-File -Encoding ascii "$env:ProgramData\Netskope\STAgent\data\nscacert_combined.pem" -NoNewline

Method 2: Authenticated v2 API Download (Headless/Tunnels)

For headless machines, servers using IPsec/GRE tunnels without the Netskope Client, or instances where Secure Enrollment blocks the legacy API, you must use the Netskope v2 API with a valid API token to fetch the certificates.

 

A fully maintained repository of scripts utilizing this fallback method is available here:

GitHub Repository: ns-toconnor/ssl-configure-script

 

Method 3: Legacy API Download (Fails if Secure Config is Enabled)

Only use this if Secure Configuration is disabled on your tenant.

macOS / Linux (Bash):

Bash

orgKey="REPLACE_WITH_YOUR_ORG_KEY" 
tenantName="REPLACE_WITH_YOUR_TENANT_NAME"
certName="netskope-cert-bundle.pem"

curl -k "https://addon-$tenantName/config/ca/cert?orgkey=$orgKey" > ./$certName
curl -k "https://addon-$tenantName/config/org/cert?orgkey=$orgKey" >> ./$certName
curl -k -L "https://curl.se/ca/cacert.pem" >> ./$certName

4. Tool-Specific Configuration

AWS CLI / Boto3

  • Instruction: export AWS_CA_BUNDLE=/path/to/bundle.pem

  • Verification: aws s3 ls

  • Bypass Examples: For temporary unblocking, a Netskope admin can add *.amazonaws.com to an SSL bypass list.

cURL

  • Instruction: export CURL_CA_BUNDLE=/path/to/bundle.pem

  • Verification: curl -v https://example.com

Docker

  • Instruction: Certificate must be copied into the container image.

  • Bypass Examples: *.docker.io, *.docker.com

Git

  • Instruction (Recommended): git config --global http.sslCAInfo /path/to/bundle.pem

  • Verification: git ls-remote https://github.com/git/git

  • Bypass Examples: github.com, gitlab.com, dev.azure.com

Google Cloud SDK (gcloud CLI)

  • Instruction: gcloud config set core/custom_ca_certs_file /path/to/bundle.pem

  • Verification: gcloud auth login

  • Bypass Examples: *.googleapis.com

Java / Maven / Gradle

  • Instruction (Recommended): Use the $JAVA_OPTS environment variable.

    • Windows: setx JAVA_OPTS "-Djavax.net.ssl.trustStoreType=WINDOWS-ROOT"

    • macOS: export JAVA_OPTS="-Djavax.net.ssl.trustStoreType=KeychainStore"

  • Verification: mvn dependency:resolve

  • Bypass Examples: repo.maven.apache.org, repo1.maven.org, plugins.gradle.org

Node.js / NPM / Yarn

  • Instruction (Recommended): export NODE_EXTRA_CA_CERTS=/path/to/bundle.pem

  • Verification: npm install express

  • Bypass Examples: registry.npmjs.org, registry.yarnpkg.com

Python / pip

  • Instruction: export REQUESTS_CA_BUNDLE=/path/to/bundle.pem

  • Verification: pip install requests

  • Bypass Examples: pypi.org, files.pythonhosted.org

⚠️ CRITICAL PYTHON 3.13+ CONSIDERATIONS ⚠️

Python 3.13 and newer versions enforce stricter TLS certificate validation standards. This may cause SSL errors when connecting to services through Netskope SSL Decryption, even with a CA bundle configured.

The error often looks like: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier. This occurs because some older Netskope tenant CAs may not include certain modern X.509 extensions that Python 3.13+ now requires for validation.

If you cannot downgrade from Python 3.13+, here are the available options:

Option 1: Administrator Configuration (Recommended)

These are the most secure solutions as they do not require developers to alter their code. These actions must be performed by a Netskope administrator.

  1. Create an SSL Decryption Bypass Policy: This is the best approach. An administrator can create a policy to exempt essential developer domains (such as package repositories, code hosting sites, and API endpoints) from SSL decryption.

    • Action: In the Netskope UI, navigate to Policies > SSL Decryption. Create a new policy to "Bypass" or "Do Not Decrypt" for the required application or domain category.

  2. Regenerate Tenant Certificates (Long-Term Fix): The underlying issue causing Python 3.13+ errors is that the tenant's SSL interception certificates may be missing modern, required X.509 extensions (specifically the Authority Key Identifier) or Basic Constraint not set as “Critical”.

    • Action: Open a ticket with Netskope Support to request a rotation of your Tenant CA Certificate to comply with stricter RFC standards.

    • Note: Rotating the Tenant CA is sufficient to resolve the Python 3.13 compatibility issue; regenerating the Root CA is typically not required for this specific case. This provides a cleaner and less intrusive resolution path.

Option 2: Advanced Python Configuration (Client-Side Workarounds)

If a policy change is not possible, you can force Python to use a custom SSL context that is less strict. This requires code changes and knowingly reduces the security posture of the specific application.

Workaround A: Custom HTTP Adapter (For direct requests usage)

The following example shows how to use requests with a custom SSLContext that trusts your CA bundle (via the REQUESTS_CA_BUNDLE env var) but does not enforce the newer, stricter checks.

Note: This approach only works if no underlying library is wrapping the requests library (e.g., poetry for managing dependencies). Applications wrapping requests will still break unless patched to use custom adapters.

Python

import requests.adapters
import ssl
import certifi

class CustomHttpAdapter(requests.adapters.HTTPAdapter):
"""A custom transport adapter that uses a specific SSLContext."""
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)

def init_poolmanager(self, connections, maxsize, block=False):
# Dynamically import urllib3 poolmanager to avoid early init issues
from urllib3.poolmanager import PoolManager
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_context=self.ssl_context
)

def get_legacy_session():
""" Creates a requests Session using a custom SSLContext to trust the specified CA bundle without enforcing the strictest checks. """
ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile=certifi.where())
ctx.verify_flags = ssl.VERIFY_X509_PARTIAL_CHAIN

session = requests.Session()
session.mount('https://', CustomHttpAdapter(ssl_context=ctx))
return session

# New Requests.sessions.Session object which does not have strict certificate checking enabled
s = get_legacy_session()

Workaround B: Virtual Environment urllib3 Patch (For broader library compatibility)

To disable strict certificate chain validation across an entire virtual environment (fixing wrapper libraries like Poetry), you can manually patch urllib3:

  1. Locate the following file in your virtual environment: \Lib\site-packages\urllib3\util\ssl_.py

  2. Comment out the line containing: verify_flags |= VERIFY_X509_STRICT

Note: This must be done manually in every virtual environment where libraries are utilizing the requests/ssl modules.

5. Monitoring Client SSL Errors in Advanced Analytics

The transaction log data confirms that the errors reported by Netskope (e.g., HsFailure (error:0A000412:SSL routines::ssl/tls alert bad certificate)) are standard TLS alerts, often derived from OpenSSL libraries. The hexadecimal code (0A000412) corresponds directly to a TLS alert code (TLS_AD_BAD_CERTIFICATE).

You can proactively monitor these errors in Netskope Advanced Analytics to identify problematic applications or domains before users report them.

Step-by-Step Guide to Create a Monitoring Report

  1. Navigate to Advanced Analytics: Log into your Netskope tenant and select Advanced Analytics.

  2. Select the Data Source: Start a new query using the Transaction Events data source.

  3. Add Key Columns: Add the following fields to your query to get a clear picture of the errors:

    • Transaction Events > User

    • Transaction Events > Request Hostname

    • Transaction Events > Client SSL Error

    • Transaction Events > # Events (as the metric)

  4. Filter for Relevant Errors:

    • To see all client-side SSL errors, add a filter: Transaction Events > Client SSL Error is not equal to OK.

    • To find specific certificate validation issues (like those affecting Python 3.13+), add a filter: Transaction Events > Client SSL Error contains any of bad certificate, certificate unknown, unknown ca.

  5. Summarize and View Data:

    • Use the Group By function on Transaction Events > Request Hostname and Transaction Events > Client SSL Error.

    • Use Sum on the # Events column.

    • Sort the results by the event count in descending order. This will immediately show you the top domains and users generating the most SSL errors.

  6. Save and Schedule the Report:

    • Save this query as a report (e.g., "Top Developer SSL Errors").

    • Add the report to a dashboard for ongoing visibility.

    • You can schedule this report to be emailed regularly to the network security and developer support teams, enabling them to proactively create exceptions or reach out to affected users with this guidance.

Appendix: Step-by-Step Execution Guide

This section provides detailed instructions for users who need specific guidance on configuring their environment.

Setting Environment Variables on Windows (PowerShell)

This example shows how to permanently set the "master" environment variable in your PowerShell profile so it's available every time you open a new PowerShell window.

Step 1: Open PowerShell

Click the Start Menu, type PowerShell, and select "Windows PowerShell". It does not need to be run as an administrator for this task.

Step 2: Check for and Create a PowerShell Profile

Your profile is a script that runs every time PowerShell starts. First, check if you already have one. Type the following command and press Enter:

PowerShell

Test-Path $PROFILE

If this returns True, you already have a profile. If it returns False, create one with this command:

PowerShell

New-Item -Path $PROFILE -Type File -Force

Step 3: Open Your Profile in a Text Editor (Notepad)

Now that the profile file exists, open it in Notepad. Type the following command and press Enter:

PowerShell

notepad $PROFILE

Step 4: Add the Environment Variable Configuration

In the Notepad window, add the following lines. Be sure to replace the placeholder path with the actual path to the netskope-cert-bundle.pem (or nscacert_combined.pem) file you extracted or downloaded earlier.

PowerShell

# Set the master variable for the Netskope CA bundle 
# IMPORTANT: Update this path to where you saved your bundle file!
$env:NETSKOPE_CA_BUNDLE = "C:\Users\YourUsername\netskope-cert-bundle.pem"

# Configure common tools to use the master variable
$env:REQUESTS_CA_BUNDLE = $env:NETSKOPE_CA_BUNDLE
$env:NODE_EXTRA_CA_CERTS = $env:NETSKOPE_CA_BUNDLE
$env:SSL_CERT_FILE = $env:NETSKOPE_CA_BUNDLE
$env:AWS_CA_BUNDLE = $env:NETSKOPE_CA_BUNDLE

Step 5: Save and Close Notepad

In Notepad, go to FileSave, then close the window.

Step 6: Apply and Verify the Changes

The changes will not apply to your current PowerShell session until you "source" the profile. In your PowerShell window, type the following command and press Enter:

PowerShell

. $PROFILE

(Note: The command is a dot, a space, and then $PROFILE)

To verify that the variable is now set, type the following command and press Enter:

PowerShell

echo $env:NETSKOPE_CA_BUNDLE

It should print the path you specified. Now, close and reopen PowerShell. The variables will be set automatically in every new session.

5 replies

marina-3dc64ef2

are there any tool-specific configuration steps for  claude desktop app? we are facing lots of issues with claude desktop app at the moment… 


steiner.acedo-88e38df3

Hey ​@jforrest I’m trying to manually pull the cert but getting an error message

~/code $ curl -k "https://addon-TENANT_NAME.goskope.com/config/ca/cert?orgkey=KEY"
{"status":"error","msg":"Method Not Allowed"}

Same thing happens with the /org/cert path. 
Is there anything in specific that needs to be enabled on the tenant to get these cert? 


hvanachterberg
Netskope Employee
  • Netskope Employee
  • March 24, 2026

Hey ​@jforrest I’m trying to manually pull the cert but getting an error message

~/code $ curl -k "https://addon-TENANT_NAME.goskope.com/config/ca/cert?orgkey=KEY"
{"status":"error","msg":"Method Not Allowed"}

Same thing happens with the /org/cert path. 
Is there anything in specific that needs to be enabled on the tenant to get these cert? 

When secure configuration is turned on, this ‘API’ endpoint is not available. You can generate the certificate bundle on a client that has the Netskope Client enabled by using this command:

security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain /Library/Keychains/System.keychain > /tmp/nscacert_combined.pem

 


jforrest
Netskope Employee
Forum|alt.badge.img+12
  • Author
  • Netskope Employee
  • April 22, 2026

Hey ​@jforrest I’m trying to manually pull the cert but getting an error message

~/code $ curl -k "https://addon-TENANT_NAME.goskope.com/config/ca/cert?orgkey=KEY"
{"status":"error","msg":"Method Not Allowed"}

Same thing happens with the /org/cert path. 
Is there anything in specific that needs to be enabled on the tenant to get these cert? 

did you update the TENANT_NAME and Orgkey values when executing the curl cmd?


notskope
  • New Member III
  • May 1, 2026

Option 2: Advanced Python Configuration (Client-Side Workaround)

If a policy change is not possible, you can force Python to use a custom SSL context that is less strict. This requires code changes and knowingly reduces the security posture of the specific application.

 

The following example shows how to use requests with a custom SSLContext that trusts your CA bundle but does not enforce the newer, stricter checks.

 

code block omitted for brevity

 

This approach only works if no underlying library is using the requests library (such as poetry for managing dependencies). These applications still break unless you patch them to use custom requests adapters as well. I have reformatted the above code block to be actually usable and removed the sections specifying the CA bundle as using the `REQUESTS_CA_BUNDLE` environment works fine for this.

import requests.adapters
import ssl
import certifi # Path to the CA bundle file you generated.

class CustomHttpAdapter(requests.adapters.HTTPAdapter):
"""A custom transport adapter that uses a specific SSLContext."""
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, block=False):
# Dynamically import urllib3 poolmanager to avoid early init issues
from urllib3.poolmanager import PoolManager
self.poolmanager = PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_context=self.ssl_context )

def get_legacy_session():
""" Creates a requests Session using a custom SSLContext to trust the specified CA bundle without enforcing the strictest checks. """
# Add the Netskope CA bundle to the context's trust store.
ctx = ssl.create_default_context( purpose=ssl.Purpose.SERVER_AUTH, cafile=certifi.where())
ctx.verify_flags = ssl.VERIFY_X509_PARTIAL_CHAIN
# ctx.load_verify_locations(cafile=ca_bundle_path)
session = requests.Session()
session.mount('https://', CustomHttpAdapter(ssl_context=ctx))
return session

s = get_legacy_session() #New Requests.sessions.Session object which does not have strict certificate checking enabled

 

To disable strict certificate chain validation in an entire virtual environment:

You can edit the following file in your virtual environment: "\Lib\site-packages\urllib3\util\ssl_.py" and comment out the line containing:

  • verify_flags |= VERIFY_X509_STRICT

However, this needs to be done in every virtual environment where libraries are using the requests/ssl modules.