

Amazon CodeCatalyst is no longer open to new customers. Existing customers can continue to use the service as normal. For more information, see [How to migrate from CodeCatalyst](migration.md).

# Publishing and modifying packages
<a name="working-with-packages"></a>

A *package* in CodeCatalyst is a bundle of software and the metadata that is required to resolve dependencies and install the software. For a list of supported package formats in CodeCatalyst, see [Publish and share software packages in CodeCatalyst](packages.md). This section provides information about publishing, viewing, deleting packages, and updating a package version's status.

**Topics**
+ [Publishing packages to a CodeCatalyst package repository](package-publishing.md)
+ [Viewing package version details](working-with-packages-view.md)
+ [Deleting a package version](working-with-packages-delete.md)
+ [Updating a package version's status](working-with-packages-update-version-status.md)
+ [Editing package origin controls](package-origin-controls.md)

# Publishing packages to a CodeCatalyst package repository
<a name="package-publishing"></a>

 You can publish versions of any supported package type to a CodeCatalyst package repository by using package manager tools. The steps to publish a package version are as follows:

**To publish a package version to a CodeCatalyst package repository**

1. If you haven't, [create a package repository](packages-repositories-create.md).

1. Connect your package manager to your package repository. For instructions on how to connect the npm package manager to a CodeCatalyst package repository, see [Configuring and using npm](packages-npm-use.md).

1. Use your connected package manager to publish your package versions.

**Contents**
+ [Publishing and upstream repositories](#package-publishing-upstreams)
+ [Private packages and public repositories](#package-publishing-upstreams-direct)
+ [Overwriting package assets](#package-publishing-overwrite-assets)

## Publishing and upstream repositories
<a name="package-publishing-upstreams"></a>

In CodeCatalyst, you cannot publish package versions that are present in reachable upstream repositories or public repositories. For example, suppose that you want to publish an npm package, `lodash@1.0`, to a package repository, `myrepo`, and `myrepo` is connected to npmjs.com through a gateway repository configured as an upstream repository. If `lodash@1.0` is present in the upstream repository or in npmjs.com, CodeCatalyst rejects any attempt to publish to it in `myrepo` by issuing a 409 conflict error. This helps prevent you from accidentally publishing a package with the same name and version as a package in an upstream repository, which can result in unexpected behavior. 

You can still publish different versions of a package name that exist in an upstream repository. For example, if `lodash@1.0` is present in an upstream repository, but `lodash@1.1` is not, you can publish `lodash@1.1` to the downstream repository.

## Private packages and public repositories
<a name="package-publishing-upstreams-direct"></a>

 CodeCatalyst does not publish packages stored in CodeCatalyst repositories to public repositories, such as npmjs.com or Maven Central. CodeCatalyst imports packages from public repositories into a CodeCatalyst repository, but it doesn't move packages in the opposite direction. Packages that you publish to CodeCatalyst repositories remain private and are only available to the CodeCatalyst project in which the repository belongs.

## Overwriting package assets
<a name="package-publishing-overwrite-assets"></a>

 You can't republish a package asset that already exists with different content. For example, suppose that you already published a Maven package with a JAR asset `mypackage-1.0.jar`. You can only publish that asset again if the checksum of the old and new assets are identical. To republish the same asset with new content, delete the package version first. Trying to republish the same asset name with different content will result in an HTTP 409 conflict error. 

For package formats that support multiple assets (Python and Maven), you can add new assets with different names to an existing package version at any time, assuming you have the required permissions. Because npm and NuGet only support a single asset per package version, to modify a published package version you must first delete it. 

 If you try to republish an asset that already exists (for example, `mypackage-1.0.jar`), and the content of the published asset and the new asset are identical, the operation will succeed because the operation is idempotent. 

# Viewing package version details
<a name="working-with-packages-view"></a>

You can use the CodeCatalyst console to view details about a specific package version.

**To view package version details**

1. In the navigation pane, choose **Packages**.

1. On the **Package repositories** page, choose the repository that contains the package version that you want to view the details of.

1. Search for the package version in the **Packages** table. You can use the search bar to filter packages by package name and format. Choose the package from the list.

1. In the **Package details** page, choose **Versions**, and then choose the version you want to view.

# Deleting a package version
<a name="working-with-packages-delete"></a>

You can delete a package version from the **Package version details** page in the CodeCatalyst console.

**To delete a package version**

1. In the navigation pane, choose **Packages**.

1. On the **Package repositories** page, choose the repository that contains the package version that you want to delete.

1. Search and choose the package from the table.

1. On the **Package details** page, choose **Versions** and choose the version you want to delete.

1. On the **Package version details** page, choose **Version actions** and then choose **Delete**.

1. Enter *delete* into the text field and choose **Delete**.

# Updating a package version's status
<a name="working-with-packages-update-version-status"></a>

Every package version in CodeCatalyst has a status that describes the current state and availability of the package version. You can change the package version status in the CodeCatalyst console. For more information about the possible status values of package versions and their meanings, see [Package version status](#package-version-status).

**To update a package version's status**

1. In the navigation pane, choose **Packages**.

1. On the **Package repositories** page, choose the repository that contains the package version that you want to update the status of.

1. Search and choose the package from the table.

1. On the **Package details** page, choose **Versions** and then choose the version that you want to view.

1. On the **Package version details** page, choose **Actions** and then choose **Unlist**, **Archive**, or **Dispose**. For information about each package version status, see [Package version status](#package-version-status).

1. Enter the confirmation text into the text field, and then choose **Unlist**, **Archive**, or **Dispose**, depending on which status you are updating to.

## Package version status
<a name="package-version-status"></a>

The following are possible values for package version status. You can change the package version status in the console. For more information, see [Updating a package version's status](#working-with-packages-update-version-status).
+  **Published**: The package version is successfully published and can be requested by a package manager. The package version will be included in package version lists returned to package managers; for example, in the output of `npm view <package-name> versions`. All assets of the package version are available from the repository. 
+  **Unfinished**: The last attempt to publish did not complete. Currently only Maven package versions can have a status of **Unfinished**. This can occur when the client uploads one or more assets for a package version but does not publish a `maven-metadata.xml` file for the package that includes that version. 
+  **Unlisted**: The package version assets are available for download from the repository, but the package version is not included in the list of versions returned to package managers. For example, for an npm package, the output of `npm view <package-name> versions` does not include the package version. This means that the npm dependency resolution logic does not select the package version because the version does not appear in the list of available versions. However, if the **Unlisted** package version is already referenced in an `npm package-lock.json` file, it can still be downloaded and installed; for example, when running `npm ci`. 
+  **Archived**: The package version assets cannot be downloaded. The package version will not be included in the list of versions returned to package managers. Because the assets are not available, consumption of the package version by clients is blocked. If your application build depends on a version that is updated to **Archived**, the build will fail, unless the package version has been locally cached. You can't use a package manager or build tool to republish an **Archived** package version because it is still present in the repository. However, you can change the package version status back to **Unlisted** or **Published** in the console. 
+  **Disposed**: The package version doesn't appear in listings, and the assets cannot be downloaded from the repository. The key difference between **Disposed** and **Archived** is that with a status of **Disposed**, the assets of the package version are permanently deleted by CodeCatalyst. For this reason, you cannot move a package version from **Disposed** to **Archived**, **Unlisted**, or **Published**. The package version cannot be used because the assets have been deleted. When a package version has been marked as **Disposed**, you are not billed for storage of the package assets. 

 In addition to the statuses in the preceding list, a package version can also be deleted. After it is deleted, a package version is not in the repository and you can freely republish that package version by using a package manager or build tool. 

## Package name, package version, and asset name normalization
<a name="package-name-normalization"></a>

CodeCatalyst normalizes package names, package versions, and asset names before storing them, which means the names or versions in CodeCatalyst may be different than the name or version provided when the package was published. For more information about how names and versions are normalized in CodeCatalyst for each package type, see the following documentation.
+ [Python package name normalization](python-name-normalization.md)
+ [NuGet package name, version, and asset name normalization](nuget-name-normalization.md)

CodeCatalyst does not perform normalization on other package formats.

# Editing package origin controls
<a name="package-origin-controls"></a>

In Amazon CodeCatalyst, package versions can be added to a package repository by directly publishing them, pulling them down from an upstream repository, or ingesting them from an external, public repository through a gateway. If you allow versions of a package to be added both by direct publishing and ingesting from public repositories, then you are vulnerable to a dependency substitution attack. For more information, see [Dependency substitution attacks](#dependency-substitution-attacks). To protect yourself against a dependency substitution attack, configure package origin controls on a package in a repository to limit how versions of that package can be added to the repository.

You should consider configuring package origin controls to make new versions of different packages come from both internal sources, such as direct publishing, and external sources, such as public repositories. By default, package origin controls are configured based on how the first version of a package is added to the repository.

## Package origin control settings
<a name="package-origin-control-settings"></a>

With package origin controls, you can configure how package versions can be added to a repository. The following lists include the available package origin control settings and values.

**Publish**

This setting configures whether package versions can be published directly to the repository using package managers or similar tools.
+ **ALLOW**: Package versions can be published directly.
+ **BLOCK**: Package versions cannot be published directly.

**Upstream**

This setting configures whether package versions can be ingested from external, public repositories, or retained from upstream repositories when requested by a package manager.
+ **ALLOW**: Any package version can be retained from other CodeCatalyst repositories configured as upstream repositories or ingested from a public source with an external connection.
+ **BLOCK**: Package versions cannot be retained from other CodeCatalyst repositories configured as upstream repositories or ingested from a public source with an external connection.

### Default package origin control settings
<a name="default-package-origin-control-settings"></a>

The default package origin controls for a package will be based on how the first version of that package is added to the package repository.
+ If the first package version is published direcly by a package manager, the settings will be **Publish: ALLOW** and **Upstream: BLOCK**.
+ If the first package version is ingested from a public source, the settings will be **Publish: BLOCK** and **Upstream: ALLOW**.

## Common package access control scenarios
<a name="package-origin-control-scenarios"></a>

This section describes some common scenarios of when a package version is added to a CodeCatalyst package repository. Package origin control settings are set for new packages depending on how the first package version is added.

In the following scenarios, an *internal package* is published directly from a package manager to your repository, such as a package that you maintain. An *external package* is a package that exists in a public repository that can be ingested into your repository through a gateway repository upstream.

**An external package version is published for an existing internal package**

In this scenario, consider an internal package, *packageA*. Your team publishes the first package version for *packageA* to a CodeCatalyst package repository. Because this is the first package version for that package, the package origin control settings are automatically set to **Publish: Allow** and **Upstream: Block**. After the package is published in your repository, a package with the same name is published to a public repository that is connected to your CodeCatalyst package repository. This could be an attempted dependency substitution attack against the internal package, or it could be a coincidence. Regardless, package origin controls are configured to block the ingestion of the new external version to protect themselves against a potential attack.

In the following image, *repoA* is your CodeCatalyst package repository with an upstream connection to the `npm-public-registry-gateway` repository. Your repository contains versions 1.1 and 2.1 of *packageA*, but version 3.0 is published to the public repository. Normally, *repoA* would ingest version 3.0 after the package is requested by a package manager. Because package ingestion is set to **Block**, version 3.0 is not ingested into your CodeCatalyst package repository and is not available to package managers connected to it.

![\[Simple graphic showing a new external package version being blocked from a public repository.\]](http://docs.aws.amazon.com/codecatalyst/latest/userguide/images/packages/package-origin-controls-one.png)


**An internal package version is published for an existing external package**

In this scenario, a package, *packageB*, exists externally in a public repository that you have connected to your repository. When a package manager connected to your repository requests *packageB*, the package version is ingested into your repository from the public repository. Because this is the first package version of *packageB* added to your repository, the package origin settings are configured to **Publish: BLOCK** and **Upstream: ALLOW**. Later, you try to publish a version with the same package name to the repository. You may not be aware of the public package and trying to publish an unrelated package by same name, or you may be trying to publish a patched version, or you may be trying to directly publish the exact package version that already exists externally. CodeCatalyst rejects the version that you are trying to publish, but you can explicitly override the rejection and publish the version, if necessary.

In the following image, *repoA* is your CodeCatalyst package repository with an upstream connection to the `npm-public-registry-gateway` repository. Your package repository contains version 3.0 that it ingested from the public repository. You want to publish version 1.2 to your package repository. Typically, you could publish version 1.2 to *repoA*, but because publishing is set to **Block**, version 1.2 cannot be published.

![\[Simple graphic showing package publishing blocked.\]](http://docs.aws.amazon.com/codecatalyst/latest/userguide/images/packages/package-origin-controls-two.png)


**Publishing a patched package version of an existing external package**

In this scenario, a package, *packageB*, exists externally in a public repository that you have connected to your package repository. When a package manager connected to your repository requests *packageB*, the package version is ingested into your repository from the public repository. Because this is the first package version of *packageB* added to your repository, the package origin settings are configured to **Publish: BLOCK** and **Upstream: ALLOW**. Your team decides to publish patched package versions of this package to the repository. To be able to publish package versions directly, your team changes the package origin control settings to **Publish: ALLOW** and **Upstream: BLOCK**. Versions of this package can now be published directly to your repository and ingested from public repositories. After your team publishes the patched package versions, your team reverts the package origin settings to **Publish: BLOCK** and **Upstream: ALLOW**.

## Editing package origin controls
<a name="edit-package-origin-controls"></a>

Package origin controls are configured automatically based on how the first package version of a package is added to the package repository. For more information, see [Default package origin control settings](#default-package-origin-control-settings). To add or edit package origin controls for a package in a CodeCatalyst package repository, perform the steps in the following procedure.

**To add or edit package origin controls**

1. In the navigation pane, choose **Packages**.

1. Choose the package repository that contains the package that you want to edit. 

1. In the **Packages** table, search for and choose the package that you want to edit.

1. From the package summary page, choose **Origin controls**.

1. In **Origin controls**, choose the package origin controls that you want to set for this package. Both package origin control settings, **Publish** and **Upstream**, must be set at the same time.
   + To allow publishing package versions directly, in **Publish**, choose **Allow**. To block publishing of package versions, choose **Block**.
   + To allow ingestion of packages from external repositories and pulling packages from upstream repositories, in **Upstream sources**, choose **Allow**. To block all ingestion and pulling of package versions from external and upstream repositories, choose **Block**.

1. Choose **Save**.

## Publishing and upstream repositories
<a name="package-publishing-upstreams"></a>

In CodeCatalyst, you cannot publish package versions that are present in reachable upstream repositories or public repositories. For example, suppose that you want to publish an npm package `lodash@1.0` to a repository, `myrepo`, and `myrepo` has an upstream repository with an external connection to npmjs.com. Consider the following scenarios.

1. The package origin control settings on `lodash` are **Publish: ALLOW** and **Upstream: ALLOW**. If `lodash@1.0` is present in the upstream repository or in npmjs.com, CodeCatalyst rejects any attempt to publish to it in `myrepo` by issuing a 409 conflict error. You could still publish a different version, such as `lodash@1.1`.

1. The package origin control settings on `lodash` are **Publish: ALLOW** and **Upstream: BLOCK**. You can publish any version of `lodash` to your repository that does not already exist because package versions are not reachable.

1. The package origin control settings on `lodash` are **Publish: BLOCK** and **Upstream: ALLOW**. You cannot publish any package versions directly to your repository.

## Dependency substitution attacks
<a name="dependency-substitution-attacks"></a>

Package managers simplify the process of packaging and sharing reusable code. These packages may be private packages developed by an organization for use in their applications, or they may be public, typically open-source packages that are developed outside an organization and distributed by public package repositories. When requesting packages, developers rely on their package manager to fetch new versions of their dependencies. Dependency substitution attacks, also known as dependency confusion attacks, exploit the fact that a package manager typically has no way to distinguish legitimate versions of a package from malicious versions. 

Dependency substitution attacks belong to a subset of attacks known as software supply chain attacks. A software supply chain attack is an attack that takes advantage of vulnerabilities anywhere in the software supply chain.

A dependency substitution attack can target anyone who uses both internally developed packages and packages fetched from public repositories. The attackers identify internal package names and then strategically place malicious code with the same name in public package repositories. Typically, the malicious code is published in a package with a high version number. Package managers fetch the malicious code from these public feeds because they believe that the malicious packages are the latest versions of the package. This causes a "confusion" or "substitution" between the desired package and the malicious package, which leads to the code being compromised.

To prevent dependency substitution attacks, Amazon CodeCatalyst provides package origin controls. Package origin controls are settings that control how packages can be added to your repositories. The controls are configured automatically when the first package version of a new package is added to a CodeCatalyst repository The controls can ensure package versions cannot be both published directly to your repository and ingested from public sources, protecting you from dependency substitution attacks. For more information about package origin controls and how to change them, see [Editing package origin controls](#package-origin-controls).