Skip to content

Draft: Protected npm package in package registry [POC]

What does this MR do and why?

This MR will not be merged. The intention is to discuss and document design decision and implemenation details.

This MR wants to provide a POC implementation for the Identify packages as protected to prevent accid... (&5574).

What do we want to achieve with this POC?

  • Better understanding of implementation approach and complexity
  • Better estimate of implementation plan
  • Discuss the data model

What do we not want to achieve with this POC?

  • Discuss necessary ux / ui changes in regards to the project settings
  • Investigate the implemenation of dependency types other than npm

🛠 with at Siemens

Proposal for data model

  • We want to maintain the current permissions for interacting with the package registry => therefore, the idea of Packages::PackageProtectionPolicy is to define additional permissions => hence, we do not need to migrate the existing data model
  • When a pacakge-specific Packages::PackageProtectionPolicy exists then this policy is enforced,
  • When no package-specific Packages::PackageProtectionPolicy exists then the default package permissions are applied => this ensures backward compatibility
  • The field publish_protected_up_to_access_level represent the maximum access level required to allow publishing of a package, e.g. maintainer, owner, Gitlab::ACCESS::NO_ACCESS, etc.
  • The field matching_package_name has a uniqueness contraint scoped to project_id and namespace_id => could be extended to the fields matching_package_type and matching_package_version as well
classDiagram
  class `Packages::PackageProtectionPolicy`{
    id bigint,
    matching_package_name string
    matching_package_type string
    matching_package_version string
    publish_protected_up_to_access_level Gitlab::Access
    unpublish_protected_up_to_access_level Gitlab::Access
    project_id bigint 
    namespace_id bigint
  }

  `Packages::PackageProtectionPolicy` --> `Project`
  `Project` --> `Group (Namespace)`

Here is an example of the

project_id namespace_id matching_package_name. publish_protected_up_to_access_level Meaning
7 33 "@flightjs/test-npm-package" 0 (= Gitlab::Access::NO_ACCESS) New package version for @flightjs/test-npm-package cannot be published because this PackageProtectionPolicy forbids this.
7 33 "@flightjs/test-npm-package-2 " 40 (= Gitlab::Access::MAINTAINER) New package version for @flightjs/test-npm-package cannot be published by a MAINTAINER or lower. OWNER would be able to publish a new package version.

Open Questions

  • Should we allow wildcard for matching_package_name?

How to set up and validate locally

  1. rails db:migrate
  2. rails r 'Packages::PackageProtectionPolicy.create(project: Project.find(7), namespace: Project.find(7).namespace, matching_package_name: "@flightjs/test-npm-package", publish_protected_up_to_access_level: Gitlab::Access::NO_ACCESS, unpublish_protected_up_to_access_level: Gitlab::Access::NO_ACCESS)'
  3. Create a dummy project for npm package for testing publishing, i.e. npm init
  4. Publish npm test package, i.e. NPM_TOKEN=ypCa3Dzb23o5nvsixwPA npm publish => will be blocked by PackageProtectionPolicy

TODO

  • Document data proposal in &5574
  • Document implementation plan in &5574
  • Add matching_package_type to PackageProtectionPolicy

MR acceptance checklist

This MR will not be merged. The intention is to discuss and document design decision and implemenation details.

Related to Identify packages as protected to prevent accid... (&5574) and.

Edited by Gerardo Navarro

Merge request reports