Skip to content

License tiers — Free Forever vs. Commercial

OrbitalReg ships under a two-tier model. The split is deliberate and load-bearing for the brand promise: Security is not a paywall.

TierWhat it coversWhen it's gated
Free ForeverSecurity controls + core artifact hostingNever — entitled in every license state, including trial_expired, licensed_expired, and invalid.
CommercialPremium integrations + migration importersRequires trial_active or licensed_active. Gates on a 30-day implicit trial at first boot, then again on a customer-applied commercial envelope.

Operationally, the split is enforced by license.Allow(ctx, feature) in api/internal/license/license.go: the function consults license.FeatureTier[f] and short-circuits to true for anything in the Free tier, regardless of license state. Commercial-tier features fall through to the existing State.Active() check.

Free Forever — Security Promise + Core Hosting

These features remain entitled even after a trial lapses or a commercial envelope expires. A self-hosted OrbitalReg install is a working secure registry indefinitely; only the premium integrations stop.

Security Promise

  • Verify-on-pull & trust bundles (security.verify_on_pull) — CMS / PGP / RSA / Sigstore signature verification on every pull.
  • CVE detection & signature checks (security.detection_scan) — Asynchronous scans against OSV / NVD / GHSA, Sigstore Rekor lookups.
  • Security blocks & block list (security.block) — Manual + auto block list (path / sha256 / repo-scoped) with public block landing pages.
  • Auto-quarantine on new CVE (security.auto_quarantine) — Auto- block on fresh CVE matches against existing artifacts.
  • Pull-gate policy engine (security.pull_gate) — Synchronous pre-pull gate combining license / signature / scan / SBOM checks.
  • License compliance (security.license_compliance) — Per-project SPDX allow / deny / require lists; uploads can be blocked on non-compliant licenses.
  • Audit log (audit.log) — Append-only audit of all admin + write operations.
  • Air-gapped mode (air_gapped) — Block all outbound calls (webhooks / OSV / Rekor / OTel / Sigstore) for regulated and disconnected deployments.

Core hosting

  • Artifact uploads & write APIs (write.api) — Push artifacts through every format adapter (Maven, npm, Docker, …).
  • Repository creation (repo.create) — Add new local, remote, or virtual repositories.
  • API tokens (token.issue) — Mint personal access tokens for CI lanes.
  • Service accounts (service.account) — Project-scoped service accounts with rotatable tokens.
  • Local user authentication (auth.local) — Username + password break-glass auth path.
  • Team management (user.invite) — SCIM provisioning + manual role bindings.
  • Build-Info & SBOM provenance (build.info) — Standard build-info ingestion + per-build CycloneDX SBOM aggregation.

Operations

  • Retention policies (retention) — Per-repo retention rules with audit-logged sweeps.
  • Backup & restore (backup) — CloudNativePG PITR + S3-Mirror dual-write + weekly verification job.
  • Custom branding (branding) — Operator-uploaded logo + customer banner + help-URL.
  • Documentation site (doc.site) — Bundled VitePress operator + developer docs and the in-app API reference.

Commercial — Premium Integrations + Migration

These features require an active trial or commercial envelope. A trial-lapsed install retains the data behind these features (existing webhook subscriptions, replication peers, OIDC trust policies stay in the database) but the dispatch loops short-circuit until a commercial envelope is applied.

Authentication

  • SAML SSO (sso.saml) — Sign-in via Azure Entra ID, Okta, Auth0, Keycloak. Local auth (Free) remains the fallback.
  • OIDC token exchange (CI) (oidc.exchange) — Exchange a GitLab / GitHub / Kubernetes-SA OIDC token for a short-lived OrbitalReg token.

Replication

  • Geo-Sync push (repl.push) — Push artifacts/metadata to a downstream OrbitalReg replica peer.
  • Geo-Sync pull (repl.pull) — Pull from upstream OrbitalReg / Artifactory mirrors and remote upstream registries.

Automation

  • Webhooks (webhooks) — Outbound HMAC-signed HTTP webhooks.
  • Slack / Teams / SMTP notifications (notify.channels) — Pre-formatted notifications.
  • Background jobs & sweepers (scheduler) — Retention sweeps, OSV sync, license heartbeat, backup recovery, trash reaper. The scheduler still runs security-critical sweepers (CVE auto- quarantine, audit log) regardless of license state — only the commercial-only sweepers (replication push, webhook dispatch) short-circuit.

Migration importers

  • JFrog Artifactory (import.jfrog)
  • Sonatype Nexus (import.nexus)
  • GitHub Packages (import.github)
  • GitLab Package Registry (import.gitlab)
  • Azure Artifacts (import.azure)
  • AWS CodeArtifact (import.aws)
  • Google Artifact Registry (import.google)
  • Bulk import (CSV / tarball) (import.bulk)

What changes when the trial expires?

Under the v1 flat model (≤ commit c0272ca), all writes returned 402 Payment Required after the 30-day implicit trial. Under the v2 tiered model, the gate split is:

Behaviourv1 (flat)v2 (tiered)
Artifact upload (POST /api/v1/artifacts/...)402OK — Free
Repository create (POST /api/v1/repos)402OK — Free
API token mint (POST /api/v1/tokens)402OK — Free
CVE auto-quarantine (background)pausedcontinues — Free
Audit log writes (background)pausedcontinues — Free
Pull-gate enforcement (synchronous)pausedcontinues — Free
Webhook dispatch (background)pausedpaused — Commercial
SAML logingatedgated — Commercial (local auth fallback always works)
Replication push / pull (background)pausedpaused — Commercial
New import job (POST /api/admin/imports/...)402402 — Commercial

FAQ

What happens to my Webhooks at trial expiry?

The webhook subscriptions stay in the database. The dispatch loop polls license.Allow(ctx, license.FeatureWebhooks) on each tick and short-circuits when the state is not active. Apply a commercial envelope and the dispatch loop catches up automatically — no re-configuration needed.

Are existing imported artifacts readable after trial expiry?

Yes. The migration importers are the gated feature; the artifacts they imported are ordinary registry artifacts and remain pull-able forever (the entire pull path is on the Free tier).

Can I disable a Free-tier feature?

Free-tier classification only governs license entitlement, not operator policy. You can still disable features via the relevant admin toggle (Air-gapped mode, Pull-gate Master Toggle, License- compliance per-project policy, etc.). Disabling SAML SSO at the license layer requires a commercial license to enable; turning off local auth is operator policy at the auth-mode level.

What about the Allow(FeatureWriteAPI) check in the chi license.Gate middleware?

license.Gate calls Allow(ctx, FeatureWriteAPI). Under the v2 model, FeatureWriteAPI is on the Free tier so Allow always returns true and Gate becomes a passthrough for /api/v1/... writes. The middleware is left in place because (a) it's the canonical entry point for the clock-rollback detection and request-state stash, and (b) it's the hook for any future tier-changing customisation.

Will my licensed_active install lose anything?

No. A live commercial license satisfies both Active() and the Free- tier short-circuit, so every feature is entitled. The split only matters at trial / license expiry.

How does this interact with the SOC 2 Evidence-Engine?

The Evidence-Engine itself sits inside the Audit / Compliance machinery and runs on the Free tier — auditors can pull the bundle out of an expired-trial install. The CC6.1 / CC7.x evidence the engine collects continues to be written because the underlying sweepers it depends on (audit log, security blocks, scan findings) are all on the Free tier.

Out of scope for v1

  • Per-feature pricing ("webhooks-only add-on"). v1 is a flat Commercial license; modular tier-pricing is a separate larger item.
  • Open-core license switch (e.g. AGPL for Free, Commercial license for Premium). Licensing-text changes have ship-load implications for the codebase.
  • Usage-based pricing ("free under 100 repos"). v1 is flat-fee.
  • Auto-renew via credit card. Out-of-band procurement remains the v1 model — the operator pastes a signed envelope into the License page after talking to procurement.

Released under the Apache-2.0 License.