Skip to content

Private Package Registries

If your project depends on internal or proprietary Python packages hosted on a private registry rather than the public PyPI, you’ll need to:

  1. Tell UV where to find the package (an index URL)
  2. Tell UV which packages come from that index (a source mapping)
  3. Provide credentials so UV can authenticate during install

CrewAI AMP uses UV for dependency resolution and installation. UV supports authenticated private registries through pyproject.toml configuration combined with environment variables for credentials.

Three pieces work together in your pyproject.toml:

Add the private package to your [project.dependencies] like any other dependency:

[project]
dependencies = [
"crewai[tools]>=0.100.1,<1.0.0",
"my-private-package>=1.2.0",
]

Register your private registry as a named index under [[tool.uv.index]]:

[[tool.uv.index]]
name = "my-private-registry"
url = "https://pkgs.dev.azure.com/my-org/_packaging/my-feed/pypi/simple/"
explicit = true

Tell UV which packages should be resolved from your private index using [tool.uv.sources]:

[tool.uv.sources]
my-private-package = { index = "my-private-registry" }
[project]
name = "my-crew-project"
version = "0.1.0"
requires-python = ">=3.10,<=3.13"
dependencies = [
"crewai[tools]>=0.100.1,<1.0.0",
"my-private-package>=1.2.0",
]
[tool.crewai]
type = "crew"
[[tool.uv.index]]
name = "my-private-registry"
url = "https://pkgs.dev.azure.com/my-org/_packaging/my-feed/pypi/simple/"
explicit = true
[tool.uv.sources]
my-private-package = { index = "my-private-registry" }

After updating pyproject.toml, regenerate your lock file:

Terminal window
uv lock

UV authenticates against private indexes using environment variables that follow a naming convention based on the index name you defined in pyproject.toml:

UV_INDEX_{UPPER_NAME}_USERNAME
UV_INDEX_{UPPER_NAME}_PASSWORD

Where {UPPER_NAME} is your index name converted to uppercase with hyphens replaced by underscores.

For example, an index named my-private-registry uses:

VariableValue
UV_INDEX_MY_PRIVATE_REGISTRY_USERNAMEYour registry username or token name
UV_INDEX_MY_PRIVATE_REGISTRY_PASSWORDYour registry password or token/PAT

The table below shows the index URL format and credential values for common registry providers. Replace placeholder values with your actual organization and feed details.

ProviderIndex URLUsernamePassword
Azure DevOps Artifactshttps://pkgs.dev.azure.com/{org}/_packaging/{feed}/pypi/simple/Any non-empty string (e.g. token)Personal Access Token (PAT) with Packaging Read scope
GitHub Packageshttps://pypi.pkg.github.com/{owner}/simple/GitHub usernamePersonal Access Token (classic) with read:packages scope
GitLab Package Registryhttps://gitlab.com/api/v4/projects/{project_id}/packages/pypi/simple/__token__Project or Personal Access Token with read_api scope
AWS CodeArtifactUse the URL from aws codeartifact get-repository-endpointawsToken from aws codeartifact get-authorization-token
Google Artifact Registryhttps://{region}-python.pkg.dev/{project}/{repo}/simple/_json_key_base64Base64-encoded service account key
JFrog Artifactoryhttps://{instance}.jfrog.io/artifactory/api/pypi/{repo}/simple/Username or emailAPI key or identity token
Self-hosted (devpi, Nexus, etc.)Your registry’s simple API URLRegistry usernameRegistry password

Private registry credentials must be configured as environment variables in CrewAI AMP. You have two options:

Web Interface
  1. Log in to CrewAI AMP
  2. Navigate to your automation
  3. Open the Environment Variables tab
  4. Add each variable (UV_INDEX_*_USERNAME and UV_INDEX_*_PASSWORD) with its value

See the Deploy to AMP — Set Environment Variables step for details.

CLI Deployment

Add the variables to your local .env file before running crewai deploy create. The CLI will securely transfer them to the platform:

.env
OPENAI_API_KEY=sk-...
UV_INDEX_MY_PRIVATE_REGISTRY_USERNAME=token
UV_INDEX_MY_PRIVATE_REGISTRY_PASSWORD=your-pat-here
Terminal window
crewai deploy create

To update credentials on an existing deployment, see Update Your Crew — Environment Variables.

When CrewAI AMP builds your automation, the resolution flow works like this:

  1. Build starts

    AMP pulls your repository and reads pyproject.toml and uv.lock.

  2. UV resolves dependencies

    UV reads [tool.uv.sources] to determine which index each package should come from.

  3. UV authenticates

    For each private index, UV looks up UV_INDEX_{NAME}_USERNAME and UV_INDEX_{NAME}_PASSWORD from the environment variables you configured in AMP.

  4. Packages install

    UV downloads and installs all packages — both public (from PyPI) and private (from your registry).

  5. Automation runs

    Your crew or flow starts with all dependencies available.

Symptom: Build fails with 401 Unauthorized or 403 Forbidden when resolving a private package.

Check:

  • The UV_INDEX_* environment variable names match your index name exactly (uppercased, hyphens → underscores)
  • Credentials are set in AMP environment variables, not just in a local .env
  • Your token/PAT has the required read permissions for the package feed
  • The token hasn’t expired (especially relevant for AWS CodeArtifact)

Symptom: No matching distribution found for my-private-package.

Check:

  • The index URL in pyproject.toml ends with /simple/
  • The [tool.uv.sources] entry maps the correct package name to the correct index name
  • The package is actually published to your private registry
  • Run uv lock locally with the same credentials to verify resolution works

Symptom: uv lock fails or produces unexpected results after adding a private index.

Solution: Set the credentials locally and regenerate:

Terminal window
export UV_INDEX_MY_PRIVATE_REGISTRY_USERNAME=token
export UV_INDEX_MY_PRIVATE_REGISTRY_PASSWORD=your-pat
uv lock

Then commit the updated uv.lock.