Chalk can resolve Python packages from one or more private indexes alongside PyPI. You configure them in Infrastructure > Artifact Repositories. Each index is rendered into the builder’s uv.toml as an [[index]] block. PyPI is always emitted first; the global prefer-private option controls whether PyPI is marked as the fallback (default = true) so private indexes are searched first.

Three index kinds are supported:

  • AWS CodeArtifact — backed by an AWS CodeArtifact repository. Chalk authenticates using a Chalk IAM principal that you grant read access to.
  • Google Artifact Registry (GAR) — backed by a GAR Python repository. Chalk authenticates with the management service account configured for your environment.
  • Preauthenticated — any pip-compatible index URL whose full authenticated URL is stored in your team’s secret store. Chalk reads the URL from the secret at build time and uses it as-is.

AWS CodeArtifact

Chalk supports downloading Python packages from private AWS CodeArtifact repositories. In order to use this feature, you must provide a Chalk IAM principal access to your repository so that Chalk can authenticate with the CodeArtifact pip registry.

Grant access to Chalk

Chalk will authenticate to your CodeArtifact repository using an IAM principal. You can view the IAM principal in your team’s settings page. The principal will look like this:

arn:aws:iam::***********:role/chalk-*********

Once you have the IAM principal ARN, you will need to grant the following permissions to the principal:

codeartifact:DescribePackageVersion
codeartifact:DescribeRepository
codeartifact:GetPackageVersionReadme
codeartifact:GetRepositoryEndpoint
codeartifact:ListPackages
codeartifact:ListPackageVersions
codeartifact:ListPackageVersionAssets
codeartifact:ListPackageVersionDependencies
codeartifact:ReadFromRepository

These permissions are derived from AWS’s instructions. They will grant Chalk the ability to read from the repository, but not to write to it. Here’s an example IAM policy to do this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CodeArtifactPermissions",
      "Effect": "Allow",
      "Action": [
        "codeartifact:DescribePackageVersion",
        "codeartifact:DescribeRepository",
        "codeartifact:GetPackageVersionReadme",
        "codeartifact:GetRepositoryEndpoint",
        "codeartifact:ListPackages",
        "codeartifact:ListPackageVersions",
        "codeartifact:ListPackageVersionAssets",
        "codeartifact:ListPackageVersionDependencies",
        "codeartifact:ReadFromRepository"
      ],
      "Principal": {
          "AWS": "arn:aws:iam::***********:role/chalk-*********"
       },
      "Resource": "*"
    }
  ]
}

Once you have created this policy, you can either attach it to your repository with the following example command:

aws codeartifact put-repository-permissions-policy --domain my_domain --domain-owner 111122223333 \
          --repository my_repo --policy-document file:///PATH/TO/policy.json

Or you can navigate to Infrastructure > Artifact Repositories and fill in the necessary fields:

AWS CodeArtifact Form


Google Artifact Registry

Chalk supports downloading Python packages from private Google Artifact Registry (GAR) Python repositories. Chalk authenticates using the management service account configured for your GCP environment, so no per-repo credentials need to be supplied.

Grant access to Chalk

Grant the management service account read access to the Artifact Registry repository — the roles/artifactregistry.reader role is sufficient. You can run, for example:

gcloud artifacts repositories add-iam-policy-binding my_repo \
  --location=us-central1 \
  --member="serviceAccount:chalk-management@my-project.iam.gserviceaccount.com" \
  --role="roles/artifactregistry.reader"

Configure the index

Navigate to Infrastructure > Artifact Repositories and add a Google Artifact Registry index, filling in the project ID, region, and repository name. Chalk uses these to construct the index URL (https://<region>-python.pkg.dev/<project>/<repo>/simple/) and mints a fresh OAuth access token at build time.


Preauthenticated

Use a Preauthenticated index when you have a fully-formed authenticated index URL — for example, a JFrog Artifactory or self-hosted devpi URL containing a username and access token — that you can hand to pip/uv as-is.

Store the index URL as a secret

Store the complete URL (including any auth) as a secret in your team’s secret store. The URL should look like one of:

https://<user>:<token>@<host>/api/pypi/<repo>/simple/
https://<host>/api/pypi/<repo>/simple/    # if no auth is needed

Configure the index

Navigate to Infrastructure > Artifact Repositories, add a Preauthenticated index, and set Index URL Secret to the locator/name of the secret you just created. Chalk reads the secret at build time and uses the value verbatim as the index URL.


Configure your Python environment

Once any of the indexes above are configured, include your private packages in your pyproject.toml like any other dependency. Chalk’s builder will resolve them through the configured indexes during deployment.

Naming and other options

Each index gets an auto-derived name (the first label of the index URL’s hostname; e.g. https://pypi.org/simplepypi). You can override this with the Name (override) field. If two indexes derive the same name, Chalk auto-suffixes with -2, -3, etc.

The Options tab exposes two global toggles that affect the rendered uv.toml:

  • Prefer private indexes — when enabled, the rendered [[index]] block for PyPI is marked default = true, so uv treats PyPI as the fallback and searches your private indexes first.
  • Unsafe first match — when enabled, the rendered uv.toml sets index-strategy = "unsafe-first-match".