Guide

OpenAPI to private npm registry

Publish your TypeScript SDK to a private npm registry — Verdaccio, JFrog Artifactory, Sonatype Nexus, AWS CodeArtifact, Cloudsmith — without writing the glue yourself.

Last reviewed: April 23, 2026

Most serious shipping teams end up with a private npm registry. The reasons pile on: compliance demands every dependency come from an audited source, legal wants to keep API surface off public npm, platform wants package installs to work during a public-npm outage, security wants a single chokepoint where tarballs are scanned. Whether the tool is Verdaccio on an EC2 box or a paid JFrog Artifactory tenant, "the private registry" becomes part of the supply chain.

Generating a TypeScript SDK from OpenAPI and landing it on that registry sounds like one more publish target. It is, in the strict sense — the npm protocol is the npm protocol, and any conforming registry accepts a tarball. What makes it different is the operational tail: each registry has its own auth shape (bearer token here, basic auth there, a service account elsewhere), its own rotation cadence, its own audit hooks, its own network access story. None of that is interesting work, but all of it is work somebody has to do.

SDK Factory treats every standard-protocol npm registry as a uniform target. You paste the registry URL, paste a token, pick a package name, and the pipeline handles the same auto-rebuild-on-schema-change loop it does for public npm. Compliance, audit, and rotation are built into the product instead of each team reinventing them.

Why the manual path hurts

What you actually spend time on when you wire this by hand — and what eventually drifts.

Every registry is a different .npmrc incantation

Verdaccio wants `_authToken`. JFrog Artifactory wants `_auth` with base64-encoded credentials, or a different path per repo. Nexus wants yet another path style. AWS CodeArtifact wants a short-lived token from an `aws` CLI call. Getting the publish side right the first time on each registry is a ticket; keeping it right is a standing order.

SSO-fronted registries are the hard case

A registry behind SAML or OIDC makes human access easy and automation access awkward. Teams end up with a service account whose credentials the CI pipeline holds, rotated on a calendar, with nobody confident what happens when the calendar misses a beat.

Token lifecycle is nobody's job

Some registries expire tokens every 30 days (CodeArtifact). Some never expire unless you revoke (Verdaccio, Artifactory classic tokens). Some depend on the backing identity provider's rotation policy. A mixed shop ends up with one rotation SOP per registry and no dashboard to see which is due.

Audit is an afterthought

When a customer asks "which exact tarball was live on 2026-03-18 at 10:42" you want an answer, not a grep through CI logs. Most internal publish pipelines don't retain the artifact — they retain the publish event. If the registry has gone through a retention sweep, the tarball is gone.

Before and after

The hand-rolled version versus the pasted-URL version — same end state, very different footprint.

Doing it by handa typical private-registry publish pipeline
# 1. Figure out the right .npmrc for *this* registry
cat > .npmrc <<'INI'
registry=https://npm.internal.acme.io/repository/npm-releases/
//npm.internal.acme.io/:_authToken=${NPM_TOKEN}
always-auth=true
INI

# 2. Generate SDK, build, publish
npx @openapitools/openapi-generator-cli generate ...
cd generated && npm install && npm run build
npm version patch --no-git-tag-version
npm publish --registry https://npm.internal.acme.io/...

# 3. Token lifecycle — your calendar
#    - rotate every 90d
#    - update in GitHub Actions secrets
#    - update in any other CI that references it
#    - pray nobody forgets

# 4. Audit — whatever the registry retains
#    if retention swept the 1.4.2 tarball, it is gone
With SDK FactorySDK Factory dashboard
Paste schema URL:  https://api.example.com/openapi.yaml

Registry:          [ custom ▼ ]
URL:               https://npm.internal.acme.io/repository/npm-releases/
Auth type:         [ bearer token ▼ ]
Token:             ••••••••••••  (AES256, rotatable)
Package name:      @acme/api-client

┌──────────────────────────┐
│   Create & auto-publish  │
└──────────────────────────┘

→ Tarball archived in S3 keyed by deployment ID.
→ Every publish: schema hash + version + SHA-256 retained.
→ Rotation is a form submit. No CI file edits.

What SDK Factory does instead

The same pain points, handled by the pipeline — not by whoever is on call this week.

One form for any conforming registry

Paste the URL, paste the token, pick an auth type. Verdaccio, JFrog, Sonatype Nexus, AWS CodeArtifact, Cloudsmith, GitLab, an in-house mirror — all the same form. No per-registry quirks leaking into your CI.

Token storage built for compliance

Tokens are AES-256 encrypted at rest with the envelope key separate from the database. Rotation is a first-class operation on the dashboard, not a CI file edit. Rotation events are logged with timestamp and actor.

Every tarball archived outside the registry

Each published tarball is stored in S3 keyed by deployment ID, in addition to the registry itself. If your registry purges an old version, drops under a retention policy, or suffers an outage, the canonical artifact is still one click from the dashboard.

Audit trail by design

Every deployment is persisted with: the schema hash that produced it, the registry target, the package version, the published-at timestamp, and the SHA-256 of the shipped tarball. "Which tarball was live on $date" has a single answer, not a log archaeology project.

Registries we've tested against

Verdaccio (self-hosted or SaaS), JFrog Artifactory's npm repositories, Sonatype Nexus's npm format, AWS CodeArtifact, Cloudsmith, GitLab Package Registry, and GitHub Packages all ship as first-class registry targets. The common protocol they all implement is plain npm — a `PUT` to a tarball URL with an `Authorization` header — so the list is really "anything that speaks the npm protocol."

The per-registry variation is not in the protocol but in the auth shape. Bearer tokens are the common case. Basic auth (username + password, base64-encoded in the `Authorization` header) shows up on older Artifactory tenants and some on-prem Nexus instances. AWS CodeArtifact uses short-lived tokens fetched via `aws codeartifact get-authorization-token` — we support this as a scheduled refresh on our side so you don't schedule a cron to keep the token alive.

The one pattern we do not support today is mutual TLS. Registries that require client certificates for publish need a client identity on our infrastructure that the registry trusts, and we haven't wired that up. If your registry is behind mTLS, the honest answer is that a self-hosted generator + a bastion with the cert is a better fit than SDK Factory right now.

Network reachability is still your problem

We publish over the public internet. Your registry has to be reachable from our egress IPs. For most private registries that means it's on a hostname with a real TLS certificate — which is the common case today, since cloud-hosted registries (CodeArtifact, Cloudsmith, JFrog Cloud) are internet-facing by default.

If your registry is VPN-only or on a private VPC, you have options: expose a read-only proxy on the public internet for our publish traffic, put the registry behind an IP-allowlisted ingress, or run a self-hosted generator instead. The "allowlist our egress IPs" path is the common choice and is documented on the app page once a custom registry is configured.

SSO in front of the registry doesn't change anything from our side — we use service-account credentials, the same way your CI does. If the SSO provider issues short-lived tokens, we support scheduled refresh.

Audit, retention, and reproducibility

Every tarball we publish is copied to S3, keyed by deployment ID, with a SHA-256 manifest. That artifact is retained independently of the registry — if your registry loses the version (unpublish, retention sweep, accidental delete), the tarball is still recoverable from the dashboard.

Each deployment also stores the canonicalised schema hash that produced it. "Which OpenAPI document produced version 1.4.3?" and "when did the schema actually change between 1.4.2 and 1.4.3?" both have one-click answers. That is the shape most audit questions take when a customer asks why something behaved unexpectedly on a specific date.

Re-publishing an archived tarball (for a rollback, or to re-seed a registry that lost a version) is a dashboard action on the Pro tier. The bytes are identical — not a rebuild from the same schema, which could produce a different artifact if the generator itself moved.

Who reaches for this

  • Enterprises with a security policy that forbids installing packages from public npm — the SDK has to live on the internal registry.
  • Platform teams centralising package hosting across many downstream services, each with its own generated SDK.
  • Companies under regulated compliance regimes (SOC 2, HIPAA, PCI) where dependency provenance is an audit requirement.
  • Acquisition or integration scenarios where SDK access is gated by private-registry credentials instead of public distribution.

FAQ

Do you store our registry URL anywhere else?

Only inside our database, associated with the app that uses it. It appears in operational logs in the same way any outbound URL does (request paths, response codes). It is not shared, aggregated, or surfaced in any public-facing product feature.

Can you reach our registry if it's IP-allowlisted?

Yes — SDK Factory publishes from a fixed set of egress IPs that you can allowlist on your ingress. The current list is published on the app page for any app configured with a custom registry. We send change notices in advance when the set changes.

Our registry requires mutual TLS — is that supported?

Not today. If mTLS is a hard requirement, a self-hosted generation path (OpenAPI Generator from a bastion with the cert) is the honest answer. We'd rather say that than build a half-working mTLS shim.

How is the tarball archived — and for how long?

S3 storage, keyed by deployment ID, retained for the lifetime of the app (deleted apps are physically purged after 180 days per our retention SLA). The bytes are exactly what was published to the registry — same SHA-256.

Can I export the tarball for offline installation?

Yes, from the dashboard's deployment detail page. Downloading the archived tarball gives you the identical artifact that the registry has; installing it from disk with `npm install ./pkg-1.4.3.tgz` works the same as installing from the registry.

Try it with your actual schema.

One app on the Free tier, no card required. Paste your OpenAPI URL and see the generated private npm registry in minutes.