@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.
- package/README.md +105 -51
- package/dist/index.js +30 -240
- package/package.json +6 -6
- package/skills/jfrog/SKILL.md +529 -0
- package/skills/jfrog/assets/.gitkeep +0 -0
- package/skills/jfrog/references/apptrust-entities.md +154 -0
- package/skills/jfrog/references/artifactory-api-gaps.md +206 -0
- package/skills/jfrog/references/artifactory-aql-syntax.md +656 -0
- package/skills/jfrog/references/artifactory-entities.md +236 -0
- package/skills/jfrog/references/artifactory-operations.md +178 -0
- package/skills/jfrog/references/catalog-entities.md +219 -0
- package/skills/jfrog/references/general-bulk-operations-and-agent-patterns.md +93 -0
- package/skills/jfrog/references/general-parallel-execution.md +131 -0
- package/skills/jfrog/references/general-use-case-hints.md +27 -0
- package/skills/jfrog/references/jfrog-brand-html-report.md +98 -0
- package/skills/jfrog/references/jfrog-cli-install-upgrade.md +30 -0
- package/skills/jfrog/references/jfrog-entity-index.md +112 -0
- package/skills/jfrog/references/jfrog-login-flow.md +132 -0
- package/skills/jfrog/references/jfrog-url-references.md +51 -0
- package/skills/jfrog/references/onemodel-common-patterns.md +323 -0
- package/skills/jfrog/references/onemodel-graphql.md +446 -0
- package/skills/jfrog/references/onemodel-query-examples.md +753 -0
- package/skills/jfrog/references/platform-access-entities.md +200 -0
- package/skills/jfrog/references/platform-admin-api-gaps.md +164 -0
- package/skills/jfrog/references/platform-admin-operations.md +58 -0
- package/skills/jfrog/references/projects-api.md +241 -0
- package/skills/jfrog/references/release-lifecycle-entities.md +180 -0
- package/skills/jfrog/references/stored-packages-entities.md +165 -0
- package/skills/jfrog/references/xray-entities.md +740 -0
- package/skills/jfrog/scripts/check-environment.sh +224 -0
- package/skills/jfrog/scripts/jfrog-login-register-session.sh +84 -0
- package/skills/jfrog/scripts/jfrog-login-save-credentials.sh +128 -0
- package/skills/jfrog-package-safety-and-download/SKILL.md +275 -0
- 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.
|