Connect Directly to Your Curated Catalog
This guide covers how to connect your package manager directly to your ActiveState Curated Catalog, with no intermediary artifact manager (JFrog Artifactory, Cloudsmith, etc.) in between. Your package manager authenticates straight to repo.activestate.com using a token issued from the ActiveState Portal.
If you'd rather front the catalog with a repository manager for local caching and centralized access control across your organization, see JFrog Artifactory instead.
Direct connection is not covered by ActiveState support - see Can I use pip directly without a repository manager? for why a repository manager is recommended. Availability can also vary by organization and by language; confirm with your ActiveState representative that it's enabled for your catalog.
repo.activestate.com rate-limits by IP address (roughly 2000 requests per 5 minutes overall, 1000 per 5 minutes for generic/binaries paths). Without a repository manager in front to share a local cache, a team or CI fleet sharing one outbound IP can hit this during normal use - it shows up as a 403, which looks like a credential problem rather than a rate limit. If you see unexplained 403s under load, this is the first thing to check.
Prerequisites
- An ActiveState Curated Catalog, with permission to issue access tokens at portal.activestate.com.
- The package manager for your language already installed (pip, npm, cpanm, R, Cargo, Conan, Maven, or the .NET SDK).
Get your access token
- Log in to portal.activestate.com.
- From the Curated Catalogs home page, click Setup Instructions next to the catalog you want to use, or open the catalog's page and click the same button there.
- Click Issue Access Token if this is your first time creating one, or Deactivate & Issue New Token if you need to rotate it.
- Save the token shown - it's only displayed once. The same token authenticates against every catalog (language) in your organization, so you only need to do this once per organization, not once per language.
The portal also shows a ready-made config snippet for your catalog's language. The steps below cover the same setup in more detail.
Configure your package manager
Every language follows the same shape: point your package manager's own config file or command directly at the catalog, using the token from the previous step. Select your language below for the full walkthrough.
- Python
- JavaScript
- Perl
- R
- Rust
- C/C++
- Java
- .NET
- Shared Dependencies
Configure pip (pip.conf)
Create or edit a pip.conf (pip.ini on Windows) in one of the following locations:
- User-specific:
$HOME/.config/pip/pip.conf(Linux/macOS) or%APPDATA%\pip\pip.ini(Windows) - Per-project (virtual environment):
<venv>/pip.conf
[global]
index-url = https://__token__:<your-access-token>@repo.activestate.com/<org-id>/pypi/simple/
__token__ is a literal string, not a placeholder. pip authenticates with HTTP Basic Auth using __token__ as the username and your access token as the password.
Test package access
python3 -m venv .venv
source .venv/bin/activate
pip install requests
python3 -c "import requests; print(requests.__version__)"
Fetch the Python interpreter
The Python interpreter and its native libraries (OpenSSL, SQLite, zlib, etc.) are served from the catalog's generic binaries path, using the same token:
curl -fsSL -u "activestate-repos:<your-access-token>" \
"https://repo.activestate.com/<org-id>/generic/binaries/python-3.12.12-linux-x86_64.tar.gz" \
-o python-3.12.12.tar.gz
tar -xzf python-3.12.12.tar.gz
This is an example file name - list the directory first to confirm what's in your catalog (see the Shared Dependencies tab).
Configure npm (.npmrc)
Create or edit an .npmrc in one of the following locations:
- Per-project (recommended):
<project-root>/.npmrc - User-specific:
$HOME/.npmrc(Linux/macOS) or%USERPROFILE%\.npmrc(Windows)
registry=https://repo.activestate.com/<org-id>/npm/
//repo.activestate.com/<org-id>/npm/:_authToken=<your-access-token>
always-auth=true
always-auth=true ensures npm sends the token on every request to this registry, including requests for package names that look public. Modern npm already sends the token for any request matching a scoped registry entry like the one above, so this is mainly a safety net for older npm versions and other npm-compatible clients that still decide whether to attach credentials based on a package's apparent visibility.
Test package access
npm init -y
npm install lodash
node -e "console.log(require('lodash/package.json').version)"
Configure your CPAN client
The catalog serves a standard CPAN-mirror layout, so any CPAN client works by pointing at it with HTTP Basic Auth.
cpanm
cpanm --from https://activestate-repos:<your-access-token>@repo.activestate.com/<org-id>/cpan Some::Module
cpm
cpm install --resolver 02packages,https://activestate-repos:<your-access-token>@repo.activestate.com/<org-id>/cpan Some::Module
CPAN.pm
perl -MCPAN \
-e 'CPAN::Shell->o(qw(conf urllist push), "https://activestate-repos:<your-access-token>@repo.activestate.com/<org-id>/cpan")' \
-e 'CPAN::Shell->o(qw(conf pushy_https 0))' \
-e 'CPAN::Shell->o(qw(conf commit))' \
-e 'CPAN::Shell->install("Some::Module")'
Test package access
cpanm -L /tmp/test-local --from https://activestate-repos:<your-access-token>@repo.activestate.com/<org-id>/cpan JSON::PP
perl -I /tmp/test-local/lib/perl5 -MJSON::PP -e 'print encode_json({ok => 1}), "\n"'
Configure R (.Renviron and .Rprofile)
R has no single config file that embeds both the repository URL and the token, so split them across two files.
.Renviron (in your home directory, or your project directory to scope it to one project):
ACTIVESTATE_CRAN_TOKEN=<your-access-token>
.Rprofile (sourced automatically when R starts in that directory):
token <- Sys.getenv("ACTIVESTATE_CRAN_TOKEN")
options(repos = c(CRAN = paste0(
"https://activestate-repos:", token,
"@repo.activestate.com/<org-id>/cran"
)))
This only matters on minimal base images that don't ship a system CA bundle in the location libcurl expects (for example, slim Docker images) - there, R's libcurl download method doesn't honor SSL_CERT_FILE, so you need CURL_CA_BUNDLE pointed at a CA bundle (for example, /etc/ssl/certs/ca-certificates.crt, if present), or TLS requests fail with Problem with the SSL CA cert. A normal desktop or server OS already has a CA bundle in the expected location, so this usually isn't needed there.
Test package access
install.packages("jsonlite")
library(jsonlite)
packageVersion("jsonlite")
Fetch the R interpreter
The R interpreter and its native libraries (OpenSSL, PCRE2, ICU, OpenBLAS, etc.) are served from the catalog's generic binaries path, using the same token:
curl -fsSL -u "activestate-repos:<your-access-token>" \
"https://repo.activestate.com/<org-id>/generic/binaries/R-4.4.3-linux-x86_64.tar.gz" \
-o R-4.4.3.tar.gz
tar -xzf R-4.4.3.tar.gz
This is an example file name - list the directory first to confirm what's in your catalog (see the Shared Dependencies tab).
R's launcher script hardcodes R_HOME=/usr/lib/R at build time and is not self-relocating. If you extract this tarball anywhere other than directly onto /usr, merge it into the real /usr (as root, for example during a container build) before invoking R/Rscript.
Configure Cargo
# .cargo/config.toml
[registries.activestate]
index = "sparse+https://repo.activestate.com/<org-id>/cargo/"
credential-provider = "cargo:token"
token = "Bearer <your-access-token>"
Reference the registry in Cargo.toml for any dependency you want resolved from the catalog:
[dependencies]
anyhow = { version = "1", registry = "activestate" }
Only dependencies that name registry = "activestate" resolve from the catalog - any dependency without it still resolves from crates.io, the default registry, so a project isn't fully on the catalog just because this section is configured.
Test package access
cargo new test-crate && cd test-crate
cargo add anyhow --registry activestate
cargo build
Fetch and use the Rust toolchain
rustc/cargo are served from the catalog's generic binaries path, using the same token:
curl -fsSL -u "activestate-repos:<your-access-token>" \
"https://repo.activestate.com/<org-id>/generic/binaries/rust-binary-linux-1.91.0-linux-x86_64.tar.gz" \
-o rust-binary-linux.tar.gz
tar -xzf rust-binary-linux.tar.gz
./installdir/usr/bin/rustc --version
This is an example file name - list the directory first to confirm what's in your catalog (see the Shared Dependencies tab).
rustc/cargo carry a $ORIGIN-relative RPATH to their sibling libraries, so they run correctly straight out of wherever you extract them, with no relocation step needed.
Install Conan 2.x if you haven't already (pip install conan). Conan 1.x uses a different remote/API shape and isn't covered here.
Configure Conan
conan remote add activestate https://repo.activestate.com/<org-id>/conan
conan remote login activestate activestate-repos --password <your-access-token>
conan profile detect # if you don't already have a local build profile
Test package access
conan list "brotli/1.2.0" -r activestate
conan install --requires="brotli/1.2.0" -r activestate --build="brotli/1.2.0"
Fetch the C/C++ toolchain
gcc, cmake, ninja, and around 100 native C/C++ libraries are served from the catalog's generic binaries path, using the same token:
curl -fsSL -u "activestate-repos:<your-access-token>" \
"https://repo.activestate.com/<org-id>/generic/binaries/gcc-15.1.0-linux-x86_64.tar.gz" \
-o gcc.tar.gz
tar -xzf gcc.tar.gz
./installdir/usr/bin/gcc --version
This is an example file name - list the directory first to confirm what's in your catalog (see the Shared Dependencies tab).
Three gotchas worth knowing before building on top of this, confirmed against a real Debian/Ubuntu base image:
- Multiarch paths: the compiler targets a generic
x86_64-pc-linux-gnutriplet, not Debian/Ubuntu's multiarch layout. SetCPATH=/usr/include/x86_64-linux-gnuandLIBRARY_PATH=/usr/lib/x86_64-linux-gnubefore invoking gcc, or compiling fails withfatal error: bits/libc-header-start.h: No such file or directory. cc1's runtime deps: gcc's real compiler binary needslibisl/gmp/mpfr/mpcat runtime, and a system assembler/linker (as/ld, frombinutils) to finish compiling anything. Installbinutilsfrom the base OS, and pulllibisl/gmp/mpfr/mpcas additional generic-catalog binaries alongside gcc.- cmake's OpenSSL ABI: the catalog's
cmakebinary is linked against a newer OpenSSL ABI than Debian bookworm ships. Pullopenssl-3.6.1or newer from the generic catalog and put it onLD_LIBRARY_PATH.
Configure Maven (settings.xml)
Create or edit a Maven settings.xml at ${user.home}/.m2/settings.xml - Maven picks this up automatically, with no -s flag needed:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>activestate-direct</id>
<username>activestate-repos</username>
<password><your-access-token></password>
</server>
</servers>
<mirrors>
<mirror>
<id>activestate-direct</id>
<mirrorOf>*</mirrorOf>
<url>https://repo.activestate.com/<org-id>/maven2</url>
</mirror>
</mirrors>
</settings>
With <mirrorOf>*</mirrorOf>, Maven resolves its own plugins (for example maven-dependency-plugin, used by the test command below) through the catalog too, with no fallback to Maven Central. If your catalog doesn't carry a plugin a build needs, that build fails with a plugin-resolution error rather than a missing-package error - make sure the Maven plugins your builds use are entitled in your catalog as well.
Test package access
mvn dependency:get -Dartifact=com.google.guava:guava:33.4.0-jre
Gradle
Gradle uses the same maven2 URL and token as Maven above. Keep the token out of build.gradle (a project file usually committed to git) by putting it in ~/.gradle/gradle.properties instead:
activestate.username=activestate-repos
activestate.password=<your-access-token>
Then reference those properties from build.gradle:
repositories {
maven {
url = "https://repo.activestate.com/<org-id>/maven2"
credentials {
username = findProperty("activestate.username")
password = findProperty("activestate.password")
}
}
}
Fetch the JDK
An OpenJDK build is served from the catalog's generic binaries path, using the same token:
curl -fsSL -u "activestate-repos:<your-access-token>" \
"https://repo.activestate.com/<org-id>/generic/binaries/openjdk-bin-25.0.2-linux-x86_64.tar.gz" \
-o openjdk-bin.tar.gz
tar -xzf openjdk-bin.tar.gz
./installdir/usr/bin/java -version
This is an example file name - list the directory first to confirm what's in your catalog (see the Shared Dependencies tab).
Configure NuGet (NuGet.Config)
Create or edit a NuGet.Config in your project directory, or at %AppData%\NuGet\NuGet.Config (Windows) / ~/.nuget/NuGet/NuGet.Config (Linux/macOS) to apply it machine/user-wide:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="activestate" value="https://repo.activestate.com/<org-id>/nuget/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<activestate>
<add key="Username" value="activestate-repos" />
<add key="ClearTextPassword" value="<your-access-token>" />
</activestate>
</packageSourceCredentials>
</configuration>
Test package access
dotnet new console -n TestApp && cd TestApp
dotnet add package morelinq --version 4.4.0
dotnet run
The portal labels the generic ecosystem Shared Dependencies - it isn't a separate catalog with its own token, it's the same generic/binaries facet already used by the "Fetch the interpreter/toolchain" sections above (Python, R, Rust, C/C++, Java), served under the same org-id and the same access token you saved in Get your access token.
The exact binaries and versions available depend on your own catalog and change over time, so every file name shown in this guide (python-3.12.12-..., R-4.4.3-..., and so on) is an example, not a guarantee. List the directory first to find the exact name in your catalog:
curl -fsSL -u "activestate-repos:<your-access-token>" "https://repo.activestate.com/<org-id>/generic/binaries/"
Test access
curl -fsSL -u "activestate-repos:<your-access-token>" \
"https://repo.activestate.com/<org-id>/generic/binaries/mozilla-ca-cert-bundle-2025-07-15-linux-x86_64.tar.gz" \
-o ca-bundle.tar.gz
tar -xzf ca-bundle.tar.gz
Any curl-based tool can authenticate with plain HTTP Basic Auth as shown above. If you'd rather use a credential file than pass -u on every call, .netrc works as a drop-in alternative for curl, wget, and other clients that read it automatically - R's libcurl download method does not use .netrc, so use the curl form directly for R as well. Create ~/.netrc (on Windows, curl looks for _netrc under %USERPROFILE%, since %HOME% usually isn't set) and set its permissions to 600 so other users on the machine can't read your token:
machine repo.activestate.com
login activestate-repos
password <your-access-token>
Support
As noted above, ActiveState support does not cover a direct, repository-manager-free setup. If you run into a catalog issue that isn't specific to this connection method (a missing package, an entitlement problem), contact ActiveState support with:
- Package name experiencing the issue.
- Catalog/token configuration, with a screenshot and credentials redacted.
- Error messages from your package manager's output.