Skip to content

Jfrogpipelines#3422

Open
naveenku-jfrog wants to merge 32 commits intomasterfrom
jfrogpipelines
Open

Jfrogpipelines#3422
naveenku-jfrog wants to merge 32 commits intomasterfrom
jfrogpipelines

Conversation

@naveenku-jfrog
Copy link
Copy Markdown
Collaborator

  • All tests have passed. If this feature is not already covered by the tests, new tests have been added.
  • The pull request is targeting the master branch.
  • The code has been validated to compile successfully by running go vet ./....
  • The code has been formatted properly using go fmt ./....

fluxxBot and others added 25 commits March 26, 2026 14:13
…ken creation

The previous approach (support-token → OAuth client_credentials) generated
tokens with iss:jfsupport that Artifactory data-plane APIs (api/build,
api/repositories) reject with 403 even when scope=applied-permissions/admin.

Switch to POST /access/api/v1/tokens with -u admin:password basic auth,
which produces a proper user-issued admin token that Artifactory honors.
Also removes the now-unused JFrog CLI + access plugin install and JOIN_KEY variable.

Made-with: Cursor
… auth)

SaaS Artifactory (jfrogdev.org) rejects Basic auth with 401 UNAUTHORIZED.
The OAuth client_credentials approach produced jfsupport-issued tokens
that Artifactory data-plane APIs (api/build, api/repositories) rejected
with 403.

Correct flow: generate support token via join key, then POST to
/access/api/v1/tokens with that token as Bearer to create a proper
user-issued admin token that all Artifactory APIs accept.

Made-with: Cursor
Without username= in the POST body, /access/api/v1/tokens creates a
token for the jfsupport system user (sub: jfac/.../users/jfsupport@...),
which has no Artifactory data-plane permissions -> 403 on api/build etc.

Adding username=${JFROG_ADMIN_USERNAME} makes the token's sub the actual
admin user, so applied-permissions/admin takes effect for all Artifactory APIs.

Made-with: Cursor
Every token we create using the support token as Bearer inherits
iss:jfsupport@<id>, which Artifactory nginx rejects with 403.

The support token itself is issued by the instance's own Access service
(iss:jfac@<instance-id>) because the join-key verification happens on
the instance, not at a central support service. Using it directly avoids
the issuer mismatch that causes 403 on all Artifactory data-plane APIs.

Also adds support token claims logging to make future debugging easier.

Made-with: Cursor
All support-token-based approaches produce iss:jfsupport@... tokens
that SaaS nginx rejects with 403 regardless of sub/scope.

The older /artifactory/api/security/token endpoint accepts Basic auth
(unlike /access/api/v1/tokens) and produces properly instance-issued
tokens (iss:jfac@<instance>) that nginx and Artifactory accept.
Also switches scope to member-of-groups:* to ensure Artifactory
group membership is reflected rather than relying on applied-permissions.

Made-with: Cursor
All previous approaches failed:
- Basic auth on /access/api/v1/tokens -> 401 (disabled on SaaS)
- Support token Bearer on /access/api/v1/tokens -> iss:jfsupport@... -> 403
- Basic auth on /artifactory/api/security/token -> also rejected

The OAuth2 Resource Owner Password Credentials Grant sends credentials
in the request body (no Authorization header), authenticates the user
directly, and produces a properly instance-issued token (iss:jfac@<instance>)
that nginx and Artifactory accept for admin operations.

Made-with: Cursor
All external token generation approaches are blocked on this SaaS platform
(Basic auth disabled, password grant disabled, support tokens produce
iss:jfsupport tokens that nginx rejects with 403).

The jfrog_cli_tests integration token is the platform admin credential
that deployed the checkpoint instance, so it should have admin access.
Verify it works against the instance before writing; fall back to
support-token if not.

Made-with: Cursor
int_jfrog_cli_tests_token was empty in setup_environment because the
step only declared docker_jfrog_io_reader. Integration variables are
only available in a step when that integration is explicitly listed.

Also fix the token verification to use /api/system/version (requires
auth) instead of /api/system/ping (returns 200 without any auth).

Made-with: Cursor
Reverts changes made to the 8 workflow files (artifactoryTests, dockerTests,
goTests, gradleTests, mavenTests, npmTests, nugetTests, pythonTests) back to
the state at cb4891a, removing the workflow_dispatch external-URL inputs and
conditional logic that were added as part of the pipelines.yml task.

Made-with: Cursor
Restores dockerTests.yml, testdata/docker Dockerfiles, utils/tests/container.go,
docker_test.go and maven_test.go to their current master state so that the only
diff in this branch is the pipelines.yml change.

Made-with: Cursor
Two fixes in setup_environment:

1. SKIP_ENV_SETUP=true path was reading int_jfrog_cli_tests_token which
   does not exist as an integration field, causing "token must be set"
   error. Replace with ARTIFACTORY_ADMIN_TOKEN pipeline variable
   (allowCustom: true) that callers set explicitly when pointing at an
   external Artifactory instance.

2. local-rt-setup --rt-version requires a plain semver (X.Y.Z).
   Draft/milestone RT_VERSION values like "draft-7.145.0-m002" cannot
   be parsed or downloaded, causing "strconv.Atoi: invalid syntax".
   Validate the version and fall back to the pinned stable 7.84.17 when
   the format is not X.Y.Z.

Made-with: Cursor
…ETUP path

Instead of requiring a manually provided ARTIFACTORY_ADMIN_TOKEN variable,
generate an admin access token automatically using the integration credentials
(int_jfrog_cli_tests_username / int_jfrog_cli_tests_password) against the
provided ARTIFACTORY_URL. This mirrors exactly what the local-rt-setup path
does after starting the container, requiring no extra inputs from the caller.

Made-with: Cursor
… runs

Pipeline variables set by add_pipeline_variables persist across runs.
A previous SKIP_ENV_SETUP=false run stamped ARTIFACTORY_URL with a
generated warm-env URL (e.g. cli<timestamp>.jfrogdev.org). When the
next run had SKIP_ENV_SETUP=true, that stale URL was used, causing
curl to fail with exit code 6 (cannot resolve host).

Two fixes:
1. Promote ARTIFACTORY_URL to a pipeline-level variable (allowCustom: true)
   so it can be explicitly overridden when triggering with SKIP_ENV_SETUP=true.
2. In setup_cli_test, only call add_pipeline_variables ARTIFACTORY_URL when
   SKIP_ENV_SETUP is NOT true, and fail early with a clear message if the
   caller forgot to set ARTIFACTORY_URL when SKIP_ENV_SETUP=true.

Made-with: Cursor
…image pull

local-rt-setup only handles publicly released semver builds and fails to
parse draft version strings like "draft-7.145.0-m002".

Now setup_environment branches on the RT_VERSION format:
- Plain semver (X.Y.Z)  → local-rt-setup as before (mirrors GitHub Actions)
- Draft/milestone       → pull releases-docker.jfrog.io/jfrog/artifactory-pro:<RT_VERSION>
                          directly and mount the RTLIC license file into the container

This allows testing against specific checkpoint/draft builds without
falling back to a different version.

Made-with: Cursor
…eases.jfrog.io

local-rt-setup rejects draft version strings (e.g. draft-7.145.0-m002) with
strconv.Atoi because its checkArtifactoryVersion only accepts X.X.X format.
The underlying download URL on releases.jfrog.io works with any version string,
so replicate local-rt-setup steps manually (download, extract, license, staging
mode, start) for non-semver versions, bypassing the validation entirely.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants