From f021b55e3bc75ba707760ff2d57b3efec1123c50 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Thu, 23 Oct 2025 17:24:27 -0400 Subject: [PATCH 1/6] Update npmjs publishing guide with OIDC --- .../overview/typescript/publishing-to-npm.mdx | 386 +++++++++--------- fern/snippets/typescript-sdk-version.mdx | 2 +- 2 files changed, 205 insertions(+), 183 deletions(-) diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index 1b0bd0464..c3ffe4300 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -3,12 +3,12 @@ title: Publishing to npm description: How to publish the Fern TypeScript SDK to npm. --- -Publish your public-facing Fern TypeScript SDK to the [npm +Publish your public-facing Fern TypeScript SDK to the [npmjs registry](https://www.npmjs.com/). After following the steps on this page, you'll have a versioned package published on npm. - Versioned package published on npm + Versioned package published on npmjs.com @@ -29,10 +29,10 @@ You'll need to update your `generators.yml` file to configure the package name, - In the `group` for your TypeScript SDK, change the output location from `local-file-system` (the default) to `npm` to indicate that Fern should publish your package directly to the npm registry: + In the `group` for your TypeScript SDK, change the output location from `local-file-system` (the default) to `npm` to indicate that Fern should publish your package directly to the npmjs registry: ```yaml {6-7} title="generators.yml" - groups: + groups: ts-sdk: # Group name for your TypeScript SDK generators: - name: fernapi/fern-typescript-sdk @@ -45,10 +45,10 @@ You'll need to update your `generators.yml` file to configure the package name, - Your package name must be unique in the npm repository, otherwise publishing your SDK to npm will fail. + Your package name must be unique in the npmjs registry, otherwise publishing your SDK will fail. ```yaml {8} title="generators.yml" - groups: + groups: ts-sdk: generators: - name: fernapi/fern-typescript-sdk @@ -62,10 +62,10 @@ You'll need to update your `generators.yml` file to configure the package name, - The `namespaceExport` option controls the name of the generated client. This is the name customers use to import your SDK (`import { your-client-name } from 'your-package-name';`). + The `namespaceExport` option controls the name of the generated client. This is the name customers use to import your SDK (`import { your-client-name } from 'your-package-name';`). ```yaml {9-10} title="generators.yml" - groups: + groups: ts-sdk: generators: - name: fernapi/fern-typescript-sdk @@ -81,259 +81,281 @@ You'll need to update your `generators.yml` file to configure the package name, -## Generate an npm token +## Configure GitHub publishing + +Fern can automatically publish your SDK to npmjs via GitHub Actions. Configure your GitHub repository and publishing mode: + + + +```yaml title="generators.yml" {11-14} +groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: + output: + location: npm + package-name: your-package-name + config: + namespaceExport: YourClientName + github: + repository: your-org/your-repository + mode: push # or "pull-request" + branch: your-branch-name # Required for mode: push +``` + +## Configure authentication + +Choose how you want to authenticate with npmjs when publishing. **OIDC is strongly recommended** for security. + + +**Starting in early 2025**, npmjs.org is deprecating long-lived authentication tokens for publishing from CI/CD workflows. We recommend using OIDC-based authentication. + + + + + +OIDC-based publishing (also known as "trusted publishing") is the most secure way to publish. With OIDC, you don't need to manage authentication tokens - npmjs trusts your GitHub repository to publish directly. + + +**Requirements:** +- Fern TypeScript SDK generator version `3.12.0` or later +- Fern CLI version `0.94.0` or later (only required for local generation with `--local`) + + - + Add `token: OIDC` to the `output` section: - Log into [npm](https://www.npmjs.com/) or create a new account. + ```yaml title="generators.yml" {9} + groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: # Must be 3.12.0 or later + output: + location: npm + package-name: your-package-name + token: OIDC + config: + namespaceExport: YourClientName + github: + repository: your-org/your-repository + mode: push + branch: your-branch-name + ``` - + - 1. Click on your profile picture. - 1. Select **Edit Profile**. - 1. Select **Access Tokens**. + Generate your SDK to create the GitHub Actions workflow with OIDC configuration: + + ```bash + fern generate --group ts-sdk + ``` + + Or push your `generators.yml` changes and let the Fern GitHub Action generate it for you. + + This creates a `.github/workflows/ci.yml` file that's configured to use OIDC for npm publishing. - + - Click on **Generate New Token**, then choose the appropriate token type. - - For more information on access tokens and which type to choose, see npm's [About access tokens](https://docs.npmjs.com/about-access-tokens) documentation. + Configure trusted publishing on npmjs.com to allow your GitHub repository to publish: - - + 1. Navigate to your package settings on npmjs.com + 1. Find the "Trusted Publisher" section and click "Add trusted publisher" + 1. Select "GitHub Actions" as your provider + 1. Fill in: + - **Organization or user**: Your GitHub username or organization + - **Repository**: Your TypeScript SDK repository name (e.g., `your-org/your-repository`) + - **Workflow filename**: `ci.yml` + - **Environment name**: Leave blank - 1. Select **Classic Token** - 1. Name your token and select **Automation** as the token type. - 1. Click **Generate Token**. + For more details, see npm's [trusted publishing documentation](https://docs.npmjs.com/trusted-publishers). - Save your new token – it won't be displayed after you leave the page. + + - - Creating NPM Automation Token - + - - - 1. Select **Granular Access Token**. - 1. Name your token. - 1. Set an expiration. - 1. Configure your token's access to packages and scopes. - 1. Configure your token's access to organizations. In order to fill this out, you must have at least one organization already configured in npm. See [Creating an organization](https://docs.npmjs.com/creating-an-organization) for more information. - 1. Optionally fill out additional permissions according to your organization's requirements. - 1. Click **Generate Token**. +**"Unable to authenticate" error** - Save your new token – it won't be displayed after you leave the page. +Common causes: +- Workflow filename doesn't match exactly (must be `ci.yml`) +- Trusted publisher configuration on npmjs.com doesn't match your repository settings +- Using self-hosted runners (not currently supported by npmjs.org) - - Creating Granular Access Token - +**Solution:** Double-check your trusted publisher configuration on npmjs.com matches your repository name and workflow filename exactly. - - - - +**Private repository limitations** - +Provenance attestations are not generated for packages published from private repositories, even when using trusted publishing. This is a [known limitation](https://github.blog/changelog/2023-07-25-publishing-with-npm-provenance-from-private-source-repositories-is-no-longer-supported/). + + + + + + -## Configure npm publication + +**This method is being deprecated by npmjs.org in early 2025.** We strongly recommend using OIDC-based authentication instead. Long-lived authentication tokens can be accidentally exposed in logs, compromised, and are difficult to manage and rotate. + - + - Add the path to the GitHub repository containing your TypeScript SDK: +1. Log into [npmjs.com](https://www.npmjs.com/) +1. Click on your profile picture and select **Edit Profile** +1. Select **Access Tokens** +1. Click **Generate New Token** and choose either **Classic Token** (select "Automation" type) or **Granular Access Token** +1. Save your token securely - it won't be displayed again - ```yaml {11-12} title="generators.yml" - groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: - output: - location: npm - package-name: your-package-name - config: - namespaceExport: YourClientName - github: - repository: your-org/company-typescript - ``` +For more information on access tokens, see npm's [About access tokens](https://docs.npmjs.com/about-access-tokens) documentation. - -Add `token: ${NPM_TOKEN}` to `generators.yml` to tell Fern to use the `NPM_TOKEN` environment variable for authentication when publishing to the npm registry. + + +Add `token: ${NPM_TOKEN}` to the `output` section: ```yaml title="generators.yml" {9} -groups: +groups: ts-sdk: generators: - name: fernapi/fern-typescript-sdk version: output: location: npm - package-name: name-of-your-package + package-name: your-package-name token: ${NPM_TOKEN} config: namespaceExport: YourClientName - github: + github: repository: your-org/your-repository + mode: push + branch: your-branch-name ``` + - - + -```yaml title="generators.yml" {14} -groups: - ts-sdk: - generators: - - name: fernapi/fern-typescript-sdk - version: - output: - location: npm - package-name: name-of-your-package - token: ${NPM_TOKEN} - config: - namespaceExport: YourClientName - github: - repository: your-org/your-repository - mode: push - branch: your-branch-name # Required for mode: push -``` +1. Open your repository on GitHub and go to **Settings** +1. Navigate to **Secrets and variables** > **Actions** +1. Click **New repository secret** +1. Name it `NPM_TOKEN` and paste your npm token +1. Click **Add secret** -## Publish your SDK + -Decide how you want to publish your SDK to npm. You can use GitHub workflows for automated releases or publish directly via the CLI. + - +## Publish your SDK - +Your SDK will automatically be published to npmjs when you create a GitHub release with a version tag: -Set up a release workflow via [GitHub Actions](https://docs.github.com/en/actions/get-started/quickstart) so you can trigger new SDK releases directly from your source repository. +1. Create a GitHub release with a version tag (e.g., `v1.0.0`) +1. The CI workflow will run automatically and publish to npm +1. View your package on npmjs.com to confirm the new version - - + - Open your source repository in GitHub. Click on the **Settings** tab. Then, under the **Security** section, open **Secrets and variables** > **Actions**. +If you prefer to trigger publishes manually, create a `.github/workflows/publish.yml` file: - - Adding GitHub Repository Secret - +```yaml title=".github/workflows/publish.yml" +name: Publish TypeScript SDK - You can also use the url `https://github.com//settings/secrets/actions`. +on: + workflow_dispatch: + inputs: + version: + description: "Version to publish (e.g., 1.0.0)" + required: true + type: string - - +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 - 1. Select **New repository secret**. - 1. Name your secret `NPM_TOKEN`. - 1. Add the corresponding token you generated above. - 1. Click **Add secret**. + - name: Install Fern + run: npm install -g fern-api - - NPM_TOKEN secret - + - name: Generate and publish SDK + env: + FERN_TOKEN: ${{ secrets.FERN_TOKEN }} + run: fern generate --group ts-sdk --version ${{ inputs.version }} --log-level debug +``` - - +Add your `FERN_TOKEN` as a repository secret (run `fern token` to generate one), then trigger the workflow from the **Actions** tab. - 1. Select **New repository secret**. - 1. Name your secret `FERN_TOKEN`. - 1. Add your Fern token. If you don't already have one, generate one by - running `fern token`. By default, the `fern_token` is generated for the - organization listed in `fern.config.json`. - 1. Click **Add secret**. + - - - - Set up a CI workflow that you can manually trigger from the GitHub UI. In your repository, navigate to **Actions**. Select **New workflow**, then **Set up workflow yourself**. Add a workflow that's similar to this: - - ```yaml title=".github/workflows/publish.yml" maxLines=0 - name: Publish TypeScript SDK - - on: - workflow_dispatch: - inputs: - version: - description: "The version of the TypeScript SDK that you would like to release" - required: true - type: string - - jobs: - release: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Install Fern CLI - run: npm install -g fern-api - - - name: Release TypeScript SDK - env: - FERN_TOKEN: ${{ secrets.FERN_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - run: | - fern generate --group ts-sdk --version ${{ inputs.version }} --log-level debug - ``` - - You can alternatively configure your workflow to execute `on: [push]`. See Vapi's [npm publishing GitHub Action](https://github.com/VapiAI/server-sdk-typescript/blob/main/.github/workflows/ci.yml) for an example. - - +--- - +## Migrating from token-based to OIDC publishing - Navigate to the **Actions** tab, select the workflow you just created, specify a version number, and click **Run workflow**. This regenerates your SDK. +If you're currently using token-based authentication and need to migrate to OIDC, follow these steps: - - Running TS publish workflow - + + - + Change the `output.token` field from `${NPM_TOKEN}` to `OIDC` and ensure you're using version 3.12.0 or later: + + ```yaml title="generators.yml" + groups: + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: 3.12.0 # Must be 3.12.0 or later + output: + location: npm + package-name: your-package-name + token: OIDC # Changed from ${NPM_TOKEN} + config: + namespaceExport: YourClientName + github: + repository: your-org/your-repository + ``` - Once the workflow completes, you can view your new release by logging into npm and navigating to **Packages**. - - + - + Follow the [Configure trusted publishing on npmjs.com](#oidc-based-publishing-recommended) instructions in the OIDC section above to add your repository as a trusted publisher. - - + - + -Set the `NPM_TOKEN` environment variable on your local machine: + Regenerate your SDK locally or via GitHub Actions: -```bash -export NPM_TOKEN=your-actual-npm-token -``` + ```bash + fern generate --group ts-sdk + ``` - - + This will update your `.github/workflows/ci.yml` file with the required OIDC permissions. -Regenerate your SDK, specifying the version: + -```bash -fern generate --group ts-sdk --version -``` + - + After verifying the migration works, remove the `NPM_TOKEN` secret from your GitHub repository settings to prevent accidental use. -Once the workflow completes, you can view your new release by logging into npm and navigating to **Packages**. + + - +## Additional resources - - - +- [npm Trusted Publishing Documentation](https://docs.npmjs.com/trusted-publishers) +- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) +- [npm Provenance Documentation](https://docs.npmjs.com/generating-provenance-statements) diff --git a/fern/snippets/typescript-sdk-version.mdx b/fern/snippets/typescript-sdk-version.mdx index fad066f80..87dbaa157 100644 --- a/fern/snippets/typescript-sdk-version.mdx +++ b/fern/snippets/typescript-sdk-version.mdx @@ -1 +1 @@ -2.5.0 \ No newline at end of file +3.12.0 \ No newline at end of file From 004c6ebe3a34807879d4b065215ddd10b749e1b5 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Thu, 23 Oct 2025 17:33:31 -0400 Subject: [PATCH 2/6] Make migration more detailed --- .../overview/typescript/publishing-to-npm.mdx | 197 +++++++++++++++++- 1 file changed, 190 insertions(+), 7 deletions(-) diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index c3ffe4300..34e615c8f 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -306,7 +306,54 @@ Add your `FERN_TOKEN` as a repository secret (run `fern token` to generate one), If you're currently using token-based authentication and need to migrate to OIDC, follow these steps: +### Why migrate to OIDC + +npm is implementing trusted publishing to eliminate security risks associated with long-lived tokens, which can be: + +- Accidentally exposed in logs or configuration files +- Compromised and used persistently until manually revoked +- Difficult to manage and rotate + +OIDC-based publishing uses short-lived, cryptographically-signed tokens that are specific to your workflow and cannot be extracted or reused. + +### Prerequisites + +Before migrating, ensure you have: + +- A package published to [npmjs.org](https://npmjs.org) +- A GitHub repository with GitHub Actions configured +- Access to your package settings on [npmjs.com](https://npmjs.com) +- Fern CLI version `0.94.0` or later (for local generation) + +### Choose your migration path + +Select the approach that fits your situation: + + + + +This is the easiest path if you can upgrade to version 3.12.0 or later of the TypeScript SDK generator. + +**When to use this path:** +- You're able to upgrade to Fern TypeScript SDK generator version 3.12.0 or later +- You haven't `.fernignore`'d your CI workflow file + + + + Follow npm's ["Add a trusted publisher on npmjs.com"](https://docs.npmjs.com/trusted-publishers#step-1-add-a-trusted-publisher-on-npmjscom) instructions: + + 1. Navigate to your package settings on [npmjs.com](https://npmjs.com) + 1. Find the "Trusted Publisher" section and click "Add trusted publisher" + 1. Select "GitHub Actions" as your provider + 1. Configure: + - **Organization or user**: Your GitHub username or organization + - **Repository**: Your TypeScript SDK repository name + - **Workflow filename**: `ci.yml` (the default Fern workflow file) + - **Environment name**: Leave blank (unless you use GitHub environments) + + + Change the `output.token` field from `${NPM_TOKEN}` to `OIDC` and ensure you're using version 3.12.0 or later: @@ -329,20 +376,20 @@ If you're currently using token-based authentication and need to migrate to OIDC - - - Follow the [Configure trusted publishing on npmjs.com](#oidc-based-publishing-recommended) instructions in the OIDC section above to add your repository as a trusted publisher. - - - - Regenerate your SDK locally or via GitHub Actions: + Regenerate your SDK with the updated CI configuration. You can do this either: + + **Locally:** ```bash fern generate --group ts-sdk ``` + **Or via GitHub Actions:** + + If you use the Fern GitHub Action to generate your SDK, simply push your updated `generators.yml` file and let the workflow regenerate the SDK for you. + This will update your `.github/workflows/ci.yml` file with the required OIDC permissions. @@ -354,6 +401,142 @@ If you're currently using token-based authentication and need to migrate to OIDC + + + + +Use this path if you cannot upgrade the generator or have customized your CI workflow. + +**When to use this path:** +- You cannot upgrade due to breaking changes or bugs +- You've customized your CI workflow and added it to `.fernignore` +- Path 1 didn't update your workflow file + + + + + Follow the same instructions as Path 1 to add your repository as a trusted publisher on npmjs.com. + + + + + + Open your `.github/workflows/ci.yml` file and make these changes to the `publish` job: + + ```yaml title=".github/workflows/ci.yml" + publish: + needs: [ compile, test ] + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + permissions: + id-token: write # ADD THIS: Required for OIDC + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up node + uses: actions/setup-node@v4 + + # ADD THIS: Ensure npm 11.5.1 or later is installed for OIDC support + - name: Update npm + run: npm install -g npm@latest + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm build + + # MODIFY THIS: Remove npm config set and env block + - name: Publish to npm + run: | + if [[ ${GITHUB_REF} == *alpha* ]]; then + npm publish --access public --tag alpha + elif [[ ${GITHUB_REF} == *beta* ]]; then + npm publish --access public --tag beta + else + npm publish --access public + fi + # Previously had: + # run: | + # npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} + # if [[ ${GITHUB_REF} == *alpha* ]]; then + # npm publish --access public --tag alpha + # elif [[ ${GITHUB_REF} == *beta* ]]; then + # npm publish --access public --tag beta + # else + # npm publish --access public + # fi + # env: + # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + ``` + + **Key changes:** + - Add `permissions` block with `id-token: write` to the publish job + - Add step to update npm to version 11.5.1 or later + - Remove the `npm config set` line from the publish step + - Remove the `env` block with `NPM_TOKEN` from the publish step + + + + + + If you haven't already, add your CI workflow to `.fernignore` to prevent future generator updates from overwriting your manual changes: + + ```text title=".fernignore" + .github/workflows/ci.yml + ``` + + + + + + After verifying the migration works, remove the `NPM_TOKEN` secret from your GitHub repository settings. + + + + + + + +### Verify your migration + +After completing either migration path: + +1. **Trigger a workflow run** by creating a GitHub release with an alpha tag (e.g., `v1.0.0-alpha`) +2. **Check the workflow logs** to verify the publish step succeeds +3. **Verify provenance** by visiting your package on [npmjs.com](https://npmjs.com) - you should see a provenance badge + +### Migration troubleshooting + + + + +**Common causes:** +- Workflow filename doesn't match exactly (must be `ci.yml` with the `.yml` extension) +- Missing `id-token: write` permission in workflow +- npm CLI version is older than 11.5.1 +- Using self-hosted runners (not currently supported) + +**Solution:** Double-check your trusted publisher configuration on npmjs.com matches your actual workflow file name and verify all requirements are met. + + + + + +If your workflow continues using the old token-based authentication: + +- Verify you've removed the `npm config set` line and the `env: NPM_TOKEN` block from the publish step +- Check that npm CLI version 11.5.1+ is installed (add the update npm step) +- Ensure you're using generator version 3.12.0 or later (if using Path 1) +- When using `--local` generation, you need to use Fern CLI version 0.94.0 or later + + + + ## Additional resources - [npm Trusted Publishing Documentation](https://docs.npmjs.com/trusted-publishers) From 7369f7fd312f8f1a87d4f987ab3f1cb3597bba1c Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Thu, 23 Oct 2025 17:45:35 -0400 Subject: [PATCH 3/6] Fix vale issues --- .../overview/typescript/publishing-to-npm.mdx | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index 34e615c8f..75772756b 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -106,10 +106,10 @@ groups: ## Configure authentication -Choose how you want to authenticate with npmjs when publishing. **OIDC is strongly recommended** for security. +Choose how you want to authenticate with npmjs when publishing. **OpenID Connect (OIDC) is strongly recommended** for security. -**Starting in early 2025**, npmjs.org is deprecating long-lived authentication tokens for publishing from CI/CD workflows. We recommend using OIDC-based authentication. +**Starting in early 2025**, npmjs.org is deprecating long-lived authentication tokens for publishing from CI/CD workflows. OIDC-based authentication is recommended. @@ -193,7 +193,7 @@ Common causes: **Private repository limitations** -Provenance attestations are not generated for packages published from private repositories, even when using trusted publishing. This is a [known limitation](https://github.blog/changelog/2023-07-25-publishing-with-npm-provenance-from-private-source-repositories-is-no-longer-supported/). +Provenance attestations aren't generated for packages published from private repositories, even when using trusted publishing. This is a [known limitation](https://github.blog/changelog/2023-07-25-publishing-with-npm-provenance-from-private-source-repositories-is-no-longer-supported/). @@ -202,7 +202,7 @@ Provenance attestations are not generated for packages published from private re -**This method is being deprecated by npmjs.org in early 2025.** We strongly recommend using OIDC-based authentication instead. Long-lived authentication tokens can be accidentally exposed in logs, compromised, and are difficult to manage and rotate. +**This method is being deprecated by npmjs.org in early 2025.** OIDC-based authentication is strongly recommended instead. Long-lived authentication tokens can be exposed in logs, compromised, and are difficult to manage and rotate. @@ -261,7 +261,7 @@ groups: Your SDK will automatically be published to npmjs when you create a GitHub release with a version tag: -1. Create a GitHub release with a version tag (e.g., `v1.0.0`) +1. Create a GitHub release with a version tag (for example, `v1.0.0`) 1. The CI workflow will run automatically and publish to npm 1. View your package on npmjs.com to confirm the new version @@ -308,13 +308,13 @@ If you're currently using token-based authentication and need to migrate to OIDC ### Why migrate to OIDC -npm is implementing trusted publishing to eliminate security risks associated with long-lived tokens, which can be: +npmjs is implementing trusted publishing to remove security risks associated with long-lived tokens, which can be: -- Accidentally exposed in logs or configuration files +- Exposed in logs or configuration files - Compromised and used persistently until manually revoked - Difficult to manage and rotate -OIDC-based publishing uses short-lived, cryptographically-signed tokens that are specific to your workflow and cannot be extracted or reused. +OIDC-based publishing uses short-lived, cryptographically signed tokens that are specific to your workflow and can't be extracted or reused. ### Prerequisites @@ -405,10 +405,10 @@ This is the easiest path if you can upgrade to version 3.12.0 or later of the Ty -Use this path if you cannot upgrade the generator or have customized your CI workflow. +Use this path if you can't upgrade the generator or have customized your CI workflow. **When to use this path:** -- You cannot upgrade due to breaking changes or bugs +- You can't upgrade due to breaking changes or bugs - You've customized your CI workflow and added it to `.fernignore` - Path 1 didn't update your workflow file @@ -506,7 +506,7 @@ Use this path if you cannot upgrade the generator or have customized your CI wor After completing either migration path: -1. **Trigger a workflow run** by creating a GitHub release with an alpha tag (e.g., `v1.0.0-alpha`) +1. **Trigger a workflow run** by creating a GitHub release with an alpha tag (for example, `v1.0.0-alpha`) 2. **Check the workflow logs** to verify the publish step succeeds 3. **Verify provenance** by visiting your package on [npmjs.com](https://npmjs.com) - you should see a provenance badge From b7c147f41662c6d6d0e41fb91e4c758d984b2e96 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Fri, 24 Oct 2025 13:59:32 -0400 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Devin Logan --- .../overview/typescript/publishing-to-npm.mdx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index 75772756b..f82aaea2d 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -106,19 +106,18 @@ groups: ## Configure authentication -Choose how you want to authenticate with npmjs when publishing. **OpenID Connect (OIDC) is strongly recommended** for security. +Choose how you want to authenticate with npmjs when publishing. - -**Starting in early 2025**, npmjs.org is deprecating long-lived authentication tokens for publishing from CI/CD workflows. OIDC-based authentication is recommended. - + +**Starting in early 2025**, npmjs.org is deprecating long-lived authentication tokens for publishing from CI/CD workflows. **OpenID Connect (OIDC) authentication is strongly recommended** for security. + OIDC-based publishing (also known as "trusted publishing") is the most secure way to publish. With OIDC, you don't need to manage authentication tokens - npmjs trusts your GitHub repository to publish directly. - -**Requirements:** + - Fern TypeScript SDK generator version `3.12.0` or later - Fern CLI version `0.94.0` or later (only required for local generation with `--local`) @@ -156,7 +155,7 @@ OIDC-based publishing (also known as "trusted publishing") is the most secure wa fern generate --group ts-sdk ``` - Or push your `generators.yml` changes and let the Fern GitHub Action generate it for you. + This creates a `.github/workflows/ci.yml` file that's configured to use OIDC for npmjs publishing. Alternatively, you can push your `generators.yml` changes and let the Fern GitHub Action generate the workflow for you. This creates a `.github/workflows/ci.yml` file that's configured to use OIDC for npm publishing. @@ -202,7 +201,7 @@ Provenance attestations aren't generated for packages published from private rep -**This method is being deprecated by npmjs.org in early 2025.** OIDC-based authentication is strongly recommended instead. Long-lived authentication tokens can be exposed in logs, compromised, and are difficult to manage and rotate. +**This method is being deprecated by npmjs.org in early 2025.** Long-lived authentication tokens can be exposed in logs, compromised, and are difficult to manage and rotate. [OIDC-based authentication is strongly recommended instead](#migrating-from-token-based-to-oidc-publishing). From 49d57c5e8ca09d4428edb6510a24b24a2bf28e26 Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:04:55 -0400 Subject: [PATCH 5/6] Feedback --- .../overview/typescript/publishing-to-npm.mdx | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index f82aaea2d..c600d9d98 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -166,8 +166,8 @@ OIDC-based publishing (also known as "trusted publishing") is the most secure wa Configure trusted publishing on npmjs.com to allow your GitHub repository to publish: 1. Navigate to your package settings on npmjs.com - 1. Find the "Trusted Publisher" section and click "Add trusted publisher" - 1. Select "GitHub Actions" as your provider + 1. Find the **Trusted Publisher** section and click **Add trusted publisher** + 1. Select **GitHub Actions** as your provider 1. Fill in: - **Organization or user**: Your GitHub username or organization - **Repository**: Your TypeScript SDK repository name (e.g., `your-org/your-repository`) @@ -343,8 +343,8 @@ This is the easiest path if you can upgrade to version 3.12.0 or later of the Ty Follow npm's ["Add a trusted publisher on npmjs.com"](https://docs.npmjs.com/trusted-publishers#step-1-add-a-trusted-publisher-on-npmjscom) instructions: 1. Navigate to your package settings on [npmjs.com](https://npmjs.com) - 1. Find the "Trusted Publisher" section and click "Add trusted publisher" - 1. Select "GitHub Actions" as your provider + 1. Find the **Trusted Publisher** section and click **Add trusted publisher** + 1. Select **GitHub Actions** as your provider 1. Configure: - **Organization or user**: Your GitHub username or organization - **Repository**: Your TypeScript SDK repository name @@ -355,14 +355,14 @@ This is the easiest path if you can upgrade to version 3.12.0 or later of the Ty - Change the `output.token` field from `${NPM_TOKEN}` to `OIDC` and ensure you're using version 3.12.0 or later: + Change the `output.token` field from `${NPM_TOKEN}` to `OIDC` and ensure you're using version `3.12.0` or later: ```yaml title="generators.yml" groups: ts-sdk: generators: - name: fernapi/fern-typescript-sdk - version: 3.12.0 # Must be 3.12.0 or later + version: # Must be 3.12.0 or later output: location: npm package-name: your-package-name @@ -535,9 +535,3 @@ If your workflow continues using the old token-based authentication: - -## Additional resources - -- [npm Trusted Publishing Documentation](https://docs.npmjs.com/trusted-publishers) -- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) -- [npm Provenance Documentation](https://docs.npmjs.com/generating-provenance-statements) From 4152b8b93f7ea0b5a5739e09d578d153b46bd59b Mon Sep 17 00:00:00 2001 From: Niels Swimberghe <3382717+Swimburger@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:17:09 -0400 Subject: [PATCH 6/6] Add migration note at top of page --- fern/products/sdks/overview/typescript/publishing-to-npm.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx index c600d9d98..cf62e186a 100644 --- a/fern/products/sdks/overview/typescript/publishing-to-npm.mdx +++ b/fern/products/sdks/overview/typescript/publishing-to-npm.mdx @@ -7,6 +7,10 @@ Publish your public-facing Fern TypeScript SDK to the [npmjs registry](https://www.npmjs.com/). After following the steps on this page, you'll have a versioned package published on npm. + +If you're currently using token-based authentication, npmjs is deprecating long-lived tokens in early 2025. See [Migrating from token-based to OpenID Connect (OIDC) publishing](#migrating-from-token-based-to-oidc-publishing) to upgrade to the more secure OIDC authentication. + + Versioned package published on npmjs.com