Migrating from JFrog Artifactory
This is the field guide for moving an existing JFrog Artifactory installation — Self-Hosted, JFrog Cloud, or hybrid — to OrbitalReg. It covers Artifactory Pro, Enterprise, and Enterprise+ on every supported format. The procedures have been validated against installs ranging from single-Pro mid-market deployments to Enterprise+ HA clusters with 100+ repositories and 30 million artifacts.
Reading this for the first time?
Skip to Pick your strategy if you already know your risk profile. Read What stays the same if you are evaluating before committing.
What stays the same
For your developers, almost nothing visible changes:
- Push and pull commands stay format-native (
mvn deploy,npm publish,docker push,helm push, etc.) - Bearer-token authentication, scoped tokens, and Docker-login flows all carry through
- CI pipeline scripts only need their registry URL updated
- Existing artifact identifiers (group:artifact:version, image tags) carry through unchanged
- Build-info envelopes — JFrog's strength — translate 1:1 to OrbitalReg's build-info schema (CI run, commit SHA, builder identity, signed)
- The
jfrogCLI's push/pull commands work against OrbitalReg with only an endpoint change; onlyjfrog rt-specific commands (config, search) need replacement withorbital
For your operations team, the big-picture shape changes:
- One Go binary instead of a JVM application server
- One Postgres database instead of Derby / MySQL / Postgres / Oracle with JFrog-specific schema
- One S3-compatible bucket instead of binary-store provider config
- Air-gapped operation as the default, rather than a JFrog-Mission-Control
- Distribution-side configuration
What changes
| Concept | JFrog Artifactory | OrbitalReg |
|---|---|---|
| Runtime | JVM application server | Single Go binary |
| Database | Derby / MySQL / Postgres / Oracle / MS SQL | Postgres |
| Blob storage | Filestore providers (file, S3, Azure, GCS, sharded) | S3-compatible (MinIO or native) |
| Format coverage | ~30 formats via plugin architecture | 40+ formats, all in one binary |
| Security scanning | Xray (separate licence) | Trivy + Grype, included |
| Signature verification | Plugin-based | Sigstore + X.509 + OpenPGP, included |
| OIDC / SSO | Pro+ | All tiers |
| Deployment model | SaaS-first; on-prem upcharge | Self-hosted by default |
| Pricing model | Per-user, per-repo, per-feature | Per-deployment annual flat-rate |
| Air-gapped operation | Possible with manual config | Default-on |
| HA setup | Complex (sealed-config, license-bucket) | Standard Kubernetes HA |
Pre-migration audit
The first step is always inventory. The orbital migrate plan command walks the entire Artifactory instance, catalogues what it finds, and writes a plan file the apply step consumes.
orbital migrate plan \
--source jfrog \
--endpoint https://artifactory.example.com \
--token "$JFROG_TOKEN" \
--output migration-plan.jsonWhat gets discovered:
- Repositories — name, format (package type), type (local / remote / virtual / federated), filestore, layout, deployment policy
- Artifacts — counted per repository, sha256 sampled, build-info envelopes recognised and preserved
- Permissions — JFrog "permission targets" (the building block that binds users/groups to repositories with read/write/delete/manage privileges)
- Webhooks — global and per-repository, with target URLs and event filters
- Replications — local-to-remote replication setups, push-replication schedules
- Watches and Xray policies — flagged for translation to OrbitalReg pull-gate policies (manual review required — DSLs differ)
- Federated repositories — flagged separately; OrbitalReg's geo-sync is the equivalent feature, but the configuration model differs enough that this is a manual conversion
- Project-level configuration (Enterprise+) — JFrog Projects map to OrbitalReg Projects naturally
The output of plan is a JSON file. Read it before running apply. It is the contract between the audit and the migration.
Format coverage
OrbitalReg supports every format JFrog does, plus more. The format-by-format mapping:
| JFrog format | OrbitalReg adapter | Notes |
|---|---|---|
| Maven | maven | Snapshot vs release semantics preserved. JFrog "checksum policy" maps to OrbitalReg's strict-checksum mode. |
| Gradle | maven | Same backend as Maven; Gradle clients use the Maven endpoint. |
| Ivy | maven | Layout-aware mapping preserves Ivy's [organization]/[module]/[revision]/ paths. |
| npm | npm | Scoped packages preserved. Integrity hashes verified during transfer. |
| Docker | docker | Manifests, layers, tags, multi-arch index.json. JFrog Container Registry repos are just Docker repos under the hood. |
| Helm | helm | index.yaml + .tgz tarballs + signed Chart.yaml provenance. |
| NuGet | nuget | NuGet v3 protocol. SemVer + prerelease tags preserved. |
| RubyGems | rubygems | gem files + spec metadata. |
| PyPI | pypi | wheels + sdists. |
| Conan | conan | Both Conan 1.x and 2.x supported. Lockfiles preserved. |
| CocoaPods | cocoapods | Podspec + .tar.gz. |
| Conda | conda | Anaconda channel format. |
| Cargo | cargo | crates.io-compatible registry. |
| Generic | generic | Path-based pass-through with sha256 verification. |
| apt / Debian | apt | Repository metadata + signatures. Distribution + component preserved. |
| RPM / yum | yum | repodata.xml + GPG signatures. |
| Go modules | go | Module proxy semantics, sumdb support. |
| Helm OCI | docker | Helm-on-OCI uses the Docker adapter under the hood. |
| Pub | pub | Dart pub package format. |
| Build-info | native | Stored separately as build-info envelopes attached to artifacts; preserved 1:1 during migration. |
Permission model translation
JFrog permissions use a four-level model: users → groups → permission targets → repositories. OrbitalReg flattens this into roles + scoped tokens + project memberships.
The translator maps automatically where the semantics line up:
| JFrog | OrbitalReg |
|---|---|
| Built-in admin | system_admin role |
Permission target with manage privilege on a repo | Project admin role (when permission scope is project-level) or repo admin token |
Permission target with read privilege | Project viewer role or read-scoped token |
Permission target with deploy privilege | Repo write-scoped token |
Permission target with delete-overwrite | Repo write-scoped token + retention policy |
| LDAP / SAML / Crowd / OAuth user-source | Same connector configured on OrbitalReg side; translator preserves group mappings |
| JFrog Project | OrbitalReg Project |
| JFrog Project Role | OrbitalReg Project role |
| Federated user | OrbitalReg user (federated identity preserved if SAML/OIDC) |
Path-pattern permissions (e.g. JFrog permission target with include-patterns: com/example/** and exclude-patterns: com/example/internal/**) translate to OrbitalReg's path-scoped tokens. The translator generates a report showing every JFrog permission target and its mapped OrbitalReg equivalent. Review it before applying — a small percentage of JFrog patterns rely on edge-case AQL syntax that needs manual translation.
Webhook + automation translation
JFrog webhook events map to OrbitalReg webhook events:
| JFrog event | OrbitalReg event |
|---|---|
artifact.deployed | artifact.uploaded |
artifact.deleted | artifact.deleted |
artifact.moved | artifact.moved |
artifact.copied | artifact.copied |
artifact.property.added | artifact.tag.added (properties → tags) |
repository.created | repository.created |
repository.deleted | repository.deleted |
build.uploaded | build_info.uploaded |
build.deleted | build_info.deleted |
build.promoted | build_info.promoted |
JFrog Properties (custom key-value metadata on artifacts) map to OrbitalReg's tag system. Property-driven retention, replication, or download conditions translate to the equivalent OrbitalReg retention-policy or pull-gate condition.
JFrog Pipelines (CI/CD) is out of scope for migration — OrbitalReg is a registry, not a CI/CD orchestrator. Customers using JFrog Pipelines typically migrate that workload separately to GitHub Actions, GitLab CI, or Jenkins.
JFrog Distribution (release-bundle creation + signing + edge distribution) maps partially: OrbitalReg's promotion gates + Sigstore integration cover the signed-release-bundle use case; edge-node distribution is covered by OrbitalReg's geo-sync feature.
Pick your strategy
Use the matrix below — the orbital migrate plan step also recommends one based on what it sees.
| Your situation | Recommended strategy |
|---|---|
| Registry under 500 GB, can take 4 h downtime | Big bang |
| Production-critical, zero downtime, registry under 5 TB | Blue-green parallel run |
| Huge registry (over 10 TB), distributed teams, can't agree on a cutover window | Lazy proxy |
| 14 TB, 30M artifacts (the big-customer profile) | Lazy proxy |
| HA cluster behind a load balancer | Blue-green parallel run (mirror the topology) |
| JFrog Cloud (SaaS-only, no on-prem source) | Lazy proxy (you don't control the source's lifecycle) |
Big bang cutover
Schedule a maintenance window. Run the migration end-to-end. Flip DNS.
Day -7 Announce maintenance window to all developer teams
Day -3 Dry-run on a copy of production (or a representative sample)
Day 0 Window opens
00:00 Set Artifactory to read-only mode (System → General Configuration)
00:15 orbital migrate apply --plan migration-plan.json
T+2h apply complete — orbital migrate verify --sample 1000
T+3h Flip DNS: registry.example.com → OrbitalReg
T+4h Spot-check pulls from each format
T+5h Window closes — all clear
Day +30 Decommission Artifactory licence (Pro/Enterprise)Total wall-clock time: 4-12 hours for registries up to 500 GB. Beyond that, prefer one of the other two strategies — JFrog's bulk-export at scale is bandwidth-bound on a single connection.
Blue-green parallel run
Run both registries simultaneously. Push to both. Pull from JFrog until verification passes, then flip DNS in a single change.
Day -14 Install OrbitalReg in parallel to Artifactory
Configure both as push targets in CI (dual-publish via the
existing 'jfrog' CLI for one + 'orbital' CLI for the other,
or via Maven distribution-management mirrors)
Day -14 Run continuous import in the background — at full bandwidth
OrbitalReg catches up over days, not hours
Day -7 Cutover-readiness check — orbital migrate verify
Sample sizes: 5,000 sha256 comparisons per format
Day -3 Flip dev / staging DNS — soak for 72 h
Day 0 Flip production DNS in a single change
Artifactory becomes read-only (still serving fallback)
Day +14 Stop dual-publish — push only to OrbitalReg
Day +30 Decommission Artifactory licencePush traffic during the dual-publish window goes to both registries, which doubles your CI write traffic. JFrog's Replication feature can also be used in reverse — point an OrbitalReg-hosted local repo at JFrog as the upstream, replicating in the opposite direction during the verification phase.
Lazy proxy cutover
For very large registries (over 10 TB), the lazy-proxy strategy avoids the upfront full-import cost. OrbitalReg fronts Artifactory as a remote-proxy. Pulls go through OrbitalReg, which fills its cache from Artifactory on demand. Over weeks, the cache populates organically with the artifacts your team actually pulls.
Day -14 Install OrbitalReg in front of Artifactory as a remote-proxy
Configure all repository entries as remote-mode pointing at JFrog
Day -14 Flip dev / staging DNS to OrbitalReg immediately
All pulls go through OrbitalReg → cache fills naturally
Day -14 Soak — monitor cache-hit rate, error-rate, latency
Day -7 Production DNS flip
OrbitalReg now in front of all reads
Writes still go to Artifactory (will switch in next phase)
Day +0 Switch CI / push targets to OrbitalReg directly
New artifacts now land in OrbitalReg first, async-replicate
to Artifactory (using the same `replications` configuration
JFrog already understands)
Day +14 When cache-hit rate exceeds 95%, switch repositories from
remote-mode to local-mode (cached blobs become canonical)
Day +30 When all repositories are local-mode and re-verified,
decommission ArtifactoryThis strategy minimises risk — Artifactory stays as a fallback for the entire migration window. If anything breaks, flip DNS back. No data was ever lost because OrbitalReg never deleted anything from Artifactory.
For a 14 TB / 30M-artifact deployment, this is the recommended path. Total elapsed time: 30-60 days. Active work: ~10-20 hours of operator time spread over that period.
Cutover sequence (lazy proxy, detailed)
Here is the canonical lazy-proxy sequence with concrete commands.
Phase 1: Install OrbitalReg (Day -14)
# Helm install on your existing Kubernetes cluster
helm repo add orbitalreg https://charts.orbitalreg.com
helm install orbitalreg orbitalreg/orbitalreg \
--namespace orbitalreg --create-namespace \
--values your-values.yaml
# Wait for the API to become healthy
kubectl wait --for=condition=ready pod -l app=orbitalreg-api \
-n orbitalreg --timeout=300sPhase 2: Configure remote-proxy mode (Day -14)
# Run the migration plan in proxy-only mode
orbital migrate plan \
--source jfrog \
--endpoint https://artifactory.example.com \
--token "$JFROG_TOKEN" \
--strategy lazy-proxy \
--output migration-plan.json
# Apply — this only registers repositories as remote-mode, no blob copy
orbital migrate apply --plan migration-plan.jsonAfter this, OrbitalReg has every Artifactory repository configured as a remote-proxy. Pulls go through OrbitalReg, which fetches from Artifactory on cache miss. Authentication is via a JFrog identity-token scoped to read-only on the source repos.
Phase 3: Soak on dev / staging (Day -14 to Day -7)
Switch dev and staging environments to point at OrbitalReg. Monitor:
- Cache-hit rate per repository (target: 60% within 7 days)
- p99 pull latency vs JFrog baseline (acceptable: same or better — OrbitalReg's pull path has fewer hops than JFrog's filestore-proxy layer)
- Error rate (acceptable: under 0.1%)
The portal observability dashboard tracks all three. Watch for format-specific anomalies; multi-arch Docker images sometimes have manifest-list quirks that need a second look.
Phase 4: Production DNS flip (Day -7)
# Update DNS — registry.example.com → OrbitalReg ingress
# This is a single CNAME or A record changePulls now flow through OrbitalReg in production. Writes still target Artifactory directly (CI configurations unchanged).
Phase 5: Switch CI to push to OrbitalReg (Day 0)
Update your CI pipelines to push to OrbitalReg directly. New artifacts now land in OrbitalReg first; the proxy fills the cache for old artifacts on demand. Existing JFrog Replication configurations can be reversed to keep Artifactory in sync with OrbitalReg during a transition window.
# .github/workflows/publish.yml example
- name: Publish
env:
NPM_REGISTRY: https://registry.example.com # now OrbitalReg
run: |
npm config set registry "$NPM_REGISTRY"
npm publishPhase 6: Convert remote-mode to local-mode (Day +14)
Once cache-hit rates exceed 95%, you can switch repositories from remote-mode to local-mode. Cached blobs become canonical; OrbitalReg no longer reaches back to Artifactory.
orbital migrate finalize --plan migration-plan.jsonThis sweeps the cache, marks all blobs as authoritative, and removes the upstream-proxy configuration. Verification runs again at this stage.
Phase 7: Decommission Artifactory (Day +30)
After 30 days of stable local-mode operation with no rollback signals, Artifactory can be turned off. Take a final snapshot for the audit log, then surrender or downgrade the JFrog licence (Pro / Enterprise / Enterprise+ tier).
For Enterprise+ customers, this is also the moment to turn off any JFrog Distribution edge nodes — OrbitalReg's geo-sync replaces the multi-region distribution use case.
Verification
Verification is what tells you it's safe to cut over.
orbital migrate verify --sample 5000What gets verified:
- Sha256 sample comparison — pulls a random sample from OrbitalReg, compares against the source. If any mismatch, the verifier fails and reports which artifact diverged.
- Build-info round-trip — JFrog's build-info envelopes are pulled from both sides and compared structurally. Build-info is OrbitalReg's strongest 1:1 mapping with JFrog.
- Metadata round-trip — for each format, verifies that format-specific metadata (Maven
pom.xml, npmpackage.json, Docker manifests) round-trip correctly. - Synthetic pull test — performs a real pull through the format-native client (
mvn,npm,docker pull) on a sampled set, ensuring client compatibility. - Permission spot-check — re-runs each translated permission against a synthetic test user; reports any divergence from JFrog's answer.
A clean run looks like this:
✓ 5000/5000 sha256 matches
✓ 247 build-info envelopes round-trip correctly
✓ All metadata round-trips correctly (12 formats checked)
✓ Pull-test from random sample succeeded
✓ Permission spot-check: 89/89 permission targets match
→ Safe to flip DNSIf any check fails, the report lists the divergence. Do not flip DNS until the report is clean.
Rollback
The lazy-proxy strategy makes rollback trivial: flip DNS back to Artifactory. Nothing was ever deleted from Artifactory during migration.
For blue-green: same — DNS flip, OrbitalReg becomes write-only-via-CI, Artifactory resumes serving pulls.
For big-bang: rollback requires restoring Artifactory from your maintenance-window snapshot. This is why we recommend big-bang only for smaller registries where the snapshot-restore time is bounded.
FAQ
Can we migrate without any downtime?
Yes. Use the blue-green or lazy-proxy strategy. Both give you zero developer-visible downtime through the cutover.
Do existing CI pipelines need updates?
Only the registry URL. Push commands, authentication, and artifact identifiers all carry through unchanged. The jfrog CLI's push/pull verbs work against OrbitalReg with only an endpoint change; JFrog-CLI-specific verbs (jfrog config, jfrog rt search) are replaced by orbital CLI verbs.
What about JFrog Xray?
OrbitalReg includes equivalent CVE detection (Trivy + Grype), signature verification (Sigstore + X.509 + OpenPGP), and pull-gate enforcement natively — no separate licence, no separate product. Migrating Xray policies takes a few hours of manual translation since the DSLs differ; the OrbitalReg pull-gate-policy engine is more concise but less expressive than Xray's full rule-set, so a small percentage of hyper-specific Xray policies need workshop time.
What about JFrog Distribution?
OrbitalReg's promotion gates + Sigstore integration cover the signed-release-bundle use case. For multi-region edge distribution, OrbitalReg's geo-sync replaces JFrog Distribution's edge-node story.
What about JFrog Pipelines?
Out of scope for migration. OrbitalReg is a registry, not a CI/CD orchestrator. Customers using JFrog Pipelines migrate that workload separately to GitHub Actions, GitLab CI, or Jenkins.
Will our jfrog CLI scripts keep working?
Push and pull verbs (e.g. jfrog rt upload, jfrog rt download, jfrog rt build-publish) work against any Artifactory-API-compatible endpoint, and OrbitalReg implements the JFrog REST API surface that the CLI uses. JFrog-CLI-specific verbs (jfrog config show, jfrog rt search with AQL) are not implemented; rewrite those parts in the orbital CLI's vocabulary.
How long does a full migration take?
| Registry size | Big bang | Blue-green | Lazy proxy |
|---|---|---|---|
| Under 500 GB | 4 h | 24 h elapsed | 14 days elapsed |
| 1-5 TB | not recommended | 48-72 h elapsed | 21 days elapsed |
| 5-10 TB | not recommended | 5-7 days elapsed | 30 days elapsed |
| Over 10 TB | not recommended | not recommended | 30-60 days elapsed |
Active operator hours are a fraction of elapsed time — most of the elapsed window is wait-for-traffic-to-fill-cache or wait-for-soak-period.
What's the cost difference vs Artifactory Pro / Enterprise?
JFrog Artifactory pricing scales with seats, repositories, and add-on products (Xray, Distribution, Pipelines). For a typical mid-market deployment with Xray, the all-in annual cost runs six figures. OrbitalReg is licensed per-deployment, annual flat-rate. See the pricing overview — security is included in every tier, never an upcharge.
Can we run both registries permanently?
Yes — OrbitalReg can stay configured as a proxy in front of Artifactory indefinitely. Some teams prefer that posture for the first 12 months to keep Artifactory as a hot fallback. After that, the cost of two licences usually outweighs the comfort of redundancy.
What about JFrog Cloud (SaaS)?
JFrog Cloud is supported as a migration source. The lazy-proxy strategy is recommended — you don't control the source's lifecycle, so a big-bang cutover risks SaaS-side rate-limits during the bulk-export window. The orbital migrate plan step uses the same JFrog REST API surface against either self-hosted or cloud endpoints.
Need a working session?
Email info@orbitalreg.com with subject "JFrog migration support" and we'll book a 60-minute working session. Customers in active migration get a dedicated channel for questions during the cutover window.