Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ tags:
**Granular Access Tokens with `bypass_2fa`:**

Granular Access Tokens (GATs) created with `bypass_2fa: true` are
allowed to perform automation flows such as direct publish, but they
allowed to perform automation flows within their scopes and publish policy, but they
are **not** permitted to perform account-identity or governance write
operations. Requests to those endpoints authenticated with a
bypass-2FA GAT are rejected with `403 Forbidden` and must instead be
Expand All @@ -91,7 +91,7 @@ tags:
`PUT`/`DELETE /-/team/{orgName}/{teamName}/package`

Direct publish (`PUT /{escapedPackageName}`) remains functional for
bypass-2FA GATs.
direct-capable bypass-2FA GATs. It is not permitted for stage-only GATs.

- name: Tokens
x-displayName: Tokens
Expand Down
13 changes: 13 additions & 0 deletions api/registry.npmjs.com/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ paths:
tags:
- Publish
summary: Publish a new version of a package
description: |
Publish a new package version directly to the registry.

Stage-only Granular Access Tokens cannot publish new versions through this
endpoint, even with `bypass_2fa: true`. Requests rejected by the publish-policy
check return `403 Forbidden` with `E_STAGE_REQUIRED` in the error message.
Earlier authentication or package authorization checks can return other errors,
including `404 Not Found`. Rejected requests are not automatically redirected
to staging. Use `POST /-/stage/package/{package-name}`
(`npm stage publish`), followed by maintainer approval with 2FA.

The stage-only policy restricts new-version publication. Existing authorization
and 2FA requirements still apply.
operationId: publish
requestBody:
required: true
Expand Down
52 changes: 46 additions & 6 deletions api/registry.npmjs.com/token.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ paths:
Create a new npm access token with customizable permissions, scope restrictions,
expiration, and CIDR IP range limitations.

To create a stage-only Granular Access Token (GAT), set
`packages_and_scopes_permission` to `read-write-stage-only` and select
at least one package or scope. This grants package write access but
restricts publishing new versions to `POST /-/stage/package/{package-name}`
(`npm stage publish`). Direct publication is not allowed or automatically staged.
Requests rejected by the publish-policy check return `403 Forbidden` with
`E_STAGE_REQUIRED` in the error message. Earlier authentication or package
authorization checks can return other errors, including `404 Not Found`.
A maintainer must approve the staged version with 2FA before publication.
Stage-only is not a valid value for `orgs_permission`.

The publish restriction is separate from `bypass_2fa`. Stage-only tokens
can be created with either setting, and existing scope, permission, and
2FA checks still apply to all operations. The restriction does not itself
remove other package write capabilities, such as changing dist-tags or
deprecating versions.

**Requirements:**
- Must be authenticated
- **Two-factor authentication is required for this endpoint**
Expand Down Expand Up @@ -86,12 +103,14 @@ paths:
oneOf:
- type: number
- type: string
description: 'Expiration in days (number) or ISO date string. Read-write tokens: maximum 90 days, defaults to 7 days. Read-only tokens: unlimited maximum, defaults to 30 days'
description: 'Expiration in days (number) or ISO date string. Read-write tokens, including read-write-stage-only: maximum 90 days, defaults to 7 days. Read-only tokens: unlimited maximum, defaults to 30 days'
bypass_2fa:
type: boolean
description: |
Allow token to bypass 2FA requirements for automation
flows such as direct publish.
flows permitted by its package permissions and publish policy.
This does not allow a stage-only token to publish directly or
bypass the 2FA challenge when approving a staged version.

Tokens created with `bypass_2fa: true` **cannot** perform
account, token, or org/team/package governance write
Expand Down Expand Up @@ -125,15 +144,35 @@ paths:
description: Organizations this token can access. Empty arrays are treated as not provided
packages_and_scopes_permission:
type: string
enum: ["read-only", "read-write", "no-access"]
description: Permission for packages and scopes. Defaults to "read-only" if packages/scopes arrays have length > 0, otherwise "no-access"
enum: ["read-only", "read-write", "read-write-stage-only", "no-access"]
description: |
Permission for packages and scopes. Defaults to "read-only" if
packages/scopes arrays have length > 0, otherwise "no-access".

- `read-only`: read package data.
- `read-write`: package write access, including direct and staged publishing.
- `read-write-stage-only`: package write access with new versions restricted
to staged publishing and subsequent maintainer approval with 2FA.
- `no-access`: no package or scope permissions.

orgs_permission:
type: string
enum: ["read-only", "read-write", "no-access"]
description: Permission for organizations. Defaults to "read-only" if orgs array has length > 0, otherwise "no-access"
required:
- password
- name
examples:
stageOnly:
summary: Stage-only GAT for an existing package
value:
password: '<your npm password>'
name: 'staged-release-ci'
packages: ['@myorg/release-tools']
packages_and_scopes_permission: 'read-write-stage-only'
orgs_permission: 'no-access'
expires: 7
bypass_2fa: true
security:
- npmSessionToken: []
- npmAccessToken: []
Expand Down Expand Up @@ -216,7 +255,8 @@ paths:
action:
type: string
description: Permission action ("read" or "write").
description: List of permissions granted to this token.
description: |
List of permissions granted to this token.
scopes:
type: array
items:
Expand Down Expand Up @@ -258,7 +298,7 @@ paths:
invalidPackagesPermission:
summary: Invalid packages_and_scopes_permission value
value:
error: 'Invalid packages_and_scopes_permission. Must be one of: no-access, read-only, read-write'
error: 'Invalid packages_and_scopes_permission. Must be one of: no-access, read-only, read-write, read-write-stage-only'
invalidOrgsPermission:
summary: Invalid orgs_permission value
value:
Expand Down
Loading