diff --git a/api/base.yaml b/api/base.yaml index e6217cd..fee61d0 100644 --- a/api/base.yaml +++ b/api/base.yaml @@ -19,7 +19,7 @@ tags: x-displayName: Introduction description: | This is the API documentation for the npm registry. For information about the npm registry, website, and command-line interface (CLI), please refer to [https://docs.npmjs.com](https://docs.npmjs.com). - + - name: Authentication x-displayName: Authentication & Authorization description: | @@ -27,28 +27,28 @@ tags: **Token Types:** - **1. npm Session Token (`npmSessionToken`)** + **1. npm Session Token (`npmSessionToken`)** Traditional npm session tokens created via `npm login`. These tokens: - Are tied to a user account - Inherit the user's permissions - Have limited expiration - **Required for:** User account management, token creation/management - **2. npm Access Token (`npmAccessToken`)** + **2. npm Access Token (`npmAccessToken`)** Fine-grained tokens with specific permissions: - Can be scoped to specific packages and organizations - Can be scoped to specific operations (read, write, publish) - Have configurable expiration - **Supported for:** Most package operations where explicitly documented - **3. OIDC id_token (`oidcIdToken`)** + **3. OIDC id_token (`oidcIdToken`)** Tokens from supported Identity Providers (CI/CD systems): - From GitHub Actions, GitLab CI, CircleCI, etc. - Must have `aud` claim set to `npm:registry.npmjs.org` - Short-lived tokens - **Required for:** OIDC token exchange only - **4. OIDC Exchange Token (`oidcExchangeToken`)** + **4. OIDC Exchange Token (`oidcExchangeToken`)** Short-lived tokens obtained from OIDC token exchange: - Package-scoped permissions - Limited lifetime (typically 1 hour) @@ -91,6 +91,10 @@ x-tagGroups: - Tokens - OIDC - Trust + - Access + - Org + - Team + - Search components: securitySchemes: @@ -102,12 +106,12 @@ components: description: | OIDC id_token from a supported Identity Provider (IdP) such as GitHub Actions, GitLab CI, or CircleCI. The `aud` (audience) claim must be set to `npm:registry.npmjs.org`. - + **Supported Identity Providers:** - GitHub Actions - GitLab CI - CircleCI - + # Traditional npm user access tokens npmSessionToken: type: http @@ -115,7 +119,7 @@ components: description: | Traditional npm session token created via `npm login`. These tokens are tied to a user account and inherit the user's permissions. - + # Granular Access Tokens (GAT) - fine-grained tokens with specific permissions npmAccessToken: type: http @@ -123,7 +127,7 @@ components: description: | Granular Access Token (GAT) with fine-grained permissions. These tokens can be scoped to specific packages and operations. - + # Alias for npmAccessToken - for backward compatibility granularAccessToken: type: http @@ -132,7 +136,7 @@ components: Granular Access Token (GAT) with fine-grained permissions. These tokens can be scoped to specific packages and operations. (Alias for npmAccessToken) - + # Short-lived tokens obtained from OIDC token exchange oidcExchangeToken: type: http @@ -141,4 +145,4 @@ components: Short-lived npm registry token obtained by exchanging an OIDC id_token via the `/oidc/token/exchange` endpoint. These tokens are package-scoped and have limited lifetime (typically 1 hour). - \ No newline at end of file + diff --git a/api/merge-config.yaml b/api/merge-config.yaml index 75667d8..17cc03a 100644 --- a/api/merge-config.yaml +++ b/api/merge-config.yaml @@ -1,6 +1,10 @@ inputs: - inputFile: base.yaml + - inputFile: registry.npmjs.com/access.yaml - inputFile: registry.npmjs.com/oidc.yaml + - inputFile: registry.npmjs.com/org.yaml + - inputFile: registry.npmjs.com/search.yaml + - inputFile: registry.npmjs.com/team.yaml - inputFile: registry.npmjs.com/token.yaml - inputFile: registry.npmjs.com/trust.yaml diff --git a/api/registry.npmjs.com/access.yaml b/api/registry.npmjs.com/access.yaml new file mode 100644 index 0000000..b9f2373 --- /dev/null +++ b/api/registry.npmjs.com/access.yaml @@ -0,0 +1,178 @@ +components: + responses: + PackageAccessLevels: + description: 'Packages with their access levels' + content: + application/json: + schema: + type: object + additionalProperties: + type: string + example: + '@npmcli/arborist': read-write + '@npmcli/config': read-only + PackageVisibility: + description: 'Packages with their visibility' + content: + application/json: + schema: + type: object + additionalProperties: + type: string + example: + '@npmcli/arborist': public + '@npmcli/hidden': private + UserAccessLevels: + description: User access levels + content: + application/json: + schema: + type: object + additionalProperties: + type: string + example: + npm: read-write + microsoft: read-only +paths: + /-/team/{orgName}/{teamName}/package: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/OrgName' + - $ref: './api/shared-components.yaml#/components/parameters/TeamName' + - $ref: './api/shared-components.yaml#/components/parameters/RequiredBearerToken' + get: + tags: + - Access + summary: Get all packages for a team + description: Get all of the packages a team has access to, as well as the access level that team has for each package. + operationId: getTeamPackageGrants + security: + - npmSessionToken: [] + responses: + '200': + $ref: '#/components/responses/PackageAccessLevels' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + put: + tags: + - Access + summary: Grant access to a package for a team + operationId: createTeamPackageGrant + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + package: + type: string + description: The name of the package to give access to + permissions: + type: string + enum: + - read-only + - read-write + description: The access level of the package to grant to the team + security: + - npmSessionToken: [] + responses: + '201': + $ref: './api/shared-components.yaml#/components/responses/EmptySuccess' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + delete: + tags: + - Access + summary: Remove access to a package for a team + operationId: deleteTeamPackageGrant + security: + - npmSessionToken: [] + responses: + '204': + $ref: './api/shared-components.yaml#/components/responses/EmptySuccess' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + /-/org/{orgName}/package: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/OrgName' + - $ref: './api/shared-components.yaml#/components/parameters/RequiredBearerToken' + get: + tags: + - Access + summary: Get all packages for an org + description: Get all of the packages an org has access to, as well a the access level that org has for each pacakge. + operationId: getOrgPackages + security: + - npmSessionToken: [] + responses: + '200': + $ref: '#/components/responses/PackageAccessLevels' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + /-/package/{escapedPackageName}/collaborators: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/EscapedPackageName' + - $ref: './api/shared-components.yaml#/components/parameters/RequiredBearerToken' + get: + tags: + - Access + summary: Get all of the users that have access to a package, as well as the access level that user has for each package. + operationId: getPackageCollaborators + security: + - npmSessionToken: [] + responses: + '200': + $ref: '#/components/responses/UserAccessLevels' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + /-/package/{escapedPackageName}/visibility: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/EscapedPackageName' + - $ref: './api/shared-components.yaml#/components/parameters/RequiredBearerToken' + get: + tags: + - Access + summary: Get the visibility of a package. + operationId: getPackageVisibility + security: + - npmSessionToken: [] + responses: + '200': + $ref: '#/components/responses/PackageVisibility' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + /-/package/{escapedPackageName}/access: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/EscapedPackageName' + post: + tags: + - Access + summary: Sets the various access levels for a package. + operationId: setPackageAccess + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + # cidr_whitelist? + access: + type: string + enum: + - public + - private + description: Visibility of a package + publish_requires_tfa: + type: boolean + description: Whether publishing this package requires multifactor auth + automation_token_overrides_tfa: + type: boolean + description: Whether or not automation tokens override the requirement for multifactor auth + security: + - npmSessionToken: [] + responses: + '200': + $ref: './api/shared-components.yaml#/components/responses/EmptySuccess' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' diff --git a/api/registry.npmjs.com/org.yaml b/api/registry.npmjs.com/org.yaml new file mode 100644 index 0000000..9503fd2 --- /dev/null +++ b/api/registry.npmjs.com/org.yaml @@ -0,0 +1,111 @@ +components: + responses: + OrgMembers: + description: "Org members with their access levels" + content: + application/json: + schema: + type: object + additionalProperties: + type: string + example: + "npm": "owner" + "npm-cli-bot": "developer" + OrgInvite: + description: "Confirmation about the org membership or invite that was generated" + headers: + npm-notice: + description: Additional info about the invite sent to the user + schema: + type: string + content: + application/json: + schema: + type: object + properties: + org: + type: object + properties: + name: + type: string + description: The name of the org + size: + type: string + description: current size of the org, including invites + user: + type: string + description: The username that was invited or edited + role: + type: string + description: The role that the user was given in the org +paths: + /-/org/{orgName}/user: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/OrgName' + - $ref: "./api/shared-components.yaml#/components/parameters/RequiredBearerToken" + get: + tags: + - Org + summary: Get users in an org + description: Get all of the users in an org, along with their access levels in that org + operationId: getOrgMembership + security: + - npmSessionToken: [] + responses: + "200": + $ref: '#/components/responses/OrgMembers' + "401": + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + put: + tags: + - Org + summary: Set user membership in an org + description: Set a user's membership in an org. If the user is not already a member, an invite will be sent. + operationId: changeOrgMembership + security: + - npmSessionToken: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + user: + type: string + description: Username to grant membership to org + role: + type: string + enum: + - developer + - admin + - owner + description: Role to give user in org + responses: + "201": + $ref: '#/components/responses/OrgInvite' + "401": + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + delete: + tags: + - Org + summary: Remove user membership in an org + description: Remove a user's membership in an org + operationId: deleteOrgMembership + security: + - npmSessionToken: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + user: + type: string + description: Username to remove from the org + responses: + "204": + $ref: './api/shared-components.yaml#/components/responses/EmptySuccess' + "401": + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' diff --git a/api/registry.npmjs.com/search.yaml b/api/registry.npmjs.com/search.yaml new file mode 100644 index 0000000..46ce1a1 --- /dev/null +++ b/api/registry.npmjs.com/search.yaml @@ -0,0 +1,159 @@ +components: + responses: + MissingField: + description: A required parameter was missing + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: Message explaining what was missing from the request + code: + type: string + description: Error code for this response + SearchResults: + description: Search results + content: + application/json: + schema: + type: object + properties: + objects: + type: array + items: + type: object + properties: + downloads: + type: object + properties: + monthly: + type: number + description: Download count for this package in the last month + weekly: + type: number + description: Download count for this package in the last week + dependents: + type: number + description: The number of packages that list this package as a dependency + updated: + type: string + format: date-time + description: When the package was last updated + searchScore: + type: number + description: Search score of this result, same as score.final + package: + type: object + properties: + name: + type: string + description: The name of the package + keywords: + type: array + items: + type: string + description: A keyword associated with this package + version: + type: string + description: The latest version of this package. + description: + type: string + description: The description of this package from its package.json + sanitized_name: + type: string + description: The name of the package with some characters changed to help with indexing + publisher: + type: object + properties: + username: + type: string + email: + type: string + description: Information about the user that published the latest version of this package + maintainers: + type: array + items: + type: object + properties: + username: + type: string + email: + type: string + description: Information about the users who own this package + license: + type: string + description: SPDX license for this package + date: + type: string + format: date-time + description: Timestamp of when the latest version of this package was published + links: + type: object + properties: + homepage: + type: string + description: The main homepage for this package + repository: + type: string + description: The repository for this package's source code + bugs: + type: string + description: Where to report bugs for this package + npm: + type: string + description: This package's main page on the npm website + score: + type: object + properties: + final: + type: number + description: Search score of this result, same as searchScore + detail: + type: object + description: Legacy "pqm" values of this result. These are hard coded and left in for legacy purposes, all set to "1" + flags: + type: object + properties: + insecure: + type: number + description: Legacy attribute. Always set to 0. + total: + type: number + description: The total number of items in the search results + time: + type: string + format: date-time + description: The current time +paths: + /-/v1/search: + get: + parameters: + - name: text + in: query + required: true + schema: + type: string + description: The search query text + - name: size + in: query + schema: + type: number + description: The number of search results to return + - name: from + in: query + schema: + type: number + description: The starting index of the search results + tags: + - Search + summary: Search for packages on the registry + description: Search for packages on the registry + operationId: getsearch + security: [] + responses: + '200': + $ref: '#/components/responses/SearchResults' + '400': + $ref: '#/components/responses/MissingField' diff --git a/api/registry.npmjs.com/team.yaml b/api/registry.npmjs.com/team.yaml new file mode 100644 index 0000000..e036cf2 --- /dev/null +++ b/api/registry.npmjs.com/team.yaml @@ -0,0 +1,166 @@ +components: + responses: + TeamUsers: + description: The users in a team + content: + application/json: + schema: + type: array + items: + type: string + description: A username of a user in the team + example: + - npm + - npm-cli-bot + OrgTeams: + description: The teams in an org + content: + application/json: + schema: + type: array + items: + type: string + description: The teams in the org, in the format of orgname:teamname + example: + - '@npmcli:wombats' + +paths: + /-/org/{orgName}/team: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/OrgName' + - $ref: './api/shared-components.yaml#/components/parameters/RequiredBearerToken' + get: + tags: + - Org + summary: Get teams in an org + description: Get all of the teams in an org + operationId: getScopeTeams + security: + - npmSessionToken: [] + responses: + '200': + $ref: '#/components/responses/OrgTeams' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + put: + tags: + - Team + summary: Create a new team + description: Create a new team for an org + operationId: putScopeTeam + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: The name of the team to create + description: + type: string + description: The description of the team to create + example: { name: 'wombats', description: 'All developers' } + security: + - npmSessionToken: [] + responses: + '201': + description: Team was created successfully + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: The name of the team that was created + example: + name: wombats + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + /-/org/{orgName}/{teamName}: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/OrgName' + - $ref: './api/shared-components.yaml#/components/parameters/TeamName' + - $ref: './api/shared-components.yaml#/components/parameters/RequiredBearerToken' + delete: + tags: + - Team + summary: Delete a team + description: Delete a team from a given org + operationId: deleteTeam + security: + - npmSessionToken: [] + responses: + '204': + $ref: './api/shared-components.yaml#/components/responses/EmptySuccess' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + /-/org/{orgName}/{teamName}/user: + parameters: + - $ref: './api/shared-components.yaml#/components/parameters/OrgName' + - $ref: './api/shared-components.yaml#/components/parameters/TeamName' + - $ref: './api/shared-components.yaml#/components/parameters/RequiredBearerToken' + get: + tags: + - Team + summary: Get all users in a team + description: Get all users in a team + operationId: getTeamMembership + security: + - npmSessionToken: [] + responses: + '200': + $ref: '#/components/responses/TeamUsers' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + put: + tags: + - Team + summary: Add a user to a team + description: Add a user to a team in an org. The user must already be a member of the org. + operationId: createTeamMembership + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + user: + type: string + description: The username of the user to add to the team + example: + user: npm-cli-bot + security: + - npmSessionToken: [] + responses: + '201': + $ref: './api/shared-components.yaml#/components/responses/EmptySuccess' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' + delete: + tags: + - Team + summary: Remove a user from a team + operationId: deleteTeamMembership + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + user: + type: string + description: The username of the user to remove from the team + example: + user: npm-cli-bot + security: + - npmSessionToken: [] + responses: + '204': + $ref: './api/shared-components.yaml#/components/responses/EmptySuccess' + '401': + $ref: './api/shared-components.yaml#/components/responses/Unauthorized' diff --git a/api/registry.npmjs.com/token.yaml b/api/registry.npmjs.com/token.yaml index ef5617f..9a72410 100644 --- a/api/registry.npmjs.com/token.yaml +++ b/api/registry.npmjs.com/token.yaml @@ -7,14 +7,14 @@ paths: description: | Create a new npm access token with customizable permissions, scope restrictions, expiration, and CIDR IP range limitations. - + **Requirements:** - Must be authenticated - **Two-factor authentication is required for this endpoint** - If 2FA is enabled on your account, provide the OTP via the `npm-otp` header - If 2FA is not enabled, an email OTP will be sent and must be provided via the `npm-otp` header - For WebAuthn users, the OTP is returned in the `doneUrl` after authentication - + **Important notices:** - All responses include security notices via the `npm-notice` header regarding token limitations operationId: createToken @@ -27,9 +27,9 @@ paths: pattern: '^Bearer .+' description: | Bearer token for authentication. Must be an npm access token. - + **Format:** `Bearer ` - + **Accepted token types:** - npm access token (traditional user token created via `npm login`) - name: npm-otp @@ -39,7 +39,7 @@ paths: type: string description: | One-time password for two-factor authentication. Always required for this endpoint. - + **How to obtain the OTP:** - If 2FA is enabled on your account, provide the OTP from your configured 2FA method - If 2FA is not enabled, an email OTP will be sent and must be provided (format: `<8-digit-otp-from-email>`) @@ -275,17 +275,17 @@ paths: properties: error: type: string - + get: tags: - Tokens summary: List npm access tokens description: | List all access tokens associated with the authenticated user's account. - + **Requirements:** - Must be authenticated with a valid Bearer token - + **Response includes:** - All responses include security notices via the `npm-notice` header - Tokens are redacted for security: format is `npm_aBcD...7890` (first 8 chars including prefix + ... + last 4 chars) @@ -300,7 +300,7 @@ paths: pattern: '^Bearer .+' description: | Bearer token for authentication. Must be an npm access token. - + **Format:** `Bearer ` - name: page in: query @@ -379,7 +379,7 @@ paths: type: string format: date-time description: Timestamp when the token was last updated - accessed: + accessed: type: string format: date-time description: Timestamp when the token was last accessed @@ -443,7 +443,7 @@ paths: properties: message: type: string - + /-/npm/v1/tokens/token/{token}: delete: tags: @@ -453,11 +453,11 @@ paths: Delete an npm access token. The token can be specified as: - A UUID (token identifier) - An npm-prefixed token (format: `npm_` followed by 36 alphanumeric characters) - + **Requirements:** - Must be authenticated with a valid Bearer token - May require 2FA OTP depending on user settings - + **Web authentication flow:** - When `npm-auth-type=web` and `npm-command=token` headers are present and 2FA is required, returns authentication URLs instead of an error @@ -480,7 +480,7 @@ paths: pattern: '^Bearer .+' description: | Bearer token for authentication. Must be an npm access token. - + **Format:** `Bearer ` - name: npm-otp in: header @@ -579,7 +579,7 @@ paths: summary: "Invalid OTP provided" value: error: "invalid OTP" - webAuthFlow: + web_auth_flow: summary: "Web authentication flow (2FA required)" description: | When user has 2FA enabled and includes both `npm-auth-type=web` and `npm-command=token` headers. @@ -617,7 +617,7 @@ components: 2. **No 2FA enabled + npm-otp header omitted**: Returns error requesting email OTP. An email is automatically sent to the user's registered email address 3. **2FA enabled + npm-otp header omitted (legacy flow)**: Returns 2FA error with npm-notice header containing WebAuthn URL. This is for older CLI versions without web auth support 4. **2FA enabled + npm-otp header omitted (web auth flow)**: Returns authentication URLs (authUrl and doneUrl) when both npm-auth-type=web and npm-command=token headers are present - + headers: npm-notice: description: | @@ -659,7 +659,7 @@ components: summary: "No 2FA enabled + npm-otp header omitted" description: | When user has no 2FA enabled and omits the `npm-otp` header. - + An email OTP is automatically sent to the user's registered email address. The user should check their email and retry the request with the received OTP. value: @@ -668,7 +668,7 @@ components: summary: "2FA enabled + npm-otp header omitted (legacy flow)" description: | When user has 2FA enabled, omits the `npm-otp` header, and doesn't include web auth headers. This is a legacy notice supported in older versions of the CLI without support for `npm-auth-type=web`. - + **Response includes npm-notice header:** > `npm-notice: Open https://www.npmjs.com/login/ to use your security key for authentication` @@ -680,4 +680,4 @@ components: When user has 2FA enabled, omits the `npm-otp` header, and includes both `npm-auth-type=web` and `npm-command=token` headers. value: authUrl: "https://www.npmjs.com/auth/cli/00000000-0000-0000-0000-000000000000" - doneUrl: "https://registry.npmjs.org/-/v1/done?authId=00000000-0000-0000-0000-000000000000" \ No newline at end of file + doneUrl: "https://registry.npmjs.org/-/v1/done?authId=00000000-0000-0000-0000-000000000000" diff --git a/api/registry.npmjs.com/trust.yaml b/api/registry.npmjs.com/trust.yaml index 295577f..adac647 100644 --- a/api/registry.npmjs.com/trust.yaml +++ b/api/registry.npmjs.com/trust.yaml @@ -6,15 +6,15 @@ paths: summary: Get all trusted publisher configurations for package description: | Retrieve all trusted publisher configurations for a package. - + This endpoint allows users with write permission to the package to view all existing trusted publisher configurations that have been set up for OIDC token exchange for their package. - + ## Configuration Structure - - The structure of the payload follows a specific design. Each trusted provider has their own unique set of claims. - In order to keep things clear and consistent, the properties to create a provider match the claims structure. - The caveat is when a claim requires partial matching through parsing. + + The structure of the payload follows a specific design. Each trusted provider has their own unique set of claims. + In order to keep things clear and consistent, the properties to create a provider match the claims structure. + The caveat is when a claim requires partial matching through parsing. - All configurations MUST include a `type` and `claims` object - Top-level "claims" MUST match the cloud provider's exact claim properties @@ -22,7 +22,7 @@ paths: - Claims MAY use an object structure to define one or multiple partial matching rules - Partial matching properties MUST be defined and documented by this API specification - This documentation SHALL only provide matches for specifically defined claim items - + ## Requirements - Package MUST exist - User MUST have write permission to the package @@ -45,10 +45,10 @@ paths: pattern: '^Bearer .+' description: | Authentication header. Supports both Bearer authentication. - + **Formats:** - `Bearer ` - npm access token or granular access token - + **Accepted token types:** - npm access token (traditional user token) - name: npm-otp @@ -125,6 +125,7 @@ paths: properties: message: type: string + required: [message] - type: object description: Web authentication flow response properties: @@ -163,11 +164,11 @@ paths: examples: 2fa_disabled: summary: "Please enable 2fa for your account" - value: + value: message: "Please enable 2fa for your account" insufficient_permissions: summary: "Insufficient permissions to view configurations" - value: + value: message: "Insufficient permissions to access trusted publisher configurations for this package" "404": description: Package not found @@ -181,7 +182,7 @@ paths: examples: package_not_found: summary: "Package not found" - value: + value: message: "Package not found" post: tags: @@ -189,11 +190,11 @@ paths: summary: Add trusted publisher configuration for package description: | Configure trusted publisher settings for a package to enable OIDC token exchange. - + This endpoint allows users with write permission to the package to establish trust with CI/CD providers (GitHub Actions, GitLab CI, CircleCI, etc.) so that those services can publish to the package without requiring long-lived npm tokens. - + ## Requirements - Package MUST exist - User MUST have write permission to the package @@ -216,10 +217,10 @@ paths: pattern: '^Bearer .+' description: | Authentication header. Supports both Bearer authentication. - + **Formats:** - `Bearer ` - npm access token or granular access token - + **Accepted token types:** - npm access token (traditional user token) - name: npm-otp @@ -322,7 +323,7 @@ paths: examples: invalid_config: summary: "Invalid trusted publisher configuration" - value: + value: message: "Invalid trusted publisher configuration" "401": description: Unauthorized - missing or invalid authentication / OTP @@ -343,6 +344,7 @@ paths: properties: message: type: string + required: [message] - type: object description: Web authentication flow response properties: @@ -360,7 +362,7 @@ paths: summary: "No Authorization header provided" description: | When no Authorization header is provided or the token is invalid. - value: + value: message: "Unauthorized" web_auth_flow: summary: "2FA enabled + npm-otp header omitted (web auth flow)" @@ -381,7 +383,7 @@ paths: examples: 2fa_disabled: summary: "Please enable 2fa for your account" - value: + value: message: "Please enable 2fa for your account" "404": description: Package not found @@ -395,7 +397,7 @@ paths: examples: package_not_found: summary: "Package not found" - value: + value: message: "Package not found" "409": description: Conflict - Configuration already exists @@ -409,7 +411,7 @@ paths: examples: config_limit_reached: summary: "Config already exists" - value: + value: message: "trusted publisher config already exists for the package. Please delete and re-create." /-/package/{package}/trust/{config-uuid}: delete: @@ -418,10 +420,10 @@ paths: summary: Delete trusted publisher configuration description: | Delete a specific trusted publisher configuration for a package by its UUID. - + This endpoint allows users with write permission to the package to remove an existing trusted publisher configuration that was previously set up for OIDC token exchange. - + ## Requirements - Package MUST exist - User MUST have write permission to the package @@ -451,10 +453,10 @@ paths: pattern: '^Bearer .+' description: | Authentication header. Supports both Bearer authentication. - + **Formats:** - `Bearer ` - npm access token or granular access token - + **Accepted token types:** - npm access token (traditional user token) - name: npm-otp @@ -485,7 +487,7 @@ paths: examples: invalid_uuid: summary: "Invalid UUID format" - value: + value: message: "Invalid trusted publisher config id format" "401": description: Unauthorized - missing or invalid authentication / OTP @@ -506,6 +508,7 @@ paths: properties: message: type: string + required: [message] - type: object description: Web authentication flow response properties: @@ -523,7 +526,7 @@ paths: summary: "No Authorization header provided" description: | When no Authorization header is provided or the token is invalid. - value: + value: message: "Unauthorized" web_auth_flow: summary: "2FA enabled + npm-otp header omitted (web auth flow)" @@ -544,11 +547,11 @@ paths: examples: 2fa_disabled: summary: "Please enable 2fa for your account" - value: + value: message: "Please enable 2fa for your account" insufficient_permissions: summary: "Insufficient permissions to delete configuration" - value: + value: message: "Insufficient permissions to access trusted publisher config for the package" "404": description: Package or configuration not found @@ -562,11 +565,11 @@ paths: examples: package_not_found: summary: "Package not found" - value: + value: message: "Package not found" config_not_found: summary: "Configuration not found" - value: + value: message: "Trusted publisher configuration not found for the package" components: @@ -579,7 +582,7 @@ components: - $ref: '#/components/schemas/GitHubActionsConfig' - $ref: '#/components/schemas/GitLabPipelinesConfig' - $ref: '#/components/schemas/CircleCIConfig' - + OidcConfigsCreate: type: array description: Array of OIDC trusted publisher configurations to create @@ -588,7 +591,7 @@ components: - $ref: '#/components/schemas/GitHubActionsConfigCreate' - $ref: '#/components/schemas/GitLabPipelinesConfigCreate' - $ref: '#/components/schemas/CircleCIConfigCreate' - + GitHubActionsConfig: type: object required: @@ -629,7 +632,7 @@ components: type: string description: GitHub environment name example: production - + GitHubActionsConfigCreate: type: object required: @@ -665,7 +668,7 @@ components: type: string description: GitHub environment name example: production - + GitLabPipelinesConfig: type: object required: @@ -706,7 +709,7 @@ components: type: string description: GitLab environment name example: production - + CircleCIConfig: type: object required: diff --git a/api/shared-components.yaml b/api/shared-components.yaml new file mode 100644 index 0000000..4225329 --- /dev/null +++ b/api/shared-components.yaml @@ -0,0 +1,67 @@ +components: + parameters: + EscapedPackageName: + name: escapedPackageName + in: path + required: true + schema: + type: string + description: The name of a package. Scoped packages need "/" to be url encoded to "%2F" + example: '@npmcli%2Farborist' + OrgName: + name: orgName + in: path + required: true + schema: + type: string + description: Name of an org + TeamName: + name: teamName + in: path + required: true + schema: + type: string + description: Name of a team + RequiredBearerToken: + name: Authorization + in: header + required: true + schema: + type: string + pattern: '^Bearer .+' + description: | + Bearer token for authentication. Must be an npm access token. + + **Format:** `Bearer ` + + **Accepted token types:** + - npm access token (traditional user token created via `npm login`) + responses: + EmptySuccess: + description: Success + content: + '*/*': + schema: + not: + {} + Unauthorized: + description: Unauthorized + headers: + www-authenticate: + description: Authentication challenge (e.g., "OTP" when OTP is required) + schema: + type: string + npm-notice: + description: Additional notice information + schema: + type: string + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: Error message + example: + error: Missing "Bearer" header.