JFrog Artifactory integration
OSA Proxy supports static routes to JFrog Artifactory repositories and automatic repository discovery through the Artifactory inventory API. This page covers discovery configuration, client URL construction, repository context propagation, and block response behavior.
Automatic repository discovery
Runtime discovery retrieves the Artifactory repository list and creates dynamic routes for matching entries. Repositories do not need to be listed one by one in static ecosystem sections such as npm, maven, or pypi.
Discovery runs at startup and periodically afterwards. For every repository, OSA Proxy determines the ecosystem, builds the upstream URL, and applies the first matching repository-routing rule.
When Configuration Store is disabled, changes in osa-proxy.yml require a
restart. With Configuration Store enabled, managed discovery fields such as
enabled, repository-types, repository-routing, route-mode, and the
refresh interval can be changed through the Admin API
without a restart. Credentials and base-url remain bootstrap-owned and require
a restart.
Access requirements
Create a service account or access token that can:
- call
GET /artifactory/api/repositoriesto retrieve the inventory; - view the repositories that must be included in the API response.
In the following commands, ARTIFACTORY_BASE_URL is the platform URL without /artifactory, for example https://jfrog.example.com.
Verify Basic auth:
Verify an access token:
Discovery client credentials are used only for the inventory API. OSA Proxy does not automatically add them to package requests sent to discovered upstream repositories. Configure private package access separately, for example with incoming client credentials, anonymous read access, or a trusted reverse proxy.
Discovery configuration
Select exactly one authentication mode:
- Basic auth: both
usernameandpasswordare set andaccess-tokenis empty; - Bearer token:
access-tokenis set and bothusernameandpasswordare empty.
Set base-url without an arbitrary path. Both https://jfrog.example.com and https://jfrog.example.com/artifactory are normalized to the Artifactory root.
Allowed repository classes in repository-types are local, remote, virtual, and federated.
Selecting repositories
Every package type requires a separate rule. package-type does not support wildcards.
Omit name-regex to include all repositories of one type:
Key filters use Go regular expressions (RE2), not globs. Anchors ^ and $ are recommended:
Rules for one package type are evaluated from top to bottom. If a repository matches several rules, the first rule wins. Put specific expressions before a general fallback rule.
The scan-manifest, scan-package, remove-blocked-versions, work-mode, url-encoded-config, distro, and file-type-filter fields have the same meaning as in static ecosystem configuration. An unsupported combination causes a configuration error or rejects the discovery snapshot.
Supported formats
Artifactory discovery supports:
npm, maven, nuget, pypi, composer, cocoapods, swift, ruby, r, conan, go, hex, debian, alpine, and rpm.
The inventory formats gems, yum, and CRAN are normalized to ruby, rpm, and r. Docker and unknown package types are not discovered.
For Hex with scan-manifest: true, configure a shared OSA Proxy RSA key through hex.signing-private-key or hex.signing-private-key-file:
OSA Proxy retrieves the Artifactory public key from the upstream URL with the /public_key suffix, verifies the upstream signature, applies policies, and signs the modified manifest with its own RSA key. Clients retrieve the OSA Proxy public key from /{dynamic-route}/public_key. With scan-manifest disabled, signed metadata is proxied without modification. Key input methods and variable precedence are documented in Hex configuration.
Client routes
With route-mode: native, the client path mirrors the Artifactory URL:
/artifactory/{key}for Maven, R, Debian, Alpine, and RPM;/artifactory/api/npm/{key},/artifactory/api/pypi/{key},/artifactory/api/swift/{key}, and equivalent API paths for the other formats.
For example, a discovered npm repository with the npm-remote key is available at:
The client or reverse proxy only needs to replace the Artifactory host with the OSA Proxy host while preserving the path.
With route-mode: flat, OSA Proxy uses the legacy /{key} route. A route-prefix in an individual routing rule takes precedence over route-mode; the resulting path is /{route-prefix}/{key}.
Static routes from ecosystem sections have the highest priority. If a discovered repository path conflicts with a static route, the dynamic route is skipped while the other discovered repositories continue to work.
Repository context in the URL
The url-encoded-config: true setting allows URL-safe Base64 metadata containing the repository manager URL, repository name, and user to be passed in a request. This is used for CodeScoring policies bound to a specific Artifactory repository context.
For a native route, the encoded segment is placed after the complete repository path:
The object format and encoding examples are documented in Base64 URL configuration.
Block responses
Requests containing the Origin-Artifactory or X-Artifactory-Originated header receive JFrog Curation-compatible JSON, the required curation headers, and HTTP 403. Header values are not interpreted; the response mode is enabled by the presence of either header.
Artifactory returns its standard response to the client and does not propagate the custom HTTP status line from OSA Proxy. Therefore, do not rely on codescoring.enable-status-line to display the Artifactory block reason to users.
Refresh and diagnostics
The first inventory sync runs at startup. Further syncs run at refresh.interval with up to 10% jitter. Added and removed repositories are applied without a restart.
When an HTTP, decoding, or route construction error occurs, OSA Proxy keeps the last successful snapshot. A successful empty inventory removes all dynamic Artifactory routes. The snapshot is stored in memory only; after a restart with an unavailable Artifactory, only static routes are available.
The /healthz endpoint checks the OSA Proxy process, not discovery status. Use these metrics:
artifactory_discovery_syncs_total;artifactory_discovery_sync_duration_seconds;artifactory_discovery_last_success_timestamp_seconds;artifactory_discovery_active_repositories;artifactory_discovery_repository_changes_total.
The other supported repository manager is documented in Nexus Repository integration.
