Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 2 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,6 @@ jobs:
exit 1
fi

- name: Check npm token
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "$NODE_AUTH_TOKEN" ]; then
echo "NPM_TOKEN secret is required to publish the npm package."
exit 1
fi

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v7
with:
Expand All @@ -69,11 +60,10 @@ jobs:
with:
node-version: '24'
registry-url: https://registry.npmjs.org
package-manager-cache: false

- name: Publish npm package
working-directory: npm
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
node scripts/set-version.js "$GITHUB_REF_NAME"
npm publish --access public --provenance
npm publish --access public
Comment on lines 67 to +69

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the release workflow around the referenced lines
git ls-files .github/workflows/release.yml
echo '---'
cat -n .github/workflows/release.yml | sed -n '1,160p'

echo '--- search provenance usage ---'
rg -n --hidden --glob '.github/workflows/*.yml' --glob '.github/workflows/*.yaml' 'provenance|npm publish|id-token|permissions:' .github/workflows

Repository: go-tapd/cli

Length of output: 2532


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find any repo docs/config mentioning npm provenance or trusted publishing
rg -n --hidden 'provenance|trusted publishing|trusted-publishing|OIDC|id-token|npm publish' .

Repository: go-tapd/cli

Length of output: 1076


Restore --provenance on npm publish. .github/workflows/release.yml:69 already uses GitHub OIDC (id-token: write), so dropping --provenance stops emitting provenance for released packages.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 67 - 69, The release workflow’s
npm publish step is missing provenance even though it already has GitHub OIDC
enabled. Update the publish command in the release job to restore the provenance
flag on the npm publish invocation, and verify the change in the workflow
section that runs set-version and publishes the package.

80 changes: 34 additions & 46 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,24 @@ make lint
make test
```

## Release Secrets
## Release Credentials

The release workflow publishes three outputs when a `v*` tag is pushed:

- GitHub Release assets, using the repository `GITHUB_TOKEN`
- Homebrew formula updates, using `TAP_GITHUB_TOKEN`
- npm package updates, using `NPM_TOKEN`
- npm package updates, using npm Trusted Publishing with GitHub Actions OIDC

`GITHUB_TOKEN` is created automatically by GitHub Actions. The other two tokens
must be created manually and saved as repository secrets in `go-tapd/cli`.
`GITHUB_TOKEN` is created automatically by GitHub Actions. `TAP_GITHUB_TOKEN`
must be created manually and saved as a repository secret in `go-tapd/cli`.
npm publishing does not use a long-lived repository secret; it depends on a
trusted publisher configuration on npmjs.com.

### Required Secrets
### Required Repository Secrets

| Secret | Used for | Minimum access |
| --- | --- | --- |
| `TAP_GITHUB_TOKEN` | Commit the generated Homebrew formula to `go-tapd/homebrew-tap` | GitHub fine-grained personal access token with `Contents: Read and write` on `go-tapd/homebrew-tap` |
| `NPM_TOKEN` | Publish `@go-tapd/tapd` to npm | npm granular access token with `Read and write` access to the `@go-tapd` package scope |

### Configure `TAP_GITHUB_TOKEN`

Expand Down Expand Up @@ -58,52 +59,38 @@ write to the tap repository. The token does not need access to issues,
pull requests, actions, administration, or any repository other than
`go-tapd/homebrew-tap`.

### Configure `NPM_TOKEN`

Create this token from npm:

1. Open `https://www.npmjs.com/settings/flc1125/tokens`.
2. Click `Generate New Token`.
3. Use a descriptive name, such as `go-tapd-cli-release`.
4. Add a description, such as `Publish @go-tapd/tapd from GitHub Actions`.
5. If npm asks for token type, choose a granular access token.
6. In `Packages and scopes`, set permission to `Read and write`.
7. Select the `@go-tapd` scope. If the scope cannot be selected before the
first package exists, temporarily select all packages, publish once, then
replace the token with a narrower `@go-tapd` token.
8. Do not rely on organization permissions alone. Organization access controls
teams and settings, but package publishing requires package or scope access.
9. Set an expiration date and note it somewhere you will check before the next
release.
10. If the account or package requires two-factor authentication for publish
actions, enable `Bypass two-factor authentication` for this CI token.
11. Generate the token and copy it immediately.
### Configure npm Trusted Publishing

Save it in the CLI repository:
Configure trusted publishing from npm:

1. Open `https://github.com/go-tapd/cli/settings/secrets/actions`.
2. Click `New repository secret`.
3. Set `Name` to `NPM_TOKEN`.
4. Paste the token into `Secret`.
5. Save the secret.
1. Open `https://www.npmjs.com/package/@go-tapd/tapd`.
2. Open the package settings.
3. Find the Trusted Publishing or Trusted Publisher section.
4. Choose GitHub Actions as the publisher.
5. Set organization or user to `go-tapd`.
6. Set repository to `cli`.
7. Set workflow filename to `release.yml`.
8. Leave environment empty unless the release workflow starts using a GitHub
environment.
9. Allow the `npm publish` action.
10. Save the trusted publisher configuration.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In the npm Trusted Publisher setup UI, there is no option or step to "Allow the npm publish action". After filling in the workflow details, the user simply clicks the "Add publisher" button to save the configuration. Combining these steps makes the instructions more accurate to the actual npm interface.

Suggested change
9. Allow the `npm publish` action.
10. Save the trusted publisher configuration.
9. Click Add publisher to save the configuration.


Why this permission is needed: the release workflow runs
`npm publish --access public --provenance` from the `npm/` package directory.
The token must be able to publish `@go-tapd/tapd`. It does not need access to
private packages or unrelated npm scopes.
Why this permission is needed: the release workflow runs `npm publish --access
public` from the `npm/` package directory. npm exchanges the GitHub Actions OIDC
identity for a short-lived publish token, so no long-lived npm repository secret
is required.

### Verify Secret Configuration
### Verify Release Configuration

Check that both GitHub repository secrets exist:
Check that the required GitHub repository secret exists:

```bash
gh secret list
```

Expected names:
Expected name:

```text
NPM_TOKEN
TAP_GITHUB_TOKEN
```

Expand All @@ -124,19 +111,19 @@ Expected results:
- `npm publish --access public --dry-run` prints the package contents and ends
with `+ @go-tapd/tapd@...`.

The dry-run does not prove that `NPM_TOKEN` itself has the correct access. It
only proves the local npm account and package metadata are valid. The token is
exercised by the GitHub Actions release workflow.
The dry-run does not prove that the trusted publisher is configured correctly.
It only proves the local npm account and package metadata are valid. The trusted
publisher is exercised by the GitHub Actions release workflow.

### Rotate Expired Tokens

When a token is close to expiration:
When `TAP_GITHUB_TOKEN` is close to expiration:

1. Create a replacement token using the same permissions listed above.
2. Update the matching repository secret in
2. Update the repository secret in
`https://github.com/go-tapd/cli/settings/secrets/actions`.
3. Re-run the verification commands.
4. Revoke the old token from GitHub or npm after the new secret is saved.
4. Revoke the old token from GitHub after the new secret is saved.

Do not commit tokens, `.npmrc` files containing tokens, or screenshots that
show token values.
Expand All @@ -147,3 +134,4 @@ show token values.
- npm Docs: [Creating and viewing access tokens](https://docs.npmjs.com/creating-and-viewing-access-tokens/)
- npm Docs: [Requiring 2FA for package publishing and settings modification](https://docs.npmjs.com/requiring-2fa-for-package-publishing-and-settings-modification/)
- npm Docs: [Generating provenance statements](https://docs.npmjs.com/generating-provenance-statements/)
- npm Docs: [Trusted publishing for npm packages](https://docs.npmjs.com/trusted-publishers/)
Loading