@jfrog/opencode-jfrog-plugin 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +105 -51
  2. package/dist/index.js +30 -240
  3. package/package.json +6 -6
  4. package/skills/jfrog/SKILL.md +529 -0
  5. package/skills/jfrog/assets/.gitkeep +0 -0
  6. package/skills/jfrog/references/apptrust-entities.md +154 -0
  7. package/skills/jfrog/references/artifactory-api-gaps.md +206 -0
  8. package/skills/jfrog/references/artifactory-aql-syntax.md +656 -0
  9. package/skills/jfrog/references/artifactory-entities.md +236 -0
  10. package/skills/jfrog/references/artifactory-operations.md +178 -0
  11. package/skills/jfrog/references/catalog-entities.md +219 -0
  12. package/skills/jfrog/references/general-bulk-operations-and-agent-patterns.md +93 -0
  13. package/skills/jfrog/references/general-parallel-execution.md +131 -0
  14. package/skills/jfrog/references/general-use-case-hints.md +27 -0
  15. package/skills/jfrog/references/jfrog-brand-html-report.md +98 -0
  16. package/skills/jfrog/references/jfrog-cli-install-upgrade.md +30 -0
  17. package/skills/jfrog/references/jfrog-entity-index.md +112 -0
  18. package/skills/jfrog/references/jfrog-login-flow.md +132 -0
  19. package/skills/jfrog/references/jfrog-url-references.md +51 -0
  20. package/skills/jfrog/references/onemodel-common-patterns.md +323 -0
  21. package/skills/jfrog/references/onemodel-graphql.md +446 -0
  22. package/skills/jfrog/references/onemodel-query-examples.md +753 -0
  23. package/skills/jfrog/references/platform-access-entities.md +200 -0
  24. package/skills/jfrog/references/platform-admin-api-gaps.md +164 -0
  25. package/skills/jfrog/references/platform-admin-operations.md +58 -0
  26. package/skills/jfrog/references/projects-api.md +241 -0
  27. package/skills/jfrog/references/release-lifecycle-entities.md +180 -0
  28. package/skills/jfrog/references/stored-packages-entities.md +165 -0
  29. package/skills/jfrog/references/xray-entities.md +740 -0
  30. package/skills/jfrog/scripts/check-environment.sh +224 -0
  31. package/skills/jfrog/scripts/jfrog-login-register-session.sh +84 -0
  32. package/skills/jfrog/scripts/jfrog-login-save-credentials.sh +128 -0
  33. package/skills/jfrog-package-safety-and-download/SKILL.md +275 -0
  34. package/sync-skills-vendor.json +5 -0
@@ -0,0 +1,740 @@
1
+ # Xray entities
2
+
3
+ When to read this file:
4
+
5
+ - Working with **security scanning**, **vulnerabilities**, or **license compliance**.
6
+ - Configuring or querying **watches**, **policies**, or **violations**.
7
+ - Debugging why a scan produced unexpected results or why violations are missing.
8
+ - Generating **security reports** or **SBOM** data.
9
+ - Searching for **artifacts impacted by a CVE** or containing a specific package.
10
+
11
+ For CLI commands: `jf xr --help`, `jf audit --help`, `jf scan --help`.
12
+ For REST fallback: `jf api /xray/api/v2/...` (see the base skill's *Invoking platform APIs with `jf api`* section).
13
+
14
+ ## Entity relationship overview
15
+
16
+ ```mermaid
17
+ erDiagram
18
+ Watch ||--o{ Resource : "monitors"
19
+ Watch ||--o{ Policy : "applies"
20
+ Policy ||--o{ Rule : "contains"
21
+ Rule ||--|| Condition : "evaluates"
22
+ Rule ||--o{ Action : "triggers"
23
+ Resource ||--o{ Component : "contains (after indexing)"
24
+ Component ||--o{ Vulnerability : "affected by"
25
+ Component ||--|| License : "licensed under"
26
+ Violation }o--|| Policy : "produced by"
27
+ Violation }o--|| Component : "on"
28
+ Violation }o--|| Watch : "detected by"
29
+ IgnoreRule }o--o{ Violation : "suppresses"
30
+ ```
31
+
32
+ The core chain: **Watch** monitors **Resources** using **Policies**. When a
33
+ **Component** in a resource matches a policy **Rule**, Xray generates a
34
+ **Violation**.
35
+
36
+ ## Indexed resources
37
+
38
+ Before Xray can scan or monitor a resource, it must be **indexed**. Indexing
39
+ tells Xray to decompose artifacts in that resource into components and track
40
+ them continuously.
41
+
42
+ Indexable resource types:
43
+ - **Repositories** — local and remote repos (Xray indexes the `-cache` for remote repos)
44
+ - **Builds** — build info records published to Artifactory
45
+ - **Release Bundles** — release bundle versions
46
+
47
+ Indexing is configured in the Xray UI or via the
48
+ `PUT /api/v1/binMgr/builds` / `PUT /api/v1/binMgr/repos` endpoints.
49
+
50
+ ## Components
51
+
52
+ A component is a software package that Xray identifies during scanning.
53
+ Xray decomposes artifacts (JARs, Docker layers, npm tarballs, etc.) into
54
+ their constituent components and maps each to its vulnerability and license
55
+ data.
56
+
57
+ Component identifiers vary by package type:
58
+ - Maven: `gav://group:artifact:version`
59
+ - npm: `npm://package:version`
60
+ - Docker: `docker://image:tag`
61
+ - Python: `pypi://package:version`
62
+ - Go: `go://module:version`
63
+ - Generic: identified by checksum
64
+
65
+ ## Vulnerabilities
66
+
67
+ A vulnerability is a known security issue associated with specific component
68
+ versions.
69
+
70
+ | Field | Description |
71
+ |-------|-------------|
72
+ | `cve` | CVE identifier (e.g. `CVE-2021-44228`) |
73
+ | `xray_id` | JFrog-assigned identifier |
74
+ | `severity` | `Critical`, `High`, `Medium`, `Low`, `Unknown` |
75
+ | `cvss_v3` | Numeric score extracted from the CVSS v3 string (e.g. `"7.2/CVSS:3.1/..."` → `7.2`) |
76
+ | `fixed_versions` | Component versions where the vulnerability is resolved |
77
+ | `references` | Links to advisories and patches |
78
+
79
+ When asked about CVSS score, always use 'cvss_v3' field.
80
+ Xray maintains its own vulnerability database, updated continuously.
81
+
82
+ ## Contextual analysis
83
+
84
+ Contextual analysis evaluates whether a vulnerability is **actually
85
+ reachable** in the specific usage context, going beyond the raw CVE data.
86
+ It considers factors like whether vulnerable code paths are invoked, whether
87
+ mitigating configurations are present, and whether the component is used in a
88
+ way that exposes the vulnerability.
89
+
90
+ The result is an **applicability** status that helps prioritize remediation:
91
+ a Critical CVE that is not applicable in context is lower priority than a
92
+ High CVE that is confirmed applicable.
93
+
94
+ Available for supported package types and vulnerability types; check Xray
95
+ documentation for current coverage.
96
+
97
+ ### Response fields: `applicability` vs `applicability_details`
98
+
99
+ The summary artifact API returns **two** contextual analysis fields per issue.
100
+ They are not interchangeable — use the correct one for the task:
101
+
102
+ | Field | Scope | Use for |
103
+ |-------|-------|---------|
104
+ | `applicability` | Top-level array; only populated when a scanner ran and produced a definitive `true`/`false` result. Many issues have `applicability: null`. | Checking whether a specific CVE is confirmed applicable or not applicable, and reading the `info` field for the human-readable reason. |
105
+ | `applicability_details` | Array present on every issue with exactly one entry per component-vulnerability pair. Always has a `result` string. | **Counting and summarizing** contextual analysis across all issues. This is the authoritative source for breakdowns. |
106
+
107
+ **Always use `applicability_details[].result` for counts and summaries.** The
108
+ top-level `applicability` field is null for issues where no scanner exists or
109
+ where the result is undetermined, which leads to incorrect "not analyzed"
110
+ buckets if used for aggregation.
111
+
112
+ ### `applicability_details` result values
113
+
114
+ | `result` | Meaning | Action |
115
+ |----------|---------|--------|
116
+ | `applicable` | Vulnerable code path is confirmed reachable | Prioritize remediation |
117
+ | `not_applicable` | Vulnerable code path is confirmed unreachable (reason in `applicability[].info`) | Deprioritize; document reason |
118
+ | `undetermined` | Scanner ran but could not determine applicability | Investigate manually |
119
+ | `rescan_required` | Scanner exists but needs a fresh scan to produce a result | Trigger rescan |
120
+ | `upgrade_required` | Scanner needs an Xray version upgrade to analyze this CVE | Upgrade Xray |
121
+ | `not_scanned` | Artifact has not been scanned for contextual analysis yet | Trigger scan |
122
+ | `technology_unsupported` | The artifact's technology/language is not supported by contextual analysis | Rely on severity alone |
123
+ | `not_covered` | No contextual analysis scanner exists for this specific CVE | Rely on severity alone |
124
+
125
+ Report all eight values as distinct categories — do not merge them.
126
+
127
+ ### Summarizing contextual analysis with jq
128
+
129
+ ```bash
130
+ jq '[.artifacts[0].issues[] | .applicability_details[]? | .result]
131
+ | group_by(.) | map({result: .[0], count: length})
132
+ | sort_by(.count) | reverse' /tmp/xray-summary.json
133
+ ```
134
+
135
+ For Docker images, the path format is
136
+ `default/<repo>/<image>/<tag>/manifest.json`:
137
+
138
+ ```bash
139
+ jf api /xray/api/v2/summary/artifact \
140
+ -X POST -H "Content-Type: application/json" \
141
+ -d '{"paths": ["default/my-docker-repo/my-image/my-tag/manifest.json"]}'
142
+ ```
143
+
144
+ ## Licenses
145
+
146
+ License metadata associated with a component, identified by SPDX identifier
147
+ or license name (e.g. `Apache-2.0`, `MIT`, `GPL-3.0`).
148
+
149
+ Used in **license compliance policies** — organizations define which licenses
150
+ are approved, restricted, or banned, and Xray enforces these rules through
151
+ watches and policies.
152
+
153
+ ## Watches
154
+
155
+ A watch is the central **monitoring configuration** that connects resources to
156
+ policies.
157
+
158
+ | Field | Description |
159
+ |-------|-------------|
160
+ | `name` | Unique watch identifier |
161
+ | `resources` | List of resources to monitor (repos, builds, release bundles, or `all-repos`/`all-builds`) |
162
+ | `assigned_policies` | List of policies to evaluate against the watched resources |
163
+ | `active` | Whether the watch is enabled |
164
+ | `project_key` | Optional project scope |
165
+
166
+ When an indexed resource changes (new artifact, updated component data), Xray
167
+ re-evaluates all watches that include that resource.
168
+
169
+ API: `GET/POST/PUT/DELETE /api/v2/watches`
170
+
171
+ ## Policies
172
+
173
+ A policy defines **rules** that Xray evaluates against components found in
174
+ watched resources.
175
+
176
+ | Policy type | Rule evaluates | Common conditions |
177
+ |-------------|---------------|-------------------|
178
+ | **Security** | Vulnerabilities | Min severity, specific CVEs, CVSS score range |
179
+ | **License** | Licenses | Allowed/banned license list |
180
+ | **Operational risk** | Package metadata | End-of-life, no new versions, low activity |
181
+
182
+ Each rule has:
183
+ - **Condition** — what triggers the rule (severity ≥ High, license in banned list, etc.)
184
+ - **Actions** — what happens on match: generate violation, block download, fail build, send notification
185
+
186
+ API: `GET/POST/PUT/DELETE /api/v2/policies`
187
+
188
+ ## Violations
189
+
190
+ A violation is generated when a component in a watched resource matches a
191
+ policy rule.
192
+
193
+ | Field | Description |
194
+ |-------|-------------|
195
+ | `violation_type` | `Security`, `License`, or `Operational_Risk` |
196
+ | `watch_name` | Watch that detected the violation |
197
+ | `policy_name` | Policy whose rule matched |
198
+ | `infected_components` | Array of affected component IDs (e.g. `["npm://lodash:4.17.19"]`) |
199
+ | `impacted_artifacts` | Array of artifact paths affected |
200
+ | `severity` | Inherited from the vulnerability or rule |
201
+ | `issue_id` | Xray issue ID (e.g. `XRAY-140562`) |
202
+ | `created` | Timestamp |
203
+ | `description` | Violation description (markdown from Xray 3.42.3+) |
204
+ | `matched_policies` | Policies that matched |
205
+
206
+ Violations are the primary output that security teams act on. They accumulate
207
+ until the underlying component is updated, the artifact is removed, or the
208
+ violation is suppressed via an ignore rule.
209
+
210
+ Starting from Xray 3.42.3, JFrog Security CVE Research and Enrichment data is
211
+ included in the response. The `short_description`, `full_description`, and
212
+ `remediation` fields are markdown.
213
+
214
+ ### API: `POST /api/v1/violations`
215
+
216
+ Search violations with filters and pagination. Requires Read permissions.
217
+
218
+ **Performance warning:** On large or shared instances the violations API can
219
+ hang indefinitely when called without narrowing filters. Always include at
220
+ least one of `watch_name` or `created_from` (or both) to avoid timeouts. There
221
+ is no server-side query timeout — the request simply never returns. If you need
222
+ violations across all watches, iterate per-watch rather than issuing a single
223
+ unfiltered call. The API also has no `package_type` filter, so filtering by
224
+ component type (e.g. npm-only) must be done client-side on `infected_components`
225
+ or by querying watches that cover specific repository types.
226
+
227
+ ```bash
228
+ jf api /xray/api/v1/violations \
229
+ -X POST -H "Content-Type: application/json" \
230
+ -d '{
231
+ "filters": {
232
+ "violation_type": "Security",
233
+ "watch_name": "<watch-name>",
234
+ "min_severity": "High",
235
+ "cve_id": "CVE-2021-23337"
236
+ },
237
+ "pagination": {
238
+ "limit": 50,
239
+ "offset": 1
240
+ }
241
+ }'
242
+ ```
243
+
244
+ To scope to a project, add `?projectKey=<key>` as a query parameter.
245
+
246
+ #### Filter fields
247
+
248
+ | Filter | Type | Description |
249
+ |--------|------|-------------|
250
+ | `name_contains` | string | Filter where description contains this string |
251
+ | `include_details` | boolean | Include additional violation detail properties |
252
+ | `violation_type` | enum | `Security`, `License`, or `Operational_Risk` |
253
+ | `watch_name` | string | Filter by watch name |
254
+ | `min_severity` | enum | `Critical`, `High`, `Medium`, `Low`, `Information`, `Unknown` |
255
+ | `created_from` | date-time | RFC 3339 timestamp — violations created after this time |
256
+ | `created_until` | date-time | RFC 3339 timestamp — violations created before this time |
257
+ | `issue_id` | string | Filter by Xray issue ID (e.g. `XRAY-94620`) |
258
+ | `cve_id` | string | Filter by CVE ID (e.g. `CVE-2019-17531`) |
259
+ | `resources` | object | Filter by specific resources (see below) |
260
+
261
+ #### Resource filters
262
+
263
+ Narrow violations to specific artifacts, builds, or release bundles:
264
+
265
+ ```json
266
+ {
267
+ "filters": {
268
+ "violation_type": "Security",
269
+ "resources": {
270
+ "artifacts": [{ "repo": "npm-local", "path": "lodash/-/lodash-4.17.19.tgz" }],
271
+ "builds": [{ "name": "my-build", "number": "42", "project": "my-proj" }],
272
+ "release_bundles_v2": [{ "name": "my-rb", "version": "1.0", "project": "my-proj" }]
273
+ }
274
+ }
275
+ }
276
+ ```
277
+
278
+ | Resource type | Fields |
279
+ |---------------|--------|
280
+ | `artifacts` | `repo`, `path` |
281
+ | `builds` | `name`, `number`, `project` |
282
+ | `release_bundles` | `name`, `version` |
283
+ | `release_bundles_v2` | `name`, `version`, `project` |
284
+
285
+ **There is no `component` filter.** To find violations for a specific component
286
+ (e.g. `npm://lodash:4.17.19`), filter by the resource that contains it
287
+ (artifact path, build, or release bundle) or use `cve_id`/`issue_id` to
288
+ narrow by vulnerability, then inspect `infected_components` in the response.
289
+
290
+ ## Ignore rules
291
+
292
+ An ignore rule suppresses specific violations so they no longer surface in
293
+ reports or block downloads.
294
+
295
+ Ignore rules can be scoped by:
296
+ - **Vulnerability** — specific CVE or Xray ID
297
+ - **Component** — specific component and version
298
+ - **Artifact** — specific repo path
299
+ - **Docker layer** — specific layer in a Docker image
300
+ - **Build** — specific build name
301
+ - **Release bundle** — specific bundle name/version
302
+
303
+ Each rule has optional `expires_at` and `notes` fields.
304
+
305
+ API: `GET/POST/DELETE /api/v1/ignore_rules`
306
+
307
+ **Version note:** The ignore rules API uses **v1** only. The `/api/v2/ignore_rules`
308
+ endpoint does not exist and returns 404.
309
+
310
+ ## Summary APIs
311
+
312
+ On-demand security, license, and operational risk lookups for artifacts
313
+ stored in Artifactory. Use **only for security and compliance queries**.
314
+
315
+ **Which endpoint to use:**
316
+ - Know the Artifactory path and the repo is indexed → `/api/v2/summary/artifact`
317
+ - Know the component ID (GAV, npm, pypi) or the artifact is not indexed → `/api/v1/summary/component`
318
+ - Not sure if indexed → try component summary first (always works if the component exists in Xray's DB)
319
+
320
+ **Prerequisite — Xray indexing:** These endpoints return data only if the
321
+ artifact's repository is indexed by Xray **and** Xray has already scanned
322
+ the artifact. An artifact can exist in Artifactory while Xray knows nothing
323
+ about it — either because the repository was not marked for indexing, or
324
+ because Xray has not yet processed it. Empty results do **not** mean the
325
+ artifact is clean; they mean Xray has no data. When results are empty,
326
+ report that the artifact may not be indexed rather than declaring it
327
+ vulnerability-free.
328
+
329
+ ### `/api/v1/summary/component`
330
+
331
+ **v1 only — there is no `/api/v2/summary/component`.** Calling v2 returns 404.
332
+
333
+ Query by component identifier. Returns `issues[]`, `licenses[]`, and
334
+ `operational_risks[]` per component. Useful for looking up vulnerabilities
335
+ affecting a specific package version without needing to know its Artifactory
336
+ path, or when the artifact's repository is not indexed by Xray (making the
337
+ artifact summary endpoint return empty).
338
+
339
+ The request body uses `component_details` (an array of objects with
340
+ `component_id`), **not** `component_ids`.
341
+
342
+ ```bash
343
+ jf api /xray/api/v1/summary/component \
344
+ -X POST -H "Content-Type: application/json" \
345
+ -d '{"component_details": [{"component_id": "npm://lodash:4.17.19"}]}'
346
+ ```
347
+
348
+ Component ID format follows the same convention as component identifiers
349
+ elsewhere in Xray (see [Components](#components) above):
350
+ - npm: `npm://package:version`
351
+ - Maven: `gav://group:artifact:version`
352
+ - Python: `pypi://package:version`
353
+ - Go: `go://module:version`
354
+ - Docker: `docker://image:tag`
355
+
356
+ ### `/api/v1/summary/artifact` and `/api/v2/summary/artifact`
357
+
358
+ Query by Artifactory path or SHA-256 checksum. Returns `issues[]`,
359
+ `licenses[]`, and `operational_risks[]` per artifact.
360
+
361
+ - **v1** — base response with vulnerability, license, and operational risk data
362
+ - **v2** — same structure plus `components[]` inside each issue, containing
363
+ `component_id`, `version`, `pkg_type`, and `fixed_versions[]`
364
+
365
+ Use v2 when you need to know which component is affected and what version
366
+ fixes the vulnerability. Use v1 when fixed-version data is not needed.
367
+
368
+ Either `paths` or `checksums` must be provided in the request body. If both
369
+ are provided, checksums are ignored.
370
+
371
+ **Paths must point to specific artifacts, not repositories.** A path like
372
+ `default/my-repo/com/example/lib-1.0.jar` works; a repo-level path like
373
+ `default/my-repo` returns empty results. To get a security summary for an
374
+ entire repository, query individual artifact paths (discovered via AQL or
375
+ `jf rt search`) or use the violations API / reports API instead.
376
+
377
+ ```bash
378
+ # v1 — by path
379
+ jf api /xray/api/v1/summary/artifact \
380
+ -X POST -H "Content-Type: application/json" \
381
+ -d '{"paths": ["default/npm-local/moment-2.29.3.tar.gz"]}'
382
+
383
+ # v2 — by checksum
384
+ jf api /xray/api/v2/summary/artifact \
385
+ -X POST -H "Content-Type: application/json" \
386
+ -d '{"checksums": ["8240b88c..."]}'
387
+ ```
388
+
389
+ See `SKILL.md` § *Invoking platform APIs with `jf api`* for the full response schema.
390
+
391
+ ## Impacted resources search
392
+
393
+ `GET /api/v2/search/impactedResources` — find all resources (artifacts, builds,
394
+ release bundles) impacted by a specific CVE **or** containing a specific
395
+ package. **Preferred over `/api/v1/component/searchByCves`** when you need
396
+ artifact paths, repos, and scan dates rather than just component identifiers.
397
+
398
+ Requires the **Reports Manager** permission and the **SBOM Service** (returns
399
+ 403 if SBOM is disabled on self-hosted). Available since Xray 3.131.
400
+
401
+ ### Search modes
402
+
403
+ | Mode | Required params | Use case |
404
+ |------|----------------|----------|
405
+ | By vulnerability | `vulnerability` | "Which artifacts are affected by CVE-2021-23337?" |
406
+ | By package version | `name` + `type` + `version` | "Where is log4j-core 2.14.1 used?" |
407
+ | By package (all versions) | `name` + `type` | "Where is lodash used, any version?" |
408
+
409
+ All parameters are **query string** params (not request body):
410
+
411
+ | Param | Description |
412
+ |-------|-------------|
413
+ | `vulnerability` | CVE ID (`CVE-YYYY-NNNNN`) or Xray ID (`XRAY-N`) |
414
+ | `name` | Package name |
415
+ | `type` | Package type (`npm`, `maven`, `pypi`, `go`, etc.) |
416
+ | `version` | Package version (optional — omit for all versions) |
417
+ | `namespace` | Package namespace (default: `public`; use for Maven group IDs) |
418
+ | `ecosystem` | Package ecosystem (default: `generic`) |
419
+ | `limit` | Max results per page (default 1000, max 10000) |
420
+ | `last_key` | Pagination cursor from previous response |
421
+
422
+ ### Response structure
423
+
424
+ ```json
425
+ {
426
+ "result": [
427
+ {
428
+ "type": "Artifact",
429
+ "name": "app.jar",
430
+ "path": "libs-release-local/com/example/app/1.0.0/app-1.0.0.jar",
431
+ "repo": "libs-release-local",
432
+ "scan_date": "2024-01-15T10:30:00Z",
433
+ "artifact_pkg_version": {
434
+ "type": "maven",
435
+ "name": "app",
436
+ "namespace": "com.example",
437
+ "version": "1.0.0",
438
+ "ecosystem": "generic"
439
+ },
440
+ "impacted_pkg_version": {
441
+ "type": "maven",
442
+ "name": "log4j-core",
443
+ "namespace": "org.apache.logging.log4j",
444
+ "version": "2.14.1",
445
+ "ecosystem": "generic"
446
+ }
447
+ }
448
+ ],
449
+ "last_key": "eyJwcmltYXJ5S2V5..."
450
+ }
451
+ ```
452
+
453
+ Key response fields:
454
+
455
+ | Field | Description |
456
+ |-------|-------------|
457
+ | `type` | `Artifact`, `Build`, `ReleaseBundle`, `ReleaseBundleV2`, `AppVersion`, or `Component` |
458
+ | `name` | Resource name |
459
+ | `path` | Artifact path in repo (artifacts only) |
460
+ | `repo` | Repository name (artifacts only) |
461
+ | `scan_date` | ISO 8601 timestamp of last scan |
462
+ | `artifact_pkg_version` | Package identity of the artifact itself |
463
+ | `impacted_pkg_version` | The vulnerable/searched package found inside the artifact |
464
+ | `last_key` | Pagination cursor — empty string means no more pages |
465
+
466
+ ### CLI examples
467
+
468
+ ```bash
469
+ # Mode 1: all artifacts affected by a CVE
470
+ jf api "/xray/api/v2/search/impactedResources?vulnerability=CVE-2021-23337&limit=100"
471
+
472
+ # Mode 2: artifacts containing a specific package version
473
+ jf api "/xray/api/v2/search/impactedResources?name=log4j-core&type=maven&version=2.14.1&namespace=org.apache.logging.log4j"
474
+
475
+ # Mode 3: artifacts containing any version of a package
476
+ jf api "/xray/api/v2/search/impactedResources?name=lodash&type=npm"
477
+ ```
478
+
479
+ ### Pagination
480
+
481
+ Page through results using `last_key`:
482
+
483
+ ```bash
484
+ # First page
485
+ RESP=$(jf api "/xray/api/v2/search/impactedResources?vulnerability=CVE-2021-23337&limit=1000")
486
+ LAST_KEY=$(echo "$RESP" | jq -r '.last_key')
487
+
488
+ # Subsequent pages (loop until last_key is empty)
489
+ jf api "/xray/api/v2/search/impactedResources?vulnerability=CVE-2021-23337&limit=1000&last_key=$LAST_KEY"
490
+ ```
491
+
492
+ ## Exposures (Advanced Security)
493
+
494
+ Exposures are actionable security findings produced by JFrog Advanced Security
495
+ that go beyond traditional vulnerability scanning. While vulnerabilities
496
+ identify known CVEs in software components, exposures detect **real-world
497
+ exploitable threats** in binaries, source code, and configurations — such as
498
+ hard-coded secrets, insecure Infrastructure-as-Code templates, and service
499
+ misconfigurations. This helps prioritize critical fixes over theoretical risks.
500
+
501
+ Exposures require **JFrog Advanced Security** to be enabled on the Xray
502
+ instance. Artifacts must be in an indexed repository and already scanned.
503
+
504
+ After getting results, keep only results with status==`to_fix` unless asked otherwise.
505
+
506
+ ### Exposure categories
507
+
508
+ | Category | Path segment | What it detects |
509
+ |----------|-------------|-----------------|
510
+ | **Secrets** | `secrets` | Hard-coded credentials, API keys, tokens, private keys embedded in code or binaries |
511
+ | **Applications** | `applications` | Application-level security risks (e.g. insecure code patterns, vulnerable configurations) |
512
+ | **Services** | `services` | Service misconfigurations (e.g. open ports, insecure protocols, weak TLS settings) |
513
+ | **IaC** | `iac` | Infrastructure-as-Code issues in Terraform, CloudFormation, Kubernetes manifests, etc. |
514
+
515
+ ### Exposure result fields
516
+
517
+ | Field | Description |
518
+ |-------|-------------|
519
+ | `id` | Exposure identifier (e.g. `EXP-1519-00001`) |
520
+ | `status` | Current status (e.g. `to_fix`) |
521
+ | `jfrog_severity` | JFrog-assigned severity: `critical`, `high`, `medium`, `low` |
522
+ | `description` | Human-readable description of the finding |
523
+ | `abbreviation` | Short rule identifier (e.g. `REQ.PYTHON.HARDCODED-SECRETS`) |
524
+ | `cwe` | Associated CWE (`cwe_id` and `cwe_name`) |
525
+ | `outcomes` | Potential impact if exploited (e.g. `["Credential extraction"]`) |
526
+ | `fix_cost` | Estimated remediation effort: `low`, `medium`, `high` |
527
+
528
+ ### API: Get exposure results
529
+
530
+ `GET /api/v1/{category}/results` — returns a paginated list of exposure scan
531
+ results for a specific artifact. Available since Xray 3.59.4.
532
+
533
+ | Parameter | Required | Description |
534
+ |-----------|----------|-------------|
535
+ | `{category}` (path) | Yes | One of: `secrets`, `applications`, `services`, `iac` |
536
+ | `repo` (query) | Yes | Repository name |
537
+ | `path` (query) | Yes | Path to the artifact within the repository |
538
+ | `page_num` (query) | No | Page number, starting from 1 (default: 1) |
539
+ | `num_of_rows` (query) | No | Results per page (default: 10) |
540
+ | `order_by` (query) | No | Sort field: `status`, `jfrog_severity`, `exposure_id`, `description`, `file_path`, `cve`, `fix_cost`, `outcomes` |
541
+ | `direction` (query) | No | Sort direction: `asc` or `desc` |
542
+ | `search` (query) | No | Free-text search matched against descriptions |
543
+
544
+ Response:
545
+
546
+ ```json
547
+ {
548
+ "data": [
549
+ {
550
+ "status": "to_fix",
551
+ "jfrog_severity": "low",
552
+ "id": "EXP-1519-00001",
553
+ "description": "Hardcoded random buffer was found (Python)",
554
+ "abbreviation": "REQ.PYTHON.HARDCODED-SECRETS",
555
+ "cwe": { "cwe_id": "CWE-798", "cwe_name": "Use of Hard-coded Credentials" },
556
+ "outcomes": ["Credential extraction"],
557
+ "fix_cost": "low"
558
+ }
559
+ ],
560
+ "total_count": 1
561
+ }
562
+ ```
563
+
564
+ ### CLI examples
565
+
566
+ ```bash
567
+ # Secrets exposures for an artifact
568
+ jf api "/xray/api/v1/secrets/results?repo=my-docker-local&path=my-image/latest/manifest.json&num_of_rows=50"
569
+
570
+ # IaC exposures, sorted by severity descending
571
+ jf api "/xray/api/v1/iac/results?repo=my-repo&path=terraform/main.tf&order_by=jfrog_severity&direction=desc"
572
+
573
+ # Application exposures with search filter
574
+ jf api "/xray/api/v1/applications/results?repo=npm-local&path=app-1.0.0.tgz&search=injection"
575
+
576
+ # Service misconfigurations
577
+ jf api "/xray/api/v1/services/results?repo=docker-local&path=my-service/1.0/manifest.json"
578
+ ```
579
+
580
+ ### Paginating exposure results
581
+
582
+ ```bash
583
+ PAGE=1
584
+ while true; do
585
+ RESP=$(jf api "/xray/api/v1/secrets/results?repo=my-repo&path=my-artifact&page_num=$PAGE&num_of_rows=100")
586
+ echo "$RESP" | jq '.data[]'
587
+ TOTAL=$(echo "$RESP" | jq '.total_count')
588
+ COUNT=$(echo "$RESP" | jq '.data | length')
589
+ [ "$COUNT" -eq 0 ] && break
590
+ PAGE=$((PAGE + 1))
591
+ done
592
+ ```
593
+
594
+ ### Discovering artifact paths for exposures
595
+
596
+ The exposures API requires a specific artifact `path` — it cannot scan an
597
+ entire repository in one call. For Docker images the scannable artifact is
598
+ the **manifest**: `<image>/<tag>/manifest.json`. For other package types use
599
+ the artifact filename (e.g. `app-1.0.0.tgz`, `lib-2.3.jar`).
600
+
601
+ When the caller doesn't know the artifact paths, discover them first with AQL
602
+ and then fan out to the exposures endpoint.
603
+
604
+ **Docker repos** — find all manifests:
605
+
606
+ ```bash
607
+ OUT=/tmp/manifests-$$.json
608
+ jf api /artifactory/api/search/aql \
609
+ -X POST -H "Content-Type: text/plain" \
610
+ -d 'items.find({"repo":"my-docker-local","name":"manifest.json","path":{"$nmatch":"*_uploads*"}}).include("repo","path","name")' \
611
+ > "$OUT"
612
+ echo "$OUT"
613
+ jq -r '.results[] | .path + "/" + .name' "$OUT"
614
+ ```
615
+
616
+ The `$nmatch` filter excludes temporary upload layers. Each result path
617
+ (e.g. `my-image/latest/manifest.json`) can be passed directly to the
618
+ exposures API's `path` parameter.
619
+
620
+ **Non-Docker repos** — find scannable artifacts:
621
+
622
+ ```bash
623
+ jf api /artifactory/api/search/aql \
624
+ -X POST -H "Content-Type: text/plain" \
625
+ -d 'items.find({"repo":"npm-local","type":"file"}).include("repo","path","name").sort({"$desc":["size"]}).limit(20)'
626
+ ```
627
+
628
+ ## Curation audit events
629
+
630
+ Curation audits every package check that passes through a curated repository
631
+ and records whether the download was **approved** or **blocked**. The audit
632
+ log also captures **dry-run** policy evaluations (policies configured in
633
+ dry-run mode).
634
+
635
+ ### Get audit logs
636
+
637
+ ```
638
+ GET /xray/api/v1/curation/audit/packages
639
+ ```
640
+
641
+ Since 3.82.x. Requires `VIEW_POLICIES` permission.
642
+
643
+ **Time-range limit:** The maximum allowed window between `created_at_start` and
644
+ `created_at_end` is **168 hours (7 days)**. Requests exceeding this return an
645
+ error (`"Maximum allowed duration is 168 hours"`). To query longer periods,
646
+ split into consecutive 7-day (or shorter) chunks and merge results client-side.
647
+ Use 6-day windows to avoid edge-case overflows from hour-level rounding.
648
+
649
+ | Parameter | Type | Default | Description |
650
+ |-----------|------|---------|-------------|
651
+ | `order_by` | string | `id` | Column to sort by |
652
+ | `direction` | string | `desc` | Sort direction (`asc` / `desc`) |
653
+ | `num_of_rows` | int | `100` | Max rows (1–2000) |
654
+ | `created_at_start` | datetime | 7 days ago | Start of time range (ISO 8601, e.g. `2023-08-13T22:00:00.000Z`). Max span to `created_at_end`: 168 hours |
655
+ | `created_at_end` | datetime | today | End of time range. Max span from `created_at_start`: 168 hours |
656
+ | `offset` | int | `0` | Pagination offset |
657
+ | `include_total` | boolean | `false` | Include `total_count` in response metadata |
658
+ | `dry_run` | boolean | `false` | `false` = real audit events (non-dry-run policies, including blocking/bypassed/waived — the Blocked/Approved tab in the UI). `true` = dry-run policy events (one per policy — the Dry Run tab in the UI) |
659
+ | `format` | string | `json` | `json` or `csv`. With `csv`: response is a zip containing `audit_packages.csv` (or `audit_packages_incomplete.csv` if >500k events). `include_total=true` is not allowed with csv. Pagination counts events, not csv rows — each event can flatten into multiple rows (one per policy) |
660
+
661
+ Example request:
662
+
663
+ ```bash
664
+ jf api "/xray/api/v1/curation/audit/packages?order_by=id&direction=desc&num_of_rows=100&created_at_start=2023-07-20T22:00:00.000Z&created_at_end=2023-07-26T22:00:00.000Z&include_total=true&offset=0"
665
+ ```
666
+
667
+ Response shape (key fields):
668
+
669
+ ```json
670
+ {
671
+ "data": [
672
+ {
673
+ "id": 174,
674
+ "created_at": "2023-08-30T05:45:52Z",
675
+ "action": "blocked",
676
+ "package_type": "Docker",
677
+ "package_name": "pumevnezdiroorg/drupal",
678
+ "package_version": "latest",
679
+ "curated_repository_name": "aviv-docker1",
680
+ "username": "admin",
681
+ "origin_repository_server_name": "z0curdocktest",
682
+ "public_repo_url": "https://registry-1.docker.io",
683
+ "public_repo_name": "Docker Hub",
684
+ "policies": [
685
+ {
686
+ "policy_name": "onlyOffical",
687
+ "policy_id": 3,
688
+ "dry_run": false,
689
+ "condition_name": "Image is not Docker Hub official",
690
+ "condition_category": "operational"
691
+ }
692
+ ]
693
+ }
694
+ ],
695
+ "meta": {
696
+ "total_count": 174,
697
+ "result_count": 1,
698
+ "next_offset": 1,
699
+ "order_by": "id",
700
+ "direction": "desc",
701
+ "num_of_rows": 1,
702
+ "offset": 0,
703
+ "include_total": true
704
+ }
705
+ }
706
+ ```
707
+
708
+ The `action` field is either `"blocked"` or `"approved"`. Each event includes
709
+ the `policies` array listing every non-dry-run policy that affected the
710
+ decision (blocking, bypassed, and waived).
711
+
712
+ ### Pagination
713
+
714
+ Use `offset` + `num_of_rows` for pagination. The `meta.next_offset` field
715
+ gives the offset for the next page. Set `include_total=true` on the first
716
+ request to know the total number of events.
717
+
718
+ ### Common use cases
719
+
720
+ - **Export all blocked packages**: paginate with `num_of_rows=2000`, filter
721
+ results by `action == "blocked"`.
722
+ - **Dry-run analysis**: set `dry_run=true` to see what *would* be blocked if
723
+ dry-run policies were enforced.
724
+ - **CSV export**: set `format=csv` for bulk export. Narrow the time range if
725
+ the response indicates incomplete data (`audit_packages_incomplete.csv`).
726
+
727
+ ## Reports
728
+
729
+ On-demand analysis over a defined scope, produced asynchronously.
730
+
731
+ | Report type | Analyzes |
732
+ |-------------|----------|
733
+ | **Vulnerabilities** | CVEs affecting components in scope |
734
+ | **Licenses** | License compliance across components |
735
+ | **Violations** | Policy violations across watched resources |
736
+ | **Operational risks** | Package health metrics |
737
+
738
+ Reports can be scoped to repositories, builds, release bundles, or projects.
739
+ They are generated via `POST /api/v1/reports/{type}` and retrieved after
740
+ completion.