Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
fc52f69f81
commit
07d9675a80
|
|
@ -43,4 +43,4 @@ notify-pipeline-failure:
|
|||
variables:
|
||||
NOTIFY_CHANNEL: "${NOTIFY_PIPELINE_FAILURE_CHANNEL}"
|
||||
script:
|
||||
- scripts/slack ${NOTIFY_CHANNEL} "❌ `${CI_COMMIT_REF_NAME}` pipeline failed! See ${CI_PIPELINE_URL}" ci_failing "notify-pipeline-failure"
|
||||
- scripts/slack ${NOTIFY_CHANNEL} "❌ \`${CI_COMMIT_REF_NAME}\` pipeline failed! See ${CI_PIPELINE_URL}" ci_failing "notify-pipeline-failure"
|
||||
|
|
|
|||
|
|
@ -2,47 +2,7 @@
|
|||
# Cop supports --auto-correct.
|
||||
Layout/FirstArrayElementIndentation:
|
||||
Exclude:
|
||||
- 'config/initializers/postgres_partitioning.rb'
|
||||
- 'db/post_migrate/20210812013042_remove_duplicate_project_authorizations.rb'
|
||||
- 'ee/app/controllers/groups/settings/reporting_controller.rb'
|
||||
- 'ee/app/controllers/projects/vulnerability_feedback_controller.rb'
|
||||
- 'ee/app/finders/autocomplete/project_invited_groups_finder.rb'
|
||||
- 'ee/app/finders/geo/project_registry_finder.rb'
|
||||
- 'ee/app/finders/merge_requests/by_approvers_finder.rb'
|
||||
- 'ee/app/graphql/mutations/vulnerabilities/create.rb'
|
||||
- 'ee/app/helpers/ee/application_settings_helper.rb'
|
||||
- 'ee/app/helpers/ee/trial_helper.rb'
|
||||
- 'ee/app/models/analytics/devops_adoption/enabled_namespace.rb'
|
||||
- 'ee/app/models/ee/epic.rb'
|
||||
- 'ee/app/models/ee/project.rb'
|
||||
- 'ee/app/models/ee/user.rb'
|
||||
- 'ee/app/models/ee/vulnerability.rb'
|
||||
- 'ee/app/models/protected_environment.rb'
|
||||
- 'ee/app/models/vulnerabilities/read.rb'
|
||||
- 'ee/app/serializers/dashboard_environments_serializer.rb'
|
||||
- 'ee/app/services/app_sec/dast/profiles/update_service.rb'
|
||||
- 'ee/app/services/vulnerabilities/create_service_base.rb'
|
||||
- 'ee/lib/ee/api/helpers/award_emoji.rb'
|
||||
- 'ee/lib/ee/gitlab/geo_git_access.rb'
|
||||
- 'ee/lib/gitlab/contribution_analytics/data_collector.rb'
|
||||
- 'ee/lib/gitlab/elastic/helper.rb'
|
||||
- 'ee/lib/gitlab/sitemaps/url_extractor.rb'
|
||||
- 'ee/lib/tasks/gitlab/seed/metrics.rake'
|
||||
- 'ee/spec/controllers/admin/audit_log_reports_controller_spec.rb'
|
||||
- 'ee/spec/controllers/admin/licenses/usage_exports_controller_spec.rb'
|
||||
- 'ee/spec/controllers/groups/analytics/coverage_reports_controller_spec.rb'
|
||||
- 'ee/spec/controllers/groups/security/merge_commit_reports_controller_spec.rb'
|
||||
- 'ee/spec/controllers/projects/merge_requests_controller_spec.rb'
|
||||
- 'ee/spec/features/admin/admin_dev_ops_reports_spec.rb'
|
||||
- 'ee/spec/features/boards/boards_licensed_features_spec.rb'
|
||||
- 'ee/spec/features/groups/analytics/cycle_analytics/charts_spec.rb'
|
||||
- 'ee/spec/features/groups/group_roadmap_spec.rb'
|
||||
- 'ee/spec/finders/billed_users_finder_spec.rb'
|
||||
- 'ee/spec/finders/merge_requests/by_approvers_finder_spec.rb'
|
||||
- 'ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb'
|
||||
- 'ee/spec/finders/security/scan_execution_policies_finder_spec.rb'
|
||||
- 'ee/spec/frontend/fixtures/dast_profiles.rb'
|
||||
- 'ee/spec/frontend/fixtures/search.rb'
|
||||
- 'ee/spec/graphql/mutations/incident_management/escalation_policy/create_spec.rb'
|
||||
- 'ee/spec/graphql/resolvers/dora_metrics_resolver_spec.rb'
|
||||
- 'ee/spec/graphql/resolvers/security_orchestration/scan_execution_policy_resolver_spec.rb'
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -407,7 +407,7 @@ group :development, :test do
|
|||
end
|
||||
|
||||
group :development, :test, :danger do
|
||||
gem 'gitlab-dangerfiles', '~> 3.5.1', require: false
|
||||
gem 'gitlab-dangerfiles', '~> 3.5.2', require: false
|
||||
end
|
||||
|
||||
group :development, :test, :coverage do
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ GEM
|
|||
terminal-table (~> 1.5, >= 1.5.1)
|
||||
gitlab-chronic (0.10.5)
|
||||
numerizer (~> 0.2)
|
||||
gitlab-dangerfiles (3.5.1)
|
||||
gitlab-dangerfiles (3.5.2)
|
||||
danger (>= 8.4.5)
|
||||
danger-gitlab (>= 8.0.0)
|
||||
rake
|
||||
|
|
@ -1591,7 +1591,7 @@ DEPENDENCIES
|
|||
gitaly (~> 15.4.0.pre.rc2)
|
||||
github-markup (~> 1.7.0)
|
||||
gitlab-chronic (~> 0.10.5)
|
||||
gitlab-dangerfiles (~> 3.5.1)
|
||||
gitlab-dangerfiles (~> 3.5.2)
|
||||
gitlab-experiment (~> 0.7.1)
|
||||
gitlab-fog-azure-rm (~> 1.3.0)
|
||||
gitlab-labkit (~> 0.24.0)
|
||||
|
|
|
|||
|
|
@ -331,6 +331,8 @@ export default {
|
|||
mrReviews: this.rehydratedMrReviews,
|
||||
});
|
||||
|
||||
this.interfaceWithDOM();
|
||||
|
||||
if (this.endpointCodequality) {
|
||||
this.setCodequalityEndpoint(this.endpointCodequality);
|
||||
}
|
||||
|
|
@ -445,6 +447,16 @@ export default {
|
|||
notesEventHub.$off('refetchDiffData', this.refetchDiffData);
|
||||
notesEventHub.$off('fetchDiffData', this.fetchData);
|
||||
},
|
||||
interfaceWithDOM() {
|
||||
this.diffsTab = document.querySelector('.js-diffs-tab');
|
||||
},
|
||||
updateChangesTabCount() {
|
||||
const badge = this.diffsTab.querySelector('.gl-badge');
|
||||
|
||||
if (this.diffsTab && badge) {
|
||||
badge.textContent = this.diffFilesLength;
|
||||
}
|
||||
},
|
||||
navigateToDiffFileNumber(number) {
|
||||
this.navigateToDiffFileIndex(number - 1);
|
||||
},
|
||||
|
|
@ -461,7 +473,11 @@ export default {
|
|||
this.fetchDiffFilesMeta()
|
||||
.then(({ real_size }) => {
|
||||
this.diffFilesLength = parseInt(real_size, 10);
|
||||
if (toggleTree) this.setTreeDisplay();
|
||||
if (toggleTree) {
|
||||
this.setTreeDisplay();
|
||||
}
|
||||
|
||||
this.updateChangesTabCount();
|
||||
})
|
||||
.catch(() => {
|
||||
createFlash({
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@
|
|||
position: relative;
|
||||
top: -3px;
|
||||
padding: $gl-padding-4 0;
|
||||
background-color: $gray-light;
|
||||
background-color: $body-bg;
|
||||
|
||||
&.opened {
|
||||
color: $green-500;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module JiraConnectHelper
|
||||
def jira_connect_app_data(subscriptions, installation)
|
||||
def jira_connect_app_data(subscriptions)
|
||||
skip_groups = subscriptions.map(&:namespace_id)
|
||||
|
||||
{
|
||||
|
|
@ -11,16 +11,14 @@ module JiraConnectHelper
|
|||
subscriptions_path: jira_connect_subscriptions_path(format: :json),
|
||||
users_path: current_user ? nil : jira_connect_users_path, # users_path is used to determine if user is signed in
|
||||
gitlab_user_path: current_user ? user_path(current_user) : nil,
|
||||
oauth_metadata: Feature.enabled?(:jira_connect_oauth, current_user) ? jira_connect_oauth_data(installation).to_json : nil
|
||||
oauth_metadata: Feature.enabled?(:jira_connect_oauth, current_user) ? jira_connect_oauth_data.to_json : nil
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def jira_connect_oauth_data(installation)
|
||||
oauth_instance_url = installation.oauth_authorization_url
|
||||
|
||||
oauth_authorize_path = oauth_authorization_path(
|
||||
def jira_connect_oauth_data
|
||||
oauth_authorize_url = oauth_authorization_url(
|
||||
client_id: Gitlab::CurrentSettings.jira_connect_application_key,
|
||||
response_type: 'code',
|
||||
scope: 'api',
|
||||
|
|
@ -29,8 +27,8 @@ module JiraConnectHelper
|
|||
)
|
||||
|
||||
{
|
||||
oauth_authorize_url: Gitlab::Utils.append_path(oauth_instance_url, oauth_authorize_path),
|
||||
oauth_token_url: Gitlab::Utils.append_path(oauth_instance_url, oauth_token_path),
|
||||
oauth_authorize_url: oauth_authorize_url,
|
||||
oauth_token_url: oauth_token_url,
|
||||
state: oauth_state,
|
||||
oauth_token_payload: {
|
||||
grant_type: :authorization_code,
|
||||
|
|
|
|||
|
|
@ -24,10 +24,4 @@ class JiraConnectInstallation < ApplicationRecord
|
|||
def client
|
||||
Atlassian::JiraConnect::Client.new(base_url, shared_secret)
|
||||
end
|
||||
|
||||
def oauth_authorization_url
|
||||
return Gitlab.config.gitlab.host if instance_url.blank? || Feature.disabled?(:jira_connect_oauth_self_managed)
|
||||
|
||||
instance_url
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,11 +2,24 @@
|
|||
|
||||
module Ml
|
||||
class Candidate < ApplicationRecord
|
||||
enum status: { running: 0, scheduled: 1, finished: 2, failed: 3, killed: 4 }
|
||||
|
||||
validates :iid, :experiment, presence: true
|
||||
validates :status, inclusion: { in: statuses.keys }
|
||||
|
||||
belongs_to :experiment, class_name: 'Ml::Experiment'
|
||||
belongs_to :user
|
||||
has_many :metrics, class_name: 'Ml::CandidateMetric'
|
||||
has_many :params, class_name: 'Ml::CandidateParam'
|
||||
|
||||
default_value_for(:iid) { SecureRandom.uuid }
|
||||
|
||||
class << self
|
||||
def with_project_id_and_iid(project_id, iid)
|
||||
return unless project_id.present? && iid.present?
|
||||
|
||||
joins(:experiment).find_by(experiment: { project_id: project_id }, iid: iid)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.js-jira-connect-app{ data: jira_connect_app_data(@subscriptions, @current_jira_installation) }
|
||||
.js-jira-connect-app{ data: jira_connect_app_data(@subscriptions) }
|
||||
|
||||
= webpack_bundle_tag 'performance_bar' if performance_bar_enabled?
|
||||
= webpack_bundle_tag 'jira_connect_app'
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
= tab_link_for @merge_request, :pipelines do
|
||||
= _("Pipelines")
|
||||
= gl_badge_tag @number_of_pipelines, { size: :sm }, { class: 'js-pipelines-mr-count' }
|
||||
= render "projects/merge_requests/tabs/tab", name: "diffs", class: "diffs-tab", id: "diffs-tab", qa_selector: "diffs_tab" do
|
||||
= render "projects/merge_requests/tabs/tab", name: "diffs", class: "diffs-tab js-diffs-tab", id: "diffs-tab", qa_selector: "diffs_tab" do
|
||||
= tab_link_for @merge_request, :diffs do
|
||||
= _("Changes")
|
||||
= gl_badge_tag @diffs_count, { size: :sm }
|
||||
|
|
|
|||
|
|
@ -1,44 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Gitlab::Database::Partitioning.register_models([
|
||||
AuditEvent,
|
||||
WebHookLog,
|
||||
LooseForeignKeys::DeletedRecord,
|
||||
Gitlab::Database::BackgroundMigration::BatchedJobTransitionLog
|
||||
])
|
||||
Gitlab::Database::Partitioning.register_models(
|
||||
[
|
||||
AuditEvent,
|
||||
WebHookLog,
|
||||
LooseForeignKeys::DeletedRecord,
|
||||
Gitlab::Database::BackgroundMigration::BatchedJobTransitionLog
|
||||
])
|
||||
|
||||
if Gitlab.ee?
|
||||
Gitlab::Database::Partitioning.register_models([
|
||||
IncidentManagement::PendingEscalations::Alert,
|
||||
IncidentManagement::PendingEscalations::Issue,
|
||||
Security::Finding
|
||||
])
|
||||
Gitlab::Database::Partitioning.register_models(
|
||||
[
|
||||
IncidentManagement::PendingEscalations::Alert,
|
||||
IncidentManagement::PendingEscalations::Issue,
|
||||
Security::Finding
|
||||
])
|
||||
else
|
||||
Gitlab::Database::Partitioning.register_tables([
|
||||
{
|
||||
limit_connection_names: %i[main],
|
||||
table_name: 'incident_management_pending_alert_escalations',
|
||||
partitioned_column: :process_at, strategy: :monthly
|
||||
},
|
||||
{
|
||||
limit_connection_names: %i[main],
|
||||
table_name: 'incident_management_pending_issue_escalations',
|
||||
partitioned_column: :process_at, strategy: :monthly
|
||||
}
|
||||
])
|
||||
Gitlab::Database::Partitioning.register_tables(
|
||||
[
|
||||
{
|
||||
limit_connection_names: %i[main],
|
||||
table_name: 'incident_management_pending_alert_escalations',
|
||||
partitioned_column: :process_at, strategy: :monthly
|
||||
},
|
||||
{
|
||||
limit_connection_names: %i[main],
|
||||
table_name: 'incident_management_pending_issue_escalations',
|
||||
partitioned_column: :process_at, strategy: :monthly
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
# The following tables are already defined as models
|
||||
unless Gitlab.jh?
|
||||
Gitlab::Database::Partitioning.register_tables([
|
||||
# This should be synchronized with the following model:
|
||||
# https://jihulab.com/gitlab-cn/gitlab/-/blob/main-jh/jh/app/models/phone/verification_code.rb
|
||||
{
|
||||
limit_connection_names: %i[main],
|
||||
table_name: 'verification_codes',
|
||||
partitioned_column: :created_at, strategy: :monthly
|
||||
}
|
||||
])
|
||||
Gitlab::Database::Partitioning.register_tables(
|
||||
[
|
||||
# This should be synchronized with the following model:
|
||||
# https://jihulab.com/gitlab-cn/gitlab/-/blob/main-jh/jh/app/models/phone/verification_code.rb
|
||||
{
|
||||
limit_connection_names: %i[main],
|
||||
table_name: 'verification_codes',
|
||||
partitioned_column: :created_at, strategy: :monthly
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
Gitlab::Database::Partitioning.sync_partitions_ignore_db_error
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddStartTimeAndEndTimeAndStatusToMlCandidates < Gitlab::Database::Migration[2.0]
|
||||
def change
|
||||
add_column :ml_candidates, :start_time, :bigint
|
||||
add_column :ml_candidates, :end_time, :bigint
|
||||
add_column :ml_candidates, :status, :smallint, default: 0, null: false
|
||||
end
|
||||
end
|
||||
|
|
@ -55,7 +55,8 @@ class RemoveDuplicateProjectAuthorizations < ActiveRecord::Migration[6.1]
|
|||
end
|
||||
|
||||
def batch(&block)
|
||||
order = Gitlab::Pagination::Keyset::Order.build([
|
||||
order = Gitlab::Pagination::Keyset::Order.build(
|
||||
[
|
||||
Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
|
||||
attribute_name: 'user_id',
|
||||
order_expression: ProjectAuthorization.arel_table[:user_id].asc,
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
a3eb4d190652c43f95f8823f11957064fcf097a1fd6641562a09de5ae02ceb6e
|
||||
|
|
@ -17759,7 +17759,10 @@ CREATE TABLE ml_candidates (
|
|||
updated_at timestamp with time zone NOT NULL,
|
||||
iid uuid NOT NULL,
|
||||
experiment_id bigint NOT NULL,
|
||||
user_id bigint
|
||||
user_id bigint,
|
||||
start_time bigint,
|
||||
end_time bigint,
|
||||
status smallint DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE ml_candidates_id_seq
|
||||
|
|
|
|||
|
|
@ -5544,7 +5544,7 @@ Input type: `VulnerabilityCreateInput`
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationvulnerabilitycreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationvulnerabilitycreateconfidence"></a>`confidence` | [`VulnerabilityConfidence`](#vulnerabilityconfidence) | Confidence of the vulnerability (defaults to `unknown`). |
|
||||
| <a id="mutationvulnerabilitycreateconfidence"></a>`confidence` **{warning-solid}** | [`VulnerabilityConfidence`](#vulnerabilityconfidence) | **Deprecated:** This field will be removed from the Vulnerability domain model. Deprecated in 15.4. |
|
||||
| <a id="mutationvulnerabilitycreateconfirmedat"></a>`confirmedAt` | [`Time`](#time) | Timestamp of when the vulnerability state changed to confirmed (defaults to creation time if status is `confirmed`). |
|
||||
| <a id="mutationvulnerabilitycreatedescription"></a>`description` | [`String!`](#string) | Long text section that describes the vulnerability in more detail. |
|
||||
| <a id="mutationvulnerabilitycreatedetectedat"></a>`detectedAt` | [`Time`](#time) | Timestamp of when the vulnerability was first detected (defaults to creation time). |
|
||||
|
|
@ -15732,7 +15732,7 @@ Represents vulnerability finding of a security report on the pipeline.
|
|||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="pipelinesecurityreportfindingassets"></a>`assets` | [`[AssetType!]`](#assettype) | List of assets associated with the vulnerability. |
|
||||
| <a id="pipelinesecurityreportfindingconfidence"></a>`confidence` | [`String`](#string) | Type of the security report that found the vulnerability. |
|
||||
| <a id="pipelinesecurityreportfindingconfidence"></a>`confidence` **{warning-solid}** | [`String`](#string) | **Deprecated** in 15.4. This field will be removed from the Finding domain model. |
|
||||
| <a id="pipelinesecurityreportfindingdescription"></a>`description` | [`String`](#string) | Description of the vulnerability finding. |
|
||||
| <a id="pipelinesecurityreportfindingdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
|
||||
| <a id="pipelinesecurityreportfindingevidence"></a>`evidence` | [`VulnerabilityEvidence`](#vulnerabilityevidence) | Evidence for the vulnerability. |
|
||||
|
|
|
|||
|
|
@ -578,6 +578,8 @@ To run a manual job, you must have permission to merge to the assigned branch:
|
|||
or deployment view.
|
||||
1. Next to the manual job, select **Play** (**{play}**).
|
||||
|
||||
You can also [add custom CI/CD variables when running a manual job](index.md#specifying-variables-when-running-manual-jobs).
|
||||
|
||||
### Protect manual jobs **(PREMIUM)**
|
||||
|
||||
Use [protected environments](../environments/protected_environments.md)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Scan execution policies **(ULTIMATE)**
|
||||
|
||||
> Group-level security policies were [introduced](https://gitlab.com/groups/gitlab-org/-/epics/4425) in GitLab 15.2 [with a flag](../../../administration/feature_flags.md) named `group_level_security_policies`. Enabled by default.
|
||||
> - Group-level security policies were [introduced](https://gitlab.com/groups/gitlab-org/-/epics/4425) in GitLab 15.2.
|
||||
> - Group-level security policies were [enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/356258) in GitLab 15.4.
|
||||
|
||||
Group, sub-group, or project owners can use scan execution policies to require that security scans run on a specified
|
||||
schedule or with the project (or multiple projects if the policy is defined at a group or sub-group level) pipeline. Required scans are injected into the CI pipeline as new jobs
|
||||
|
|
|
|||
|
|
@ -1514,7 +1514,9 @@ Press <kbd>Enter</kbd> to go to the next page.
|
|||
|
||||
### Tables
|
||||
|
||||
Tables are not part of the core Markdown spec, but they are part of GitLab Flavored Markdown.
|
||||
Tables are not part of the core Markdown specification, but are part of GitLab Flavored Markdown.
|
||||
|
||||
#### Markdown
|
||||
|
||||
1. The first line contains the headers, separated by "pipes" (`|`).
|
||||
1. The second line separates the headers from the cells.
|
||||
|
|
@ -1590,12 +1592,12 @@ but they do not render properly on `docs.gitlab.com`:
|
|||
| cell 3 | <ul><li> - [ ] Task one </li><li> - [ ] Task two </li></ul> |
|
||||
```
|
||||
|
||||
#### Copy from spreadsheet and paste in Markdown
|
||||
##### Copy and paste from a spreadsheet
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27205) in GitLab 12.7.
|
||||
|
||||
If you're working in spreadsheet software (for example, Microsoft Excel, Google
|
||||
Sheets, or Apple Numbers), GitLab creates a Markdown table when you copy-and-paste
|
||||
Sheets, or Apple Numbers), GitLab creates a Markdown table when you copy and paste
|
||||
from a spreadsheet. For example, suppose you have the
|
||||
following spreadsheet:
|
||||
|
||||
|
|
@ -1606,6 +1608,247 @@ entry and paste the spreadsheet:
|
|||
|
||||

|
||||
|
||||
#### JSON
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86353) in GitLab 15.3.
|
||||
|
||||
To render tables with JSON code blocks, use the following syntax:
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{}
|
||||
```
|
||||
````
|
||||
|
||||
The `items` attribute is a list of objects representing the data points.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
]
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
To specify the table labels, use the `fields` attribute.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"fields" : ["a", "b", "c"],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
]
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"fields" : ["a", "b", "c"],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Not all elements of `items` must have corresponding values in `fields`.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"fields" : ["a", "b", "c"],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"fields" : ["a", "b", "c"],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When `fields` is not explicitly specified, the labels are picked from the first element of `items`.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can specify custom labels for `fields`.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"fields" : [
|
||||
{"key": "a", "label": "AA"},
|
||||
{"key": "b", "label": "BB"},
|
||||
{"key": "c", "label": "CC"}
|
||||
],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "b": "222", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"fields" : [
|
||||
{"key": "a", "label": "AA"},
|
||||
{"key": "b", "label": "BB"},
|
||||
{"key": "c", "label": "CC"}
|
||||
],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "b": "222", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can enable sorting for individual elements of `fields`.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"fields" : [
|
||||
{"key": "a", "label": "AA", "sortable": true},
|
||||
{"key": "b", "label": "BB"},
|
||||
{"key": "c", "label": "CC"}
|
||||
],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "b": "222", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"fields" : [
|
||||
{"key": "a", "label": "AA", "sortable": true},
|
||||
{"key": "b", "label": "BB"},
|
||||
{"key": "c", "label": "CC"}
|
||||
],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "b": "222", "c": "233"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can use the `filter` attribute to render a table with content filtered dynamically by user input.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"fields" : [
|
||||
{"key": "a", "label": "AA"},
|
||||
{"key": "b", "label": "BB"},
|
||||
{"key": "c", "label": "CC"}
|
||||
],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "b": "222", "c": "233"}
|
||||
],
|
||||
"filter" : true
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"fields" : [
|
||||
{"key": "a", "label": "AA"},
|
||||
{"key": "b", "label": "BB"},
|
||||
{"key": "c", "label": "CC"}
|
||||
],
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"},
|
||||
{"a": "211", "b": "222", "c": "233"}
|
||||
],
|
||||
"filter" : true
|
||||
}
|
||||
```
|
||||
|
||||
By default, every JSON table has the caption `Generated with JSON data`.
|
||||
You can override this caption by specifying the `caption` attribute.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
],
|
||||
"caption" : "Custom caption"
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
],
|
||||
"caption" : "Custom caption"
|
||||
}
|
||||
```
|
||||
|
||||
If JSON is invalid, an error occurs.
|
||||
|
||||
````markdown
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
],
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```json:table
|
||||
{
|
||||
"items" : [
|
||||
{"a": "11", "b": "22", "c": "33"}
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- This document leveraged heavily from the [Markdown-Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module API
|
|||
module Entities
|
||||
module Ml
|
||||
module Mlflow
|
||||
class GetExperiment < Grape::Entity
|
||||
class Experiment < Grape::Entity
|
||||
expose :experiment do
|
||||
expose :experiment_id
|
||||
expose :name
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module Entities
|
||||
module Ml
|
||||
module Mlflow
|
||||
class Run < Grape::Entity
|
||||
expose :run do
|
||||
expose(:info) { |candidate| RunInfo.represent(candidate) }
|
||||
expose(:data) { |candidate| {} }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module Entities
|
||||
module Ml
|
||||
module Mlflow
|
||||
class RunInfo < Grape::Entity
|
||||
expose :run_id
|
||||
expose :run_id, as: :run_uuid
|
||||
expose(:experiment_id) { |candidate| candidate.experiment.iid.to_s }
|
||||
expose(:start_time) { |candidate| candidate.start_time || 0 }
|
||||
expose :end_time, expose_nil: false
|
||||
expose(:status) { |candidate| candidate.status.to_s.upcase }
|
||||
expose(:artifact_uri) { |candidate| 'not_implemented' }
|
||||
expose(:lifecycle_stage) { |candidate| 'active' }
|
||||
expose(:user_id) { |candidate| candidate.user_id.to_s }
|
||||
|
||||
private
|
||||
|
||||
def run_id
|
||||
object.iid.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module Entities
|
||||
module Ml
|
||||
module Mlflow
|
||||
class UpdateRun < Grape::Entity
|
||||
expose :run_info
|
||||
|
||||
private
|
||||
|
||||
def run_info
|
||||
::API::Entities::Ml::Mlflow::RunInfo.represent object
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -6,9 +6,14 @@ module API
|
|||
# MLFlow integration API, replicating the Rest API https://www.mlflow.org/docs/latest/rest-api.html#rest-api
|
||||
module Ml
|
||||
class Mlflow < ::API::Base
|
||||
include APIGuard
|
||||
|
||||
# The first part of the url is the namespace, the second part of the URL is what the MLFlow client calls
|
||||
MLFLOW_API_PREFIX = ':id/ml/mflow/api/2.0/mlflow/'
|
||||
|
||||
allow_access_with_scope :api
|
||||
allow_access_with_scope :read_api, if: -> (request) { request.get? || request.head? }
|
||||
|
||||
before do
|
||||
authenticate!
|
||||
not_found! unless Feature.enabled?(:ml_experiment_tracking, user_project)
|
||||
|
|
@ -39,7 +44,7 @@ module API
|
|||
namespace MLFLOW_API_PREFIX do
|
||||
resource :experiments do
|
||||
desc 'Fetch experiment by experiment_id' do
|
||||
success Entities::Ml::Mlflow::GetExperiment
|
||||
success Entities::Ml::Mlflow::Experiment
|
||||
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#get-experiment'
|
||||
end
|
||||
params do
|
||||
|
|
@ -50,11 +55,11 @@ module API
|
|||
|
||||
resource_not_found! unless experiment
|
||||
|
||||
present experiment, with: Entities::Ml::Mlflow::GetExperiment
|
||||
present experiment, with: Entities::Ml::Mlflow::Experiment
|
||||
end
|
||||
|
||||
desc 'Fetch experiment by experiment_name' do
|
||||
success Entities::Ml::Mlflow::GetExperiment
|
||||
success Entities::Ml::Mlflow::Experiment
|
||||
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#get-experiment-by-name'
|
||||
end
|
||||
params do
|
||||
|
|
@ -65,7 +70,7 @@ module API
|
|||
|
||||
resource_not_found! unless experiment
|
||||
|
||||
present experiment, with: Entities::Ml::Mlflow::GetExperiment
|
||||
present experiment, with: Entities::Ml::Mlflow::Experiment
|
||||
end
|
||||
|
||||
desc 'Create experiment' do
|
||||
|
|
@ -87,6 +92,78 @@ module API
|
|||
present experiment, with: Entities::Ml::Mlflow::NewExperiment
|
||||
end
|
||||
end
|
||||
|
||||
resource :runs do
|
||||
desc 'Gets an MLFlow Run, which maps to GitLab Candidates' do
|
||||
success Entities::Ml::Mlflow::Run
|
||||
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#get-run'
|
||||
end
|
||||
params do
|
||||
optional :run_id, type: String, desc: 'UUID of the candidate.'
|
||||
optional :run_uuid, type: String, desc: 'This parameter is ignored'
|
||||
end
|
||||
get 'get', urgency: :low do
|
||||
candidate = ::Ml::Candidate.with_project_id_and_iid(user_project.id, params[:run_id])
|
||||
|
||||
resource_not_found! unless candidate
|
||||
|
||||
present candidate, with: Entities::Ml::Mlflow::Run
|
||||
end
|
||||
|
||||
desc 'Creates a Run.' do
|
||||
success Entities::Ml::Mlflow::Run
|
||||
detail ['https://www.mlflow.org/docs/1.28.0/rest-api.html#create-run',
|
||||
'MLFlow Runs map to GitLab Candidates']
|
||||
end
|
||||
params do
|
||||
requires :experiment_id, type: Integer,
|
||||
desc: 'Id for the experiment, relative to the project'
|
||||
optional :start_time, type: Integer,
|
||||
desc: 'Unix timestamp in milliseconds of when the run started.',
|
||||
default: 0
|
||||
optional :user_id, type: String, desc: 'This will be ignored'
|
||||
optional :tags, type: Array, desc: 'This will be ignored'
|
||||
end
|
||||
post 'create', urgency: :low do
|
||||
experiment = ::Ml::Experiment.by_project_id_and_iid(user_project.id, params[:experiment_id].to_i)
|
||||
|
||||
resource_not_found! unless experiment
|
||||
|
||||
candidate = ::Ml::Candidate.create!(
|
||||
experiment: experiment,
|
||||
user: current_user,
|
||||
start_time: params[:start_time] || 0
|
||||
)
|
||||
|
||||
present candidate, with: Entities::Ml::Mlflow::Run
|
||||
end
|
||||
|
||||
desc 'Updates a Run.' do
|
||||
success Entities::Ml::Mlflow::UpdateRun
|
||||
detail ['https://www.mlflow.org/docs/1.28.0/rest-api.html#update-run',
|
||||
'MLFlow Runs map to GitLab Candidates']
|
||||
end
|
||||
params do
|
||||
optional :run_id, type: String, desc: 'UUID of the candidate.'
|
||||
optional :status, type: String,
|
||||
values: ::Ml::Candidate.statuses.keys.map(&:upcase),
|
||||
desc: "Status of the run. Accepts: " \
|
||||
"#{::Ml::Candidate.statuses.keys.map(&:upcase)}."
|
||||
optional :end_time, type: Integer, desc: 'Ending time of the run'
|
||||
end
|
||||
post 'update', urgency: :low do
|
||||
candidate = ::Ml::Candidate.with_project_id_and_iid(user_project.id, params[:run_id])
|
||||
|
||||
resource_not_found! unless candidate
|
||||
|
||||
candidate.status = params[:status].downcase if params[:status]
|
||||
candidate.end_time = params[:end_time] if params[:end_time]
|
||||
|
||||
candidate.save if candidate.valid?
|
||||
|
||||
present candidate, with: Entities::Ml::Mlflow::UpdateRun
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ module Gitlab
|
|||
module Validators
|
||||
class SchemaValidator
|
||||
SUPPORTED_VERSIONS = {
|
||||
cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
|
||||
container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
|
||||
coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
|
||||
dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
|
||||
api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
|
||||
dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
|
||||
sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2],
|
||||
secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2]
|
||||
cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
|
||||
container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
|
||||
coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
|
||||
dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
|
||||
api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
|
||||
dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
|
||||
sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3],
|
||||
secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0 14.1.1 14.1.2 14.1.3]
|
||||
}.freeze
|
||||
|
||||
VERSIONS_TO_REMOVE_IN_16_0 = [].freeze
|
||||
|
|
|
|||
|
|
@ -0,0 +1,977 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Report format for GitLab Cluster Image Scanning",
|
||||
"description": "This schema provides the the report format for Cluster Image Scanning (https://docs.gitlab.com/ee/user/application_security/cluster_image_scanning/).",
|
||||
"definitions": {
|
||||
"detail_type": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/table"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/text"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/url"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/code"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/value"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/diff"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/markdown"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/commit"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/file_location"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/module_location"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"named_field": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"minLength": 1
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"named_list": {
|
||||
"type": "object",
|
||||
"description": "An object with named and typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "named-list"
|
||||
},
|
||||
"items": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_field"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"list": {
|
||||
"type": "object",
|
||||
"description": "A list of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "list"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"type": "object",
|
||||
"description": "A table of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"rows"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "table"
|
||||
},
|
||||
"header": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"type": "object",
|
||||
"description": "Raw text",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "text"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "object",
|
||||
"description": "A single URL",
|
||||
"required": [
|
||||
"type",
|
||||
"href"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "url"
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
},
|
||||
"href": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"http://mysite.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": {
|
||||
"type": "object",
|
||||
"description": "A codeblock",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "code"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
"description": "A programming language"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"description": "A field that can store a range of types of value",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "value"
|
||||
},
|
||||
"value": {
|
||||
"type": [
|
||||
"number",
|
||||
"string",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"type": "object",
|
||||
"description": "A diff",
|
||||
"required": [
|
||||
"type",
|
||||
"before",
|
||||
"after"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "diff"
|
||||
},
|
||||
"before": {
|
||||
"type": "string"
|
||||
},
|
||||
"after": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown": {
|
||||
"type": "object",
|
||||
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "markdown"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"examples": [
|
||||
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"commit": {
|
||||
"type": "object",
|
||||
"description": "A commit/tag/branch within the GitLab project",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "commit"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The commit SHA",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"file_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a file in the project",
|
||||
"required": [
|
||||
"type",
|
||||
"file_name",
|
||||
"line_start"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "file-location"
|
||||
},
|
||||
"file_name": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"line_start": {
|
||||
"type": "integer"
|
||||
},
|
||||
"line_end": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"module_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a binary module of the form module+relative_offset",
|
||||
"required": [
|
||||
"type",
|
||||
"module_name",
|
||||
"offset"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "module-location"
|
||||
},
|
||||
"module_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"compiled_binary"
|
||||
]
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"examples": [
|
||||
100
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"self": {
|
||||
"version": "14.1.3"
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"vulnerabilities"
|
||||
],
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"scan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"end_time",
|
||||
"scanner",
|
||||
"start_time",
|
||||
"status",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"end_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-01-28T03:26:02"
|
||||
]
|
||||
},
|
||||
"messages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Communication intended for the initiator of a scan.",
|
||||
"required": [
|
||||
"level",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
|
||||
"enum": [
|
||||
"info",
|
||||
"warn",
|
||||
"fatal"
|
||||
],
|
||||
"examples": [
|
||||
"info"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The message to communicate.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"Permission denied, scanning aborted"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"analyzer": {
|
||||
"type": "object",
|
||||
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"gitlab-dast"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the analyzer, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab DAST"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^https?://.+",
|
||||
"description": "A link to more information about the analyzer.",
|
||||
"examples": [
|
||||
"https://docs.gitlab.com/ee/user/application_security/dast"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the analyzer.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner": {
|
||||
"type": "object",
|
||||
"description": "Object defining the scanner used to perform the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"my-sast-scanner"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the scanner, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"My SAST Scanner"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "A link to more information about the scanner.",
|
||||
"examples": [
|
||||
"https://scanner.url"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the scanner.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-02-14T16:01:59"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"success",
|
||||
"failure"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of the scan.",
|
||||
"enum": [
|
||||
"cluster_image_scanning"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "URI pointing to the validating security report schema.",
|
||||
"format": "uri"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the schema to which the JSON report conforms.",
|
||||
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"description": "Array of vulnerability objects.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes the vulnerability using GitLab Flavored Markdown",
|
||||
"required": [
|
||||
"category",
|
||||
"cve",
|
||||
"identifiers",
|
||||
"location",
|
||||
"scanner"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
|
||||
"examples": [
|
||||
"642735a5-1425-428d-8d4e-3c854885a3c9"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vulnerability. This must not include the finding's specific information."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A long text section describing the vulnerability more fully."
|
||||
},
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Info",
|
||||
"Unknown",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Critical"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "string",
|
||||
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Ignore",
|
||||
"Unknown",
|
||||
"Experimental",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Confirmed"
|
||||
]
|
||||
},
|
||||
"solution": {
|
||||
"type": "string",
|
||||
"description": "Explanation of how to fix the vulnerability."
|
||||
},
|
||||
"scanner": {
|
||||
"description": "Describes the scanner used to find this vulnerability.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The scanner's ID, as a snake_case string."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Human-readable name of the scanner."
|
||||
}
|
||||
}
|
||||
},
|
||||
"identifiers": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Human-readable name of the identifier.",
|
||||
"minLength": 1
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the identifier's documentation.",
|
||||
"format": "uri"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Value of the identifier, for matching purpose.",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"type": "array",
|
||||
"description": "An array of references to external documentation or articles that describe the vulnerability.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the vulnerability details link."
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the vulnerability details document.",
|
||||
"format": "uri"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/definitions/named_list/properties/items"
|
||||
},
|
||||
"tracking": {
|
||||
"description": "Describes how this vulnerability should be tracked as the project changes.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "source"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item that should be tracked using source-specific tracking methods.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"signatures"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located."
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the file that includes the vulnerability."
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the file that includes the vulnerability."
|
||||
},
|
||||
"signatures": {
|
||||
"type": "array",
|
||||
"description": "An array of calculated tracking signatures for this tracking item.",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "A calculated tracking signature value and metadata.",
|
||||
"required": [
|
||||
"algorithm",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"description": "The algorithm used to generate the signature."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The result of this signature algorithm."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Each tracking type must declare its own type."
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"description": "Flags that can be attached to vulnerabilities.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Informational flags identified and assigned to a vulnerability.",
|
||||
"required": [
|
||||
"type",
|
||||
"origin",
|
||||
"description"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"flagged-as-likely-false-positive"
|
||||
]
|
||||
},
|
||||
"origin": {
|
||||
"minLength": 1,
|
||||
"description": "Tool that issued the flag.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"minLength": 1,
|
||||
"description": "What the flag is about.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "object",
|
||||
"description": "Identifies the vulnerability's location.",
|
||||
"required": [
|
||||
"dependency",
|
||||
"image",
|
||||
"kubernetes_resource"
|
||||
],
|
||||
"properties": {
|
||||
"dependency": {
|
||||
"type": "object",
|
||||
"description": "Describes the dependency of a project where the vulnerability is located.",
|
||||
"properties": {
|
||||
"package": {
|
||||
"type": "object",
|
||||
"description": "Provides information on the package where the vulnerability is located.",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the package where the vulnerability is located."
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Version of the vulnerable package."
|
||||
},
|
||||
"iid": {
|
||||
"description": "ID that identifies the dependency in the scope of a dependency file.",
|
||||
"type": "number"
|
||||
},
|
||||
"direct": {
|
||||
"type": "boolean",
|
||||
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
|
||||
},
|
||||
"dependency_path": {
|
||||
"type": "array",
|
||||
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"iid"
|
||||
],
|
||||
"properties": {
|
||||
"iid": {
|
||||
"type": "number",
|
||||
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operating_system": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The operating system that contains the vulnerable package."
|
||||
},
|
||||
"image": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The analyzed Docker image.",
|
||||
"examples": [
|
||||
"index.docker.io/library/nginx:1.21"
|
||||
]
|
||||
},
|
||||
"kubernetes_resource": {
|
||||
"type": "object",
|
||||
"description": "The specific Kubernetes resource that was scanned.",
|
||||
"required": [
|
||||
"namespace",
|
||||
"kind",
|
||||
"name",
|
||||
"container_name"
|
||||
],
|
||||
"properties": {
|
||||
"namespace": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The Kubernetes namespace the resource that had its image scanned.",
|
||||
"examples": [
|
||||
"default",
|
||||
"staging",
|
||||
"production"
|
||||
]
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The Kubernetes kind the resource that had its image scanned.",
|
||||
"examples": [
|
||||
"Deployment",
|
||||
"DaemonSet"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The name of the resource that had its image scanned.",
|
||||
"examples": [
|
||||
"nginx-ingress"
|
||||
]
|
||||
},
|
||||
"container_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The name of the container that had its image scanned.",
|
||||
"examples": [
|
||||
"nginx"
|
||||
]
|
||||
},
|
||||
"agent_id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The GitLab ID of the Kubernetes Agent which performed the scan.",
|
||||
"examples": [
|
||||
"1234"
|
||||
]
|
||||
},
|
||||
"cluster_id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 255,
|
||||
"description": "The GitLab ID of the Kubernetes cluster when using cluster integration.",
|
||||
"examples": [
|
||||
"1234"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediations": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fixes",
|
||||
"summary",
|
||||
"diff"
|
||||
],
|
||||
"properties": {
|
||||
"fixes": {
|
||||
"type": "array",
|
||||
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"cve"
|
||||
],
|
||||
"properties": {
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "An overview of how the vulnerabilities were fixed."
|
||||
},
|
||||
"diff": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "A base64-encoded remediation code diff, compatible with git apply."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,911 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Report format for GitLab Container Scanning",
|
||||
"description": "This schema provides the the report format for Container Scanning (https://docs.gitlab.com/ee/user/application_security/container_scanning).",
|
||||
"definitions": {
|
||||
"detail_type": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/table"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/text"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/url"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/code"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/value"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/diff"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/markdown"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/commit"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/file_location"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/module_location"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"named_field": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"minLength": 1
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"named_list": {
|
||||
"type": "object",
|
||||
"description": "An object with named and typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "named-list"
|
||||
},
|
||||
"items": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_field"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"list": {
|
||||
"type": "object",
|
||||
"description": "A list of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "list"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"type": "object",
|
||||
"description": "A table of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"rows"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "table"
|
||||
},
|
||||
"header": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"type": "object",
|
||||
"description": "Raw text",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "text"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "object",
|
||||
"description": "A single URL",
|
||||
"required": [
|
||||
"type",
|
||||
"href"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "url"
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
},
|
||||
"href": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"http://mysite.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": {
|
||||
"type": "object",
|
||||
"description": "A codeblock",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "code"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
"description": "A programming language"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"description": "A field that can store a range of types of value",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "value"
|
||||
},
|
||||
"value": {
|
||||
"type": [
|
||||
"number",
|
||||
"string",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"type": "object",
|
||||
"description": "A diff",
|
||||
"required": [
|
||||
"type",
|
||||
"before",
|
||||
"after"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "diff"
|
||||
},
|
||||
"before": {
|
||||
"type": "string"
|
||||
},
|
||||
"after": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown": {
|
||||
"type": "object",
|
||||
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "markdown"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"examples": [
|
||||
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"commit": {
|
||||
"type": "object",
|
||||
"description": "A commit/tag/branch within the GitLab project",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "commit"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The commit SHA",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"file_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a file in the project",
|
||||
"required": [
|
||||
"type",
|
||||
"file_name",
|
||||
"line_start"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "file-location"
|
||||
},
|
||||
"file_name": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"line_start": {
|
||||
"type": "integer"
|
||||
},
|
||||
"line_end": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"module_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a binary module of the form module+relative_offset",
|
||||
"required": [
|
||||
"type",
|
||||
"module_name",
|
||||
"offset"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "module-location"
|
||||
},
|
||||
"module_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"compiled_binary"
|
||||
]
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"examples": [
|
||||
100
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"self": {
|
||||
"version": "14.1.3"
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"vulnerabilities"
|
||||
],
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"scan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"end_time",
|
||||
"scanner",
|
||||
"start_time",
|
||||
"status",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"end_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-01-28T03:26:02"
|
||||
]
|
||||
},
|
||||
"messages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Communication intended for the initiator of a scan.",
|
||||
"required": [
|
||||
"level",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
|
||||
"enum": [
|
||||
"info",
|
||||
"warn",
|
||||
"fatal"
|
||||
],
|
||||
"examples": [
|
||||
"info"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The message to communicate.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"Permission denied, scanning aborted"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"analyzer": {
|
||||
"type": "object",
|
||||
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"gitlab-dast"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the analyzer, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab DAST"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^https?://.+",
|
||||
"description": "A link to more information about the analyzer.",
|
||||
"examples": [
|
||||
"https://docs.gitlab.com/ee/user/application_security/dast"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the analyzer.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner": {
|
||||
"type": "object",
|
||||
"description": "Object defining the scanner used to perform the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"my-sast-scanner"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the scanner, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"My SAST Scanner"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "A link to more information about the scanner.",
|
||||
"examples": [
|
||||
"https://scanner.url"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the scanner.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-02-14T16:01:59"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"success",
|
||||
"failure"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of the scan.",
|
||||
"enum": [
|
||||
"container_scanning"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "URI pointing to the validating security report schema.",
|
||||
"format": "uri"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the schema to which the JSON report conforms.",
|
||||
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"description": "Array of vulnerability objects.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes the vulnerability using GitLab Flavored Markdown",
|
||||
"required": [
|
||||
"category",
|
||||
"cve",
|
||||
"identifiers",
|
||||
"location",
|
||||
"scanner"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
|
||||
"examples": [
|
||||
"642735a5-1425-428d-8d4e-3c854885a3c9"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vulnerability. This must not include the finding's specific information."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A long text section describing the vulnerability more fully."
|
||||
},
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Info",
|
||||
"Unknown",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Critical"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "string",
|
||||
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Ignore",
|
||||
"Unknown",
|
||||
"Experimental",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Confirmed"
|
||||
]
|
||||
},
|
||||
"solution": {
|
||||
"type": "string",
|
||||
"description": "Explanation of how to fix the vulnerability."
|
||||
},
|
||||
"scanner": {
|
||||
"description": "Describes the scanner used to find this vulnerability.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The scanner's ID, as a snake_case string."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Human-readable name of the scanner."
|
||||
}
|
||||
}
|
||||
},
|
||||
"identifiers": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Human-readable name of the identifier.",
|
||||
"minLength": 1
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the identifier's documentation.",
|
||||
"format": "uri"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Value of the identifier, for matching purpose.",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"type": "array",
|
||||
"description": "An array of references to external documentation or articles that describe the vulnerability.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the vulnerability details link."
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the vulnerability details document.",
|
||||
"format": "uri"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/definitions/named_list/properties/items"
|
||||
},
|
||||
"tracking": {
|
||||
"description": "Describes how this vulnerability should be tracked as the project changes.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "source"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item that should be tracked using source-specific tracking methods.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"signatures"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located."
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the file that includes the vulnerability."
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the file that includes the vulnerability."
|
||||
},
|
||||
"signatures": {
|
||||
"type": "array",
|
||||
"description": "An array of calculated tracking signatures for this tracking item.",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "A calculated tracking signature value and metadata.",
|
||||
"required": [
|
||||
"algorithm",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"description": "The algorithm used to generate the signature."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The result of this signature algorithm."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Each tracking type must declare its own type."
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"description": "Flags that can be attached to vulnerabilities.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Informational flags identified and assigned to a vulnerability.",
|
||||
"required": [
|
||||
"type",
|
||||
"origin",
|
||||
"description"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"flagged-as-likely-false-positive"
|
||||
]
|
||||
},
|
||||
"origin": {
|
||||
"minLength": 1,
|
||||
"description": "Tool that issued the flag.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"minLength": 1,
|
||||
"description": "What the flag is about.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "object",
|
||||
"description": "Identifies the vulnerability's location.",
|
||||
"required": [
|
||||
"dependency",
|
||||
"operating_system",
|
||||
"image"
|
||||
],
|
||||
"properties": {
|
||||
"dependency": {
|
||||
"type": "object",
|
||||
"description": "Describes the dependency of a project where the vulnerability is located.",
|
||||
"properties": {
|
||||
"package": {
|
||||
"type": "object",
|
||||
"description": "Provides information on the package where the vulnerability is located.",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the package where the vulnerability is located."
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Version of the vulnerable package."
|
||||
},
|
||||
"iid": {
|
||||
"description": "ID that identifies the dependency in the scope of a dependency file.",
|
||||
"type": "number"
|
||||
},
|
||||
"direct": {
|
||||
"type": "boolean",
|
||||
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
|
||||
},
|
||||
"dependency_path": {
|
||||
"type": "array",
|
||||
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"iid"
|
||||
],
|
||||
"properties": {
|
||||
"iid": {
|
||||
"type": "number",
|
||||
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"operating_system": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The operating system that contains the vulnerable package."
|
||||
},
|
||||
"image": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": "^[^:]+(:\\d+[^:]*)?:[^:]+(:[^:]+)?$",
|
||||
"description": "The analyzed Docker image."
|
||||
},
|
||||
"default_branch_image": {
|
||||
"type": "string",
|
||||
"maxLength": 255,
|
||||
"pattern": "^[a-zA-Z0-9/_.-]+(:\\d+[a-zA-Z0-9/_.-]*)?:[a-zA-Z0-9_.-]+$",
|
||||
"description": "The name of the image on the default branch."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediations": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fixes",
|
||||
"summary",
|
||||
"diff"
|
||||
],
|
||||
"properties": {
|
||||
"fixes": {
|
||||
"type": "array",
|
||||
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"cve"
|
||||
],
|
||||
"properties": {
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "An overview of how the vulnerabilities were fixed."
|
||||
},
|
||||
"diff": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "A base64-encoded remediation code diff, compatible with git apply."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,874 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Report format for GitLab Fuzz Testing",
|
||||
"description": "This schema provides the report format for Coverage Guided Fuzz Testing (https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing).",
|
||||
"definitions": {
|
||||
"detail_type": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/table"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/text"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/url"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/code"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/value"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/diff"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/markdown"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/commit"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/file_location"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/module_location"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"named_field": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"minLength": 1
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"named_list": {
|
||||
"type": "object",
|
||||
"description": "An object with named and typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "named-list"
|
||||
},
|
||||
"items": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_field"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"list": {
|
||||
"type": "object",
|
||||
"description": "A list of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "list"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"type": "object",
|
||||
"description": "A table of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"rows"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "table"
|
||||
},
|
||||
"header": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"type": "object",
|
||||
"description": "Raw text",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "text"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "object",
|
||||
"description": "A single URL",
|
||||
"required": [
|
||||
"type",
|
||||
"href"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "url"
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
},
|
||||
"href": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"http://mysite.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": {
|
||||
"type": "object",
|
||||
"description": "A codeblock",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "code"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
"description": "A programming language"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"description": "A field that can store a range of types of value",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "value"
|
||||
},
|
||||
"value": {
|
||||
"type": [
|
||||
"number",
|
||||
"string",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"type": "object",
|
||||
"description": "A diff",
|
||||
"required": [
|
||||
"type",
|
||||
"before",
|
||||
"after"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "diff"
|
||||
},
|
||||
"before": {
|
||||
"type": "string"
|
||||
},
|
||||
"after": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown": {
|
||||
"type": "object",
|
||||
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "markdown"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"examples": [
|
||||
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"commit": {
|
||||
"type": "object",
|
||||
"description": "A commit/tag/branch within the GitLab project",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "commit"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The commit SHA",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"file_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a file in the project",
|
||||
"required": [
|
||||
"type",
|
||||
"file_name",
|
||||
"line_start"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "file-location"
|
||||
},
|
||||
"file_name": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"line_start": {
|
||||
"type": "integer"
|
||||
},
|
||||
"line_end": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"module_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a binary module of the form module+relative_offset",
|
||||
"required": [
|
||||
"type",
|
||||
"module_name",
|
||||
"offset"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "module-location"
|
||||
},
|
||||
"module_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"compiled_binary"
|
||||
]
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"examples": [
|
||||
100
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"self": {
|
||||
"version": "14.1.3"
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"vulnerabilities"
|
||||
],
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"scan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"end_time",
|
||||
"scanner",
|
||||
"start_time",
|
||||
"status",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"end_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-01-28T03:26:02"
|
||||
]
|
||||
},
|
||||
"messages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Communication intended for the initiator of a scan.",
|
||||
"required": [
|
||||
"level",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
|
||||
"enum": [
|
||||
"info",
|
||||
"warn",
|
||||
"fatal"
|
||||
],
|
||||
"examples": [
|
||||
"info"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The message to communicate.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"Permission denied, scanning aborted"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"analyzer": {
|
||||
"type": "object",
|
||||
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"gitlab-dast"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the analyzer, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab DAST"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^https?://.+",
|
||||
"description": "A link to more information about the analyzer.",
|
||||
"examples": [
|
||||
"https://docs.gitlab.com/ee/user/application_security/dast"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the analyzer.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner": {
|
||||
"type": "object",
|
||||
"description": "Object defining the scanner used to perform the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"my-sast-scanner"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the scanner, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"My SAST Scanner"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "A link to more information about the scanner.",
|
||||
"examples": [
|
||||
"https://scanner.url"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the scanner.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-02-14T16:01:59"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"success",
|
||||
"failure"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of the scan.",
|
||||
"enum": [
|
||||
"coverage_fuzzing"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "URI pointing to the validating security report schema.",
|
||||
"format": "uri"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the schema to which the JSON report conforms.",
|
||||
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"description": "Array of vulnerability objects.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes the vulnerability using GitLab Flavored Markdown",
|
||||
"required": [
|
||||
"category",
|
||||
"cve",
|
||||
"identifiers",
|
||||
"location",
|
||||
"scanner"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
|
||||
"examples": [
|
||||
"642735a5-1425-428d-8d4e-3c854885a3c9"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vulnerability. This must not include the finding's specific information."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A long text section describing the vulnerability more fully."
|
||||
},
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Info",
|
||||
"Unknown",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Critical"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "string",
|
||||
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Ignore",
|
||||
"Unknown",
|
||||
"Experimental",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Confirmed"
|
||||
]
|
||||
},
|
||||
"solution": {
|
||||
"type": "string",
|
||||
"description": "Explanation of how to fix the vulnerability."
|
||||
},
|
||||
"scanner": {
|
||||
"description": "Describes the scanner used to find this vulnerability.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The scanner's ID, as a snake_case string."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Human-readable name of the scanner."
|
||||
}
|
||||
}
|
||||
},
|
||||
"identifiers": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Human-readable name of the identifier.",
|
||||
"minLength": 1
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the identifier's documentation.",
|
||||
"format": "uri"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Value of the identifier, for matching purpose.",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"type": "array",
|
||||
"description": "An array of references to external documentation or articles that describe the vulnerability.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the vulnerability details link."
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the vulnerability details document.",
|
||||
"format": "uri"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/definitions/named_list/properties/items"
|
||||
},
|
||||
"tracking": {
|
||||
"description": "Describes how this vulnerability should be tracked as the project changes.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "source"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item that should be tracked using source-specific tracking methods.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"signatures"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located."
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the file that includes the vulnerability."
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the file that includes the vulnerability."
|
||||
},
|
||||
"signatures": {
|
||||
"type": "array",
|
||||
"description": "An array of calculated tracking signatures for this tracking item.",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "A calculated tracking signature value and metadata.",
|
||||
"required": [
|
||||
"algorithm",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"description": "The algorithm used to generate the signature."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The result of this signature algorithm."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Each tracking type must declare its own type."
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"description": "Flags that can be attached to vulnerabilities.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Informational flags identified and assigned to a vulnerability.",
|
||||
"required": [
|
||||
"type",
|
||||
"origin",
|
||||
"description"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"flagged-as-likely-false-positive"
|
||||
]
|
||||
},
|
||||
"origin": {
|
||||
"minLength": 1,
|
||||
"description": "Tool that issued the flag.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"minLength": 1,
|
||||
"description": "What the flag is about.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"description": "The location of the error",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"crash_address": {
|
||||
"type": "string",
|
||||
"description": "The relative address in memory were the crash occurred.",
|
||||
"examples": [
|
||||
"0xabababab"
|
||||
]
|
||||
},
|
||||
"stacktrace_snippet": {
|
||||
"type": "string",
|
||||
"description": "The stack trace recorded during fuzzing resulting the crash.",
|
||||
"examples": [
|
||||
"func_a+0xabcd\nfunc_b+0xabcc"
|
||||
]
|
||||
},
|
||||
"crash_state": {
|
||||
"type": "string",
|
||||
"description": "Minimised and normalized crash stack-trace (called crash_state).",
|
||||
"examples": [
|
||||
"func_a+0xa\nfunc_b+0xb\nfunc_c+0xc"
|
||||
]
|
||||
},
|
||||
"crash_type": {
|
||||
"type": "string",
|
||||
"description": "Type of the crash.",
|
||||
"examples": [
|
||||
"Heap-Buffer-overflow",
|
||||
"Division-by-zero"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediations": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fixes",
|
||||
"summary",
|
||||
"diff"
|
||||
],
|
||||
"properties": {
|
||||
"fixes": {
|
||||
"type": "array",
|
||||
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"cve"
|
||||
],
|
||||
"properties": {
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "An overview of how the vulnerabilities were fixed."
|
||||
},
|
||||
"diff": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "A base64-encoded remediation code diff, compatible with git apply."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,968 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Report format for GitLab Dependency Scanning",
|
||||
"description": "This schema provides the the report format for Dependency Scanning analyzers (https://docs.gitlab.com/ee/user/application_security/dependency_scanning).",
|
||||
"definitions": {
|
||||
"detail_type": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/table"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/text"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/url"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/code"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/value"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/diff"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/markdown"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/commit"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/file_location"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/module_location"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"named_field": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"minLength": 1
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"named_list": {
|
||||
"type": "object",
|
||||
"description": "An object with named and typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "named-list"
|
||||
},
|
||||
"items": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_field"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"list": {
|
||||
"type": "object",
|
||||
"description": "A list of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "list"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"type": "object",
|
||||
"description": "A table of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"rows"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "table"
|
||||
},
|
||||
"header": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"type": "object",
|
||||
"description": "Raw text",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "text"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "object",
|
||||
"description": "A single URL",
|
||||
"required": [
|
||||
"type",
|
||||
"href"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "url"
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
},
|
||||
"href": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"http://mysite.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": {
|
||||
"type": "object",
|
||||
"description": "A codeblock",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "code"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
"description": "A programming language"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"description": "A field that can store a range of types of value",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "value"
|
||||
},
|
||||
"value": {
|
||||
"type": [
|
||||
"number",
|
||||
"string",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"type": "object",
|
||||
"description": "A diff",
|
||||
"required": [
|
||||
"type",
|
||||
"before",
|
||||
"after"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "diff"
|
||||
},
|
||||
"before": {
|
||||
"type": "string"
|
||||
},
|
||||
"after": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown": {
|
||||
"type": "object",
|
||||
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "markdown"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"examples": [
|
||||
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"commit": {
|
||||
"type": "object",
|
||||
"description": "A commit/tag/branch within the GitLab project",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "commit"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The commit SHA",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"file_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a file in the project",
|
||||
"required": [
|
||||
"type",
|
||||
"file_name",
|
||||
"line_start"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "file-location"
|
||||
},
|
||||
"file_name": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"line_start": {
|
||||
"type": "integer"
|
||||
},
|
||||
"line_end": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"module_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a binary module of the form module+relative_offset",
|
||||
"required": [
|
||||
"type",
|
||||
"module_name",
|
||||
"offset"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "module-location"
|
||||
},
|
||||
"module_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"compiled_binary"
|
||||
]
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"examples": [
|
||||
100
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"self": {
|
||||
"version": "14.1.3"
|
||||
},
|
||||
"required": [
|
||||
"dependency_files",
|
||||
"version",
|
||||
"vulnerabilities"
|
||||
],
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"scan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"end_time",
|
||||
"scanner",
|
||||
"start_time",
|
||||
"status",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"end_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-01-28T03:26:02"
|
||||
]
|
||||
},
|
||||
"messages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Communication intended for the initiator of a scan.",
|
||||
"required": [
|
||||
"level",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
|
||||
"enum": [
|
||||
"info",
|
||||
"warn",
|
||||
"fatal"
|
||||
],
|
||||
"examples": [
|
||||
"info"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The message to communicate.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"Permission denied, scanning aborted"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"analyzer": {
|
||||
"type": "object",
|
||||
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"gitlab-dast"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the analyzer, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab DAST"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^https?://.+",
|
||||
"description": "A link to more information about the analyzer.",
|
||||
"examples": [
|
||||
"https://docs.gitlab.com/ee/user/application_security/dast"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the analyzer.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner": {
|
||||
"type": "object",
|
||||
"description": "Object defining the scanner used to perform the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"my-sast-scanner"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the scanner, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"My SAST Scanner"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "A link to more information about the scanner.",
|
||||
"examples": [
|
||||
"https://scanner.url"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the scanner.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-02-14T16:01:59"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"success",
|
||||
"failure"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of the scan.",
|
||||
"enum": [
|
||||
"dependency_scanning"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "URI pointing to the validating security report schema.",
|
||||
"format": "uri"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the schema to which the JSON report conforms.",
|
||||
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"description": "Array of vulnerability objects.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes the vulnerability using GitLab Flavored Markdown",
|
||||
"required": [
|
||||
"category",
|
||||
"cve",
|
||||
"identifiers",
|
||||
"location",
|
||||
"scanner"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
|
||||
"examples": [
|
||||
"642735a5-1425-428d-8d4e-3c854885a3c9"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vulnerability. This must not include the finding's specific information."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A long text section describing the vulnerability more fully."
|
||||
},
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Info",
|
||||
"Unknown",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Critical"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "string",
|
||||
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Ignore",
|
||||
"Unknown",
|
||||
"Experimental",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Confirmed"
|
||||
]
|
||||
},
|
||||
"solution": {
|
||||
"type": "string",
|
||||
"description": "Explanation of how to fix the vulnerability."
|
||||
},
|
||||
"scanner": {
|
||||
"description": "Describes the scanner used to find this vulnerability.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The scanner's ID, as a snake_case string."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Human-readable name of the scanner."
|
||||
}
|
||||
}
|
||||
},
|
||||
"identifiers": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Human-readable name of the identifier.",
|
||||
"minLength": 1
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the identifier's documentation.",
|
||||
"format": "uri"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Value of the identifier, for matching purpose.",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"type": "array",
|
||||
"description": "An array of references to external documentation or articles that describe the vulnerability.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the vulnerability details link."
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the vulnerability details document.",
|
||||
"format": "uri"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/definitions/named_list/properties/items"
|
||||
},
|
||||
"tracking": {
|
||||
"description": "Describes how this vulnerability should be tracked as the project changes.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "source"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item that should be tracked using source-specific tracking methods.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"signatures"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located."
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the file that includes the vulnerability."
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the file that includes the vulnerability."
|
||||
},
|
||||
"signatures": {
|
||||
"type": "array",
|
||||
"description": "An array of calculated tracking signatures for this tracking item.",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "A calculated tracking signature value and metadata.",
|
||||
"required": [
|
||||
"algorithm",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"description": "The algorithm used to generate the signature."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The result of this signature algorithm."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Each tracking type must declare its own type."
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"description": "Flags that can be attached to vulnerabilities.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Informational flags identified and assigned to a vulnerability.",
|
||||
"required": [
|
||||
"type",
|
||||
"origin",
|
||||
"description"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"flagged-as-likely-false-positive"
|
||||
]
|
||||
},
|
||||
"origin": {
|
||||
"minLength": 1,
|
||||
"description": "Tool that issued the flag.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"minLength": 1,
|
||||
"description": "What the flag is about.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "object",
|
||||
"description": "Identifies the vulnerability's location.",
|
||||
"required": [
|
||||
"file",
|
||||
"dependency"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Path to the manifest or lock file where the dependency is declared (such as yarn.lock)."
|
||||
},
|
||||
"dependency": {
|
||||
"type": "object",
|
||||
"description": "Describes the dependency of a project where the vulnerability is located.",
|
||||
"properties": {
|
||||
"package": {
|
||||
"type": "object",
|
||||
"description": "Provides information on the package where the vulnerability is located.",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the package where the vulnerability is located."
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Version of the vulnerable package."
|
||||
},
|
||||
"iid": {
|
||||
"description": "ID that identifies the dependency in the scope of a dependency file.",
|
||||
"type": "number"
|
||||
},
|
||||
"direct": {
|
||||
"type": "boolean",
|
||||
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
|
||||
},
|
||||
"dependency_path": {
|
||||
"type": "array",
|
||||
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"iid"
|
||||
],
|
||||
"properties": {
|
||||
"iid": {
|
||||
"type": "number",
|
||||
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediations": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fixes",
|
||||
"summary",
|
||||
"diff"
|
||||
],
|
||||
"properties": {
|
||||
"fixes": {
|
||||
"type": "array",
|
||||
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"cve"
|
||||
],
|
||||
"properties": {
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "An overview of how the vulnerabilities were fixed."
|
||||
},
|
||||
"diff": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "A base64-encoded remediation code diff, compatible with git apply."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependency_files": {
|
||||
"type": "array",
|
||||
"description": "List of dependency files identified in the project.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"path",
|
||||
"package_manager",
|
||||
"dependencies"
|
||||
],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"package_manager": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes the dependency of a project where the vulnerability is located.",
|
||||
"properties": {
|
||||
"package": {
|
||||
"type": "object",
|
||||
"description": "Provides information on the package where the vulnerability is located.",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the package where the vulnerability is located."
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Version of the vulnerable package."
|
||||
},
|
||||
"iid": {
|
||||
"description": "ID that identifies the dependency in the scope of a dependency file.",
|
||||
"type": "number"
|
||||
},
|
||||
"direct": {
|
||||
"type": "boolean",
|
||||
"description": "Tells whether this is a direct, top-level dependency of the scanned project."
|
||||
},
|
||||
"dependency_path": {
|
||||
"type": "array",
|
||||
"description": "Ancestors of the dependency, starting from a direct project dependency, and ending with an immediate parent of the dependency. The dependency itself is excluded from the path. Direct dependencies have no path.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"iid"
|
||||
],
|
||||
"properties": {
|
||||
"iid": {
|
||||
"type": "number",
|
||||
"description": "ID that is unique in the scope of a parent object, and specific to the resource type."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,869 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Report format for GitLab SAST",
|
||||
"description": "This schema provides the report format for Static Application Security Testing analyzers (https://docs.gitlab.com/ee/user/application_security/sast).",
|
||||
"definitions": {
|
||||
"detail_type": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/table"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/text"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/url"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/code"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/value"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/diff"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/markdown"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/commit"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/file_location"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/module_location"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"named_field": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"minLength": 1
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"named_list": {
|
||||
"type": "object",
|
||||
"description": "An object with named and typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "named-list"
|
||||
},
|
||||
"items": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_field"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"list": {
|
||||
"type": "object",
|
||||
"description": "A list of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "list"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"type": "object",
|
||||
"description": "A table of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"rows"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "table"
|
||||
},
|
||||
"header": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"type": "object",
|
||||
"description": "Raw text",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "text"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "object",
|
||||
"description": "A single URL",
|
||||
"required": [
|
||||
"type",
|
||||
"href"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "url"
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
},
|
||||
"href": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"http://mysite.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": {
|
||||
"type": "object",
|
||||
"description": "A codeblock",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "code"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
"description": "A programming language"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"description": "A field that can store a range of types of value",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "value"
|
||||
},
|
||||
"value": {
|
||||
"type": [
|
||||
"number",
|
||||
"string",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"type": "object",
|
||||
"description": "A diff",
|
||||
"required": [
|
||||
"type",
|
||||
"before",
|
||||
"after"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "diff"
|
||||
},
|
||||
"before": {
|
||||
"type": "string"
|
||||
},
|
||||
"after": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown": {
|
||||
"type": "object",
|
||||
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "markdown"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"examples": [
|
||||
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"commit": {
|
||||
"type": "object",
|
||||
"description": "A commit/tag/branch within the GitLab project",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "commit"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The commit SHA",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"file_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a file in the project",
|
||||
"required": [
|
||||
"type",
|
||||
"file_name",
|
||||
"line_start"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "file-location"
|
||||
},
|
||||
"file_name": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"line_start": {
|
||||
"type": "integer"
|
||||
},
|
||||
"line_end": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"module_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a binary module of the form module+relative_offset",
|
||||
"required": [
|
||||
"type",
|
||||
"module_name",
|
||||
"offset"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "module-location"
|
||||
},
|
||||
"module_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"compiled_binary"
|
||||
]
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"examples": [
|
||||
100
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"self": {
|
||||
"version": "14.1.3"
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"vulnerabilities"
|
||||
],
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"scan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"end_time",
|
||||
"scanner",
|
||||
"start_time",
|
||||
"status",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"end_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-01-28T03:26:02"
|
||||
]
|
||||
},
|
||||
"messages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Communication intended for the initiator of a scan.",
|
||||
"required": [
|
||||
"level",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
|
||||
"enum": [
|
||||
"info",
|
||||
"warn",
|
||||
"fatal"
|
||||
],
|
||||
"examples": [
|
||||
"info"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The message to communicate.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"Permission denied, scanning aborted"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"analyzer": {
|
||||
"type": "object",
|
||||
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"gitlab-dast"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the analyzer, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab DAST"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^https?://.+",
|
||||
"description": "A link to more information about the analyzer.",
|
||||
"examples": [
|
||||
"https://docs.gitlab.com/ee/user/application_security/dast"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the analyzer.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner": {
|
||||
"type": "object",
|
||||
"description": "Object defining the scanner used to perform the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"my-sast-scanner"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the scanner, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"My SAST Scanner"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "A link to more information about the scanner.",
|
||||
"examples": [
|
||||
"https://scanner.url"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the scanner.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-02-14T16:01:59"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"success",
|
||||
"failure"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of the scan.",
|
||||
"enum": [
|
||||
"sast"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "URI pointing to the validating security report schema.",
|
||||
"format": "uri"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the schema to which the JSON report conforms.",
|
||||
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"description": "Array of vulnerability objects.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes the vulnerability using GitLab Flavored Markdown",
|
||||
"required": [
|
||||
"category",
|
||||
"cve",
|
||||
"identifiers",
|
||||
"location",
|
||||
"scanner"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
|
||||
"examples": [
|
||||
"642735a5-1425-428d-8d4e-3c854885a3c9"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vulnerability. This must not include the finding's specific information."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A long text section describing the vulnerability more fully."
|
||||
},
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Info",
|
||||
"Unknown",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Critical"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "string",
|
||||
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Ignore",
|
||||
"Unknown",
|
||||
"Experimental",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Confirmed"
|
||||
]
|
||||
},
|
||||
"solution": {
|
||||
"type": "string",
|
||||
"description": "Explanation of how to fix the vulnerability."
|
||||
},
|
||||
"scanner": {
|
||||
"description": "Describes the scanner used to find this vulnerability.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The scanner's ID, as a snake_case string."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Human-readable name of the scanner."
|
||||
}
|
||||
}
|
||||
},
|
||||
"identifiers": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Human-readable name of the identifier.",
|
||||
"minLength": 1
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the identifier's documentation.",
|
||||
"format": "uri"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Value of the identifier, for matching purpose.",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"type": "array",
|
||||
"description": "An array of references to external documentation or articles that describe the vulnerability.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the vulnerability details link."
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the vulnerability details document.",
|
||||
"format": "uri"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/definitions/named_list/properties/items"
|
||||
},
|
||||
"tracking": {
|
||||
"description": "Describes how this vulnerability should be tracked as the project changes.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "source"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item that should be tracked using source-specific tracking methods.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"signatures"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located."
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the file that includes the vulnerability."
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the file that includes the vulnerability."
|
||||
},
|
||||
"signatures": {
|
||||
"type": "array",
|
||||
"description": "An array of calculated tracking signatures for this tracking item.",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "A calculated tracking signature value and metadata.",
|
||||
"required": [
|
||||
"algorithm",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"description": "The algorithm used to generate the signature."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The result of this signature algorithm."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Each tracking type must declare its own type."
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"description": "Flags that can be attached to vulnerabilities.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Informational flags identified and assigned to a vulnerability.",
|
||||
"required": [
|
||||
"type",
|
||||
"origin",
|
||||
"description"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"flagged-as-likely-false-positive"
|
||||
]
|
||||
},
|
||||
"origin": {
|
||||
"minLength": 1,
|
||||
"description": "Tool that issued the flag.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"minLength": 1,
|
||||
"description": "What the flag is about.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "object",
|
||||
"description": "Identifies the vulnerability's location.",
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located."
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the code affected by the vulnerability."
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the code affected by the vulnerability."
|
||||
},
|
||||
"class": {
|
||||
"type": "string",
|
||||
"description": "Provides the name of the class where the vulnerability is located."
|
||||
},
|
||||
"method": {
|
||||
"type": "string",
|
||||
"description": "Provides the name of the method where the vulnerability is located."
|
||||
}
|
||||
}
|
||||
},
|
||||
"raw_source_code_extract": {
|
||||
"type": "string",
|
||||
"description": "Provides an unsanitized excerpt of the affected source code."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediations": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fixes",
|
||||
"summary",
|
||||
"diff"
|
||||
],
|
||||
"properties": {
|
||||
"fixes": {
|
||||
"type": "array",
|
||||
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"cve"
|
||||
],
|
||||
"properties": {
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "An overview of how the vulnerabilities were fixed."
|
||||
},
|
||||
"diff": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "A base64-encoded remediation code diff, compatible with git apply."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,892 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Report format for GitLab Secret Detection",
|
||||
"description": "This schema provides the the report format for the Secret Detection analyzer (https://docs.gitlab.com/ee/user/application_security/secret_detection)",
|
||||
"definitions": {
|
||||
"detail_type": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/list"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/table"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/text"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/url"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/code"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/value"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/diff"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/markdown"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/commit"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/file_location"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/module_location"
|
||||
}
|
||||
]
|
||||
},
|
||||
"text_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"named_field": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"minLength": 1
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"named_list": {
|
||||
"type": "object",
|
||||
"description": "An object with named and typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "named-list"
|
||||
},
|
||||
"items": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
"^.*$": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/named_field"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"list": {
|
||||
"type": "object",
|
||||
"description": "A list of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "list"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"type": "object",
|
||||
"description": "A table of typed fields",
|
||||
"required": [
|
||||
"type",
|
||||
"rows"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "table"
|
||||
},
|
||||
"header": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
},
|
||||
"rows": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/detail_type"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"text": {
|
||||
"type": "object",
|
||||
"description": "Raw text",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "text"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "object",
|
||||
"description": "A single URL",
|
||||
"required": [
|
||||
"type",
|
||||
"href"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "url"
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/definitions/text_value"
|
||||
},
|
||||
"href": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"http://mysite.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"code": {
|
||||
"type": "object",
|
||||
"description": "A codeblock",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "code"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
"description": "A programming language"
|
||||
}
|
||||
}
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"description": "A field that can store a range of types of value",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "value"
|
||||
},
|
||||
"value": {
|
||||
"type": [
|
||||
"number",
|
||||
"string",
|
||||
"boolean"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"type": "object",
|
||||
"description": "A diff",
|
||||
"required": [
|
||||
"type",
|
||||
"before",
|
||||
"after"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "diff"
|
||||
},
|
||||
"before": {
|
||||
"type": "string"
|
||||
},
|
||||
"after": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown": {
|
||||
"type": "object",
|
||||
"description": "GitLab flavoured markdown, see https://docs.gitlab.com/ee/user/markdown.html",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "markdown"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/text_value",
|
||||
"examples": [
|
||||
"Here is markdown `inline code` #1 [test](gitlab.com)\n\n"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"commit": {
|
||||
"type": "object",
|
||||
"description": "A commit/tag/branch within the GitLab project",
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "commit"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The commit SHA",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"file_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a file in the project",
|
||||
"required": [
|
||||
"type",
|
||||
"file_name",
|
||||
"line_start"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "file-location"
|
||||
},
|
||||
"file_name": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"line_start": {
|
||||
"type": "integer"
|
||||
},
|
||||
"line_end": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"module_location": {
|
||||
"type": "object",
|
||||
"description": "A location within a binary module of the form module+relative_offset",
|
||||
"required": [
|
||||
"type",
|
||||
"module_name",
|
||||
"offset"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "module-location"
|
||||
},
|
||||
"module_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"compiled_binary"
|
||||
]
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"examples": [
|
||||
100
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"self": {
|
||||
"version": "14.1.3"
|
||||
},
|
||||
"required": [
|
||||
"version",
|
||||
"vulnerabilities"
|
||||
],
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"scan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"end_time",
|
||||
"scanner",
|
||||
"start_time",
|
||||
"status",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"end_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan finished.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-01-28T03:26:02"
|
||||
]
|
||||
},
|
||||
"messages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Communication intended for the initiator of a scan.",
|
||||
"required": [
|
||||
"level",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"level": {
|
||||
"type": "string",
|
||||
"description": "Describes the severity of the communication. Use info to communicate normal scan behaviour; warn to communicate a potentially recoverable problem, or a partial error; fatal to communicate an issue that causes the scan to halt.",
|
||||
"enum": [
|
||||
"info",
|
||||
"warn",
|
||||
"fatal"
|
||||
],
|
||||
"examples": [
|
||||
"info"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The message to communicate.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"Permission denied, scanning aborted"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"analyzer": {
|
||||
"type": "object",
|
||||
"description": "Object defining the analyzer used to perform the scan. Analyzers typically delegate to an underlying scanner to run the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"gitlab-dast"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the analyzer, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab DAST"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"pattern": "^https?://.+",
|
||||
"description": "A link to more information about the analyzer.",
|
||||
"examples": [
|
||||
"https://docs.gitlab.com/ee/user/application_security/dast"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the analyzer.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the analyzer.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanner": {
|
||||
"type": "object",
|
||||
"description": "Object defining the scanner used to perform the scan.",
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"version",
|
||||
"vendor"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique id that identifies the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"my-sast-scanner"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "A human readable value that identifies the scanner, not required to be unique.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"My SAST Scanner"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "A link to more information about the scanner.",
|
||||
"examples": [
|
||||
"https://scanner.url"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the scanner.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"1.0.2"
|
||||
]
|
||||
},
|
||||
"vendor": {
|
||||
"description": "The vendor/maintainer of the scanner.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vendor.",
|
||||
"minLength": 1,
|
||||
"examples": [
|
||||
"GitLab"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"description": "ISO8601 UTC value with format yyyy-mm-ddThh:mm:ss, representing when the scan started.",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}\\:\\d{2}\\:\\d{2}$",
|
||||
"examples": [
|
||||
"2020-02-14T16:01:59"
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"success",
|
||||
"failure"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of the scan.",
|
||||
"enum": [
|
||||
"secret_detection"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"description": "URI pointing to the validating security report schema.",
|
||||
"format": "uri"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "The version of the schema to which the JSON report conforms.",
|
||||
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
||||
},
|
||||
"vulnerabilities": {
|
||||
"type": "array",
|
||||
"description": "Array of vulnerability objects.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Describes the vulnerability using GitLab Flavored Markdown",
|
||||
"required": [
|
||||
"category",
|
||||
"cve",
|
||||
"identifiers",
|
||||
"location",
|
||||
"scanner"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the vulnerability. This is recommended to be a UUID.",
|
||||
"examples": [
|
||||
"642735a5-1425-428d-8d4e-3c854885a3c9"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Describes where this vulnerability belongs (for example, SAST, Dependency Scanning, and so on)."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name of the vulnerability. This must not include the finding's specific information."
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A short text section that describes the vulnerability. This may include the finding's specific information."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A long text section describing the vulnerability more fully."
|
||||
},
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"description": "How much the vulnerability impacts the software. Possible values are Info, Unknown, Low, Medium, High, or Critical. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Info",
|
||||
"Unknown",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Critical"
|
||||
]
|
||||
},
|
||||
"confidence": {
|
||||
"type": "string",
|
||||
"description": "How reliable the vulnerability's assessment is. Possible values are Ignore, Unknown, Experimental, Low, Medium, High, and Confirmed. Note that some analyzers may not report all these possible values.",
|
||||
"enum": [
|
||||
"Ignore",
|
||||
"Unknown",
|
||||
"Experimental",
|
||||
"Low",
|
||||
"Medium",
|
||||
"High",
|
||||
"Confirmed"
|
||||
]
|
||||
},
|
||||
"solution": {
|
||||
"type": "string",
|
||||
"description": "Explanation of how to fix the vulnerability."
|
||||
},
|
||||
"scanner": {
|
||||
"description": "Describes the scanner used to find this vulnerability.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "The scanner's ID, as a snake_case string."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Human-readable name of the scanner."
|
||||
}
|
||||
}
|
||||
},
|
||||
"identifiers": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "An ordered array of references that identify a vulnerability on internal or external databases. The first identifier is the Primary Identifier, which has special meaning.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type",
|
||||
"name",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "for example, cve, cwe, osvdb, usn, or an analyzer-dependent type such as gemnasium).",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Human-readable name of the identifier.",
|
||||
"minLength": 1
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the identifier's documentation.",
|
||||
"format": "uri"
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Value of the identifier, for matching purpose.",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"type": "array",
|
||||
"description": "An array of references to external documentation or articles that describe the vulnerability.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"url"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the vulnerability details link."
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "URL of the vulnerability details document.",
|
||||
"format": "uri"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"details": {
|
||||
"$ref": "#/definitions/named_list/properties/items"
|
||||
},
|
||||
"tracking": {
|
||||
"description": "Describes how this vulnerability should be tracked as the project changes.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Declares that a series of items should be tracked using source-specific tracking methods.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"const": "source"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item that should be tracked using source-specific tracking methods.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"signatures"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located."
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the file that includes the vulnerability."
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the file that includes the vulnerability."
|
||||
},
|
||||
"signatures": {
|
||||
"type": "array",
|
||||
"description": "An array of calculated tracking signatures for this tracking item.",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "A calculated tracking signature value and metadata.",
|
||||
"required": [
|
||||
"algorithm",
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"algorithm": {
|
||||
"type": "string",
|
||||
"description": "The algorithm used to generate the signature."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "The result of this signature algorithm."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Each tracking type must declare its own type."
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"description": "Flags that can be attached to vulnerabilities.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"description": "Informational flags identified and assigned to a vulnerability.",
|
||||
"required": [
|
||||
"type",
|
||||
"origin",
|
||||
"description"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "Result of the scan.",
|
||||
"enum": [
|
||||
"flagged-as-likely-false-positive"
|
||||
]
|
||||
},
|
||||
"origin": {
|
||||
"minLength": 1,
|
||||
"description": "Tool that issued the flag.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"minLength": 1,
|
||||
"description": "What the flag is about.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"required": [
|
||||
"commit"
|
||||
],
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"description": "Path to the file where the vulnerability is located"
|
||||
},
|
||||
"commit": {
|
||||
"type": "object",
|
||||
"description": "Represents the commit in which the vulnerability was detected",
|
||||
"required": [
|
||||
"sha"
|
||||
],
|
||||
"properties": {
|
||||
"author": {
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"sha": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_line": {
|
||||
"type": "number",
|
||||
"description": "The first line of the code affected by the vulnerability"
|
||||
},
|
||||
"end_line": {
|
||||
"type": "number",
|
||||
"description": "The last line of the code affected by the vulnerability"
|
||||
},
|
||||
"class": {
|
||||
"type": "string",
|
||||
"description": "Provides the name of the class where the vulnerability is located"
|
||||
},
|
||||
"method": {
|
||||
"type": "string",
|
||||
"description": "Provides the name of the method where the vulnerability is located"
|
||||
}
|
||||
}
|
||||
},
|
||||
"raw_source_code_extract": {
|
||||
"type": "string",
|
||||
"description": "Provides an unsanitized excerpt of the affected source code."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediations": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing information on available remediations, along with patch diffs to apply.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fixes",
|
||||
"summary",
|
||||
"diff"
|
||||
],
|
||||
"properties": {
|
||||
"fixes": {
|
||||
"type": "array",
|
||||
"description": "An array of strings that represent references to vulnerabilities fixed by this remediation.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"cve"
|
||||
],
|
||||
"properties": {
|
||||
"cve": {
|
||||
"type": "string",
|
||||
"description": "(Deprecated - use vulnerabilities[].id instead) A fingerprint string value that represents a concrete finding. This is used to determine whether two findings are same, which may not be 100% accurate. Note that this is NOT a CVE as described by https://cve.mitre.org/."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "An overview of how the vulnerabilities were fixed."
|
||||
},
|
||||
"diff": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"description": "A base64-encoded remediation code diff, compatible with git apply."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,11 +6,7 @@ module Gitlab
|
|||
class StreamingSerializer
|
||||
include Gitlab::ImportExport::CommandLineUtil
|
||||
|
||||
BATCH_SIZE = 2
|
||||
|
||||
def self.batch_size(exportable)
|
||||
BATCH_SIZE
|
||||
end
|
||||
BATCH_SIZE = 100
|
||||
|
||||
class Raw < String
|
||||
def to_json(*_args)
|
||||
|
|
@ -88,7 +84,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def batch(relation, key)
|
||||
opts = { of: batch_size }
|
||||
opts = { of: BATCH_SIZE }
|
||||
order_by = reorders(relation, key)
|
||||
|
||||
# we need to sort issues by non primary key column(relative_position)
|
||||
|
|
@ -138,10 +134,6 @@ module Gitlab
|
|||
relations_schema[:preload]
|
||||
end
|
||||
|
||||
def batch_size
|
||||
@batch_size ||= self.class.batch_size(@exportable)
|
||||
end
|
||||
|
||||
def reorders(relation, key)
|
||||
export_reorder = relations_schema[:export_reorder]&.dig(key)
|
||||
return unless export_reorder
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Gitlab
|
|||
|
||||
def serialize(exportable, relations_tree)
|
||||
Gitlab::ImportExport::FastHashSerializer
|
||||
.new(exportable, relations_tree, batch_size: batch_size(exportable))
|
||||
.new(exportable, relations_tree)
|
||||
.execute
|
||||
end
|
||||
|
||||
|
|
@ -18,12 +18,6 @@ module Gitlab
|
|||
|
||||
File.write(File.join(dir_path, filename), tree_json)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def batch_size(exportable)
|
||||
Gitlab::ImportExport::Json::StreamingSerializer.batch_size(exportable)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@
|
|||
"cheerio": "^1.0.0-rc.9",
|
||||
"commander": "^2.20.3",
|
||||
"custom-jquery-matchers": "^2.1.0",
|
||||
"eslint": "8.23.0",
|
||||
"eslint": "8.23.1",
|
||||
"eslint-import-resolver-jest": "3.0.2",
|
||||
"eslint-import-resolver-webpack": "0.13.2",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
|
|
|
|||
|
|
@ -270,9 +270,13 @@ RSpec.describe Projects::PipelinesController do
|
|||
user: user,
|
||||
merge_request: merge_request)
|
||||
|
||||
create_build(pipeline, 'build', 1, 'build', user)
|
||||
create_build(pipeline, 'test', 2, 'test', user)
|
||||
create_build(pipeline, 'deploy', 3, 'deploy', user)
|
||||
build_stage = create(:ci_stage, name: 'build', pipeline: pipeline)
|
||||
test_stage = create(:ci_stage, name: 'test', pipeline: pipeline)
|
||||
deploy_stage = create(:ci_stage, name: 'deploy', pipeline: pipeline)
|
||||
|
||||
create_build(pipeline, build_stage, 1, 'build', user)
|
||||
create_build(pipeline, test_stage, 2, 'test', user)
|
||||
create_build(pipeline, deploy_stage, 3, 'deploy', user)
|
||||
|
||||
pipeline
|
||||
end
|
||||
|
|
@ -284,7 +288,7 @@ RSpec.describe Projects::PipelinesController do
|
|||
:artifacts,
|
||||
artifacts_expire_at: 2.days.from_now,
|
||||
pipeline: pipeline,
|
||||
stage: stage,
|
||||
ci_stage: stage,
|
||||
stage_idx: stage_idx,
|
||||
name: name,
|
||||
status: status,
|
||||
|
|
@ -327,21 +331,24 @@ RSpec.describe Projects::PipelinesController do
|
|||
render_views
|
||||
|
||||
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
|
||||
let_it_be(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) }
|
||||
let_it_be(:test_stage) { create(:ci_stage, name: 'test', pipeline: pipeline) }
|
||||
let_it_be(:deploy_stage) { create(:ci_stage, name: 'deploy', pipeline: pipeline) }
|
||||
|
||||
def create_build_with_artifacts(stage, stage_idx, name, status)
|
||||
create(:ci_build, :artifacts, :tags, status, user: user, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name)
|
||||
create(:ci_build, :artifacts, :tags, status, user: user, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name)
|
||||
end
|
||||
|
||||
def create_bridge(stage, stage_idx, name, status)
|
||||
create(:ci_bridge, status, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name)
|
||||
create(:ci_bridge, status, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name)
|
||||
end
|
||||
|
||||
before do
|
||||
create_build_with_artifacts('build', 0, 'job1', :failed)
|
||||
create_build_with_artifacts('build', 0, 'job2', :running)
|
||||
create_build_with_artifacts('build', 0, 'job3', :pending)
|
||||
create_bridge('deploy', 1, 'deploy-a', :failed)
|
||||
create_bridge('deploy', 1, 'deploy-b', :created)
|
||||
create_build_with_artifacts(build_stage, 0, 'job1', :failed)
|
||||
create_build_with_artifacts(build_stage, 0, 'job2', :running)
|
||||
create_build_with_artifacts(build_stage, 0, 'job3', :pending)
|
||||
create_bridge(deploy_stage, 1, 'deploy-a', :failed)
|
||||
create_bridge(deploy_stage, 1, 'deploy-b', :created)
|
||||
end
|
||||
|
||||
it 'avoids N+1 database queries', :request_store, :use_sql_query_cache do
|
||||
|
|
@ -354,11 +361,11 @@ RSpec.describe Projects::PipelinesController do
|
|||
expect(response).to have_gitlab_http_status(:ok)
|
||||
end
|
||||
|
||||
create_build_with_artifacts('build', 0, 'job4', :failed)
|
||||
create_build_with_artifacts('build', 0, 'job5', :running)
|
||||
create_build_with_artifacts('build', 0, 'job6', :pending)
|
||||
create_bridge('deploy', 1, 'deploy-c', :failed)
|
||||
create_bridge('deploy', 1, 'deploy-d', :created)
|
||||
create_build_with_artifacts(build_stage, 0, 'job4', :failed)
|
||||
create_build_with_artifacts(build_stage, 0, 'job5', :running)
|
||||
create_build_with_artifacts(build_stage, 0, 'job6', :pending)
|
||||
create_bridge(deploy_stage, 1, 'deploy-c', :failed)
|
||||
create_bridge(deploy_stage, 1, 'deploy-d', :created)
|
||||
|
||||
expect do
|
||||
get_pipeline_html
|
||||
|
|
@ -402,11 +409,16 @@ RSpec.describe Projects::PipelinesController do
|
|||
sha: project.commit.id)
|
||||
end
|
||||
|
||||
let(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) }
|
||||
let(:test_stage) { create(:ci_stage, name: 'test', pipeline: pipeline) }
|
||||
let(:deploy_stage) { create(:ci_stage, name: 'deploy', pipeline: pipeline) }
|
||||
let(:post_deploy_stage) { create(:ci_stage, name: 'post deploy', pipeline: pipeline) }
|
||||
|
||||
before do
|
||||
create_build('build', 0, 'build')
|
||||
create_build('test', 1, 'rspec 0')
|
||||
create_build('deploy', 2, 'production')
|
||||
create_build('post deploy', 3, 'pages 0')
|
||||
create_build(build_stage, 0, 'build')
|
||||
create_build(test_stage, 1, 'rspec 0')
|
||||
create_build(deploy_stage, 2, 'production')
|
||||
create_build(post_deploy_stage, 3, 'pages 0')
|
||||
end
|
||||
|
||||
it 'does not perform N + 1 queries' do
|
||||
|
|
@ -612,7 +624,9 @@ RSpec.describe Projects::PipelinesController do
|
|||
|
||||
def create_pipeline(project)
|
||||
create(:ci_empty_pipeline, project: project).tap do |pipeline|
|
||||
create(:ci_build, pipeline: pipeline, stage: 'test', name: 'rspec')
|
||||
create(:ci_build, pipeline: pipeline,
|
||||
ci_stage: create(:ci_stage, name: 'test', pipeline: pipeline),
|
||||
name: 'rspec')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -642,7 +656,7 @@ RSpec.describe Projects::PipelinesController do
|
|||
end
|
||||
|
||||
def create_build(stage, stage_idx, name)
|
||||
create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name)
|
||||
create(:ci_build, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -654,10 +668,12 @@ RSpec.describe Projects::PipelinesController do
|
|||
|
||||
describe 'GET dag.json' do
|
||||
let(:pipeline) { create(:ci_pipeline, project: project) }
|
||||
let(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) }
|
||||
let(:test_stage) { create(:ci_stage, name: 'test', pipeline: pipeline) }
|
||||
|
||||
before do
|
||||
create_build('build', 1, 'build')
|
||||
create_build('test', 2, 'test', scheduling_type: 'dag').tap do |job|
|
||||
create_build(build_stage, 1, 'build')
|
||||
create_build(test_stage, 2, 'test', scheduling_type: 'dag').tap do |job|
|
||||
create(:ci_build_need, build: job, name: 'build')
|
||||
end
|
||||
end
|
||||
|
|
@ -681,7 +697,7 @@ RSpec.describe Projects::PipelinesController do
|
|||
end
|
||||
|
||||
def create_build(stage, stage_idx, name, params = {})
|
||||
create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, **params)
|
||||
create(:ci_build, pipeline: pipeline, ci_stage: stage, stage_idx: stage_idx, name: name, **params)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -730,11 +746,12 @@ RSpec.describe Projects::PipelinesController do
|
|||
|
||||
describe 'GET stages.json' do
|
||||
let(:pipeline) { create(:ci_pipeline, project: project) }
|
||||
let(:build_stage) { create(:ci_stage, name: 'build', pipeline: pipeline) }
|
||||
|
||||
context 'when accessing existing stage' do
|
||||
before do
|
||||
create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build')
|
||||
create(:ci_build, pipeline: pipeline, stage: 'build')
|
||||
create(:ci_build, :retried, :failed, pipeline: pipeline, ci_stage: build_stage)
|
||||
create(:ci_build, pipeline: pipeline, ci_stage: build_stage)
|
||||
end
|
||||
|
||||
context 'without retried' do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
FactoryBot.define do
|
||||
factory :ml_candidates, class: '::Ml::Candidate' do
|
||||
association :experiment, factory: :ml_experiments
|
||||
association :user
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"run"
|
||||
],
|
||||
"properties": {
|
||||
"run": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"info",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"info": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"run_id",
|
||||
"run_uuid",
|
||||
"user_id",
|
||||
"experiment_id",
|
||||
"status",
|
||||
"start_time",
|
||||
"artifact_uri",
|
||||
"lifecycle_stage"
|
||||
],
|
||||
"optional": [
|
||||
"end_time"
|
||||
],
|
||||
"properties": {
|
||||
"run_id": { "type": "string" },
|
||||
"run_uuid": { "type": "string" },
|
||||
"experiment_id": { "type": "string" },
|
||||
"artifact_location": { "type": "string" },
|
||||
"start_time": { "type": "integer" },
|
||||
"end_time": { "type": "integer" },
|
||||
"user_id": "",
|
||||
"status": { "type": { "enum" : ["RUNNING", "SCHEDULED", "FINISHED", "FAILED", "KILLED"] } },
|
||||
"lifecycle_stage": { "type": { "enum" : ["active"] } }
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"run_info"
|
||||
],
|
||||
"properties": {
|
||||
"run_info": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"run_id",
|
||||
"run_uuid",
|
||||
"user_id",
|
||||
"experiment_id",
|
||||
"status",
|
||||
"start_time",
|
||||
"artifact_uri",
|
||||
"lifecycle_stage"
|
||||
],
|
||||
"optional": [
|
||||
"end_time"
|
||||
],
|
||||
"properties": {
|
||||
"run_id": { "type": "string" },
|
||||
"run_uuid": { "type": "string" },
|
||||
"experiment_id": { "type": "string" },
|
||||
"artifact_location": { "type": "string" },
|
||||
"start_time": { "type": "integer" },
|
||||
"end_time": { "type": "integer" },
|
||||
"user_id": { "type": "string" },
|
||||
"status": { "type": { "enum" : ["RUNNING", "SCHEDULED", "FINISHED", "FAILED", "KILLED"] } },
|
||||
"lifecycle_stage": { "type": { "enum" : ["active"] } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,7 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe JiraConnectHelper do
|
||||
describe '#jira_connect_app_data' do
|
||||
let_it_be(:installation) { create(:jira_connect_installation) }
|
||||
let_it_be(:subscription) { create(:jira_connect_subscription, installation: installation) }
|
||||
let_it_be(:subscription) { create(:jira_connect_subscription) }
|
||||
|
||||
let(:user) { create(:user) }
|
||||
let(:client_id) { '123' }
|
||||
|
|
@ -14,12 +13,11 @@ RSpec.describe JiraConnectHelper do
|
|||
stub_application_setting(jira_connect_application_key: client_id)
|
||||
end
|
||||
|
||||
subject { helper.jira_connect_app_data([subscription], installation) }
|
||||
subject { helper.jira_connect_app_data([subscription]) }
|
||||
|
||||
context 'user is not logged in' do
|
||||
before do
|
||||
allow(view).to receive(:current_user).and_return(nil)
|
||||
allow(Gitlab).to receive_message_chain('config.gitlab.host') { 'http://test.host' }
|
||||
end
|
||||
|
||||
it 'includes Jira Connect app attributes' do
|
||||
|
|
@ -38,7 +36,7 @@ RSpec.describe JiraConnectHelper do
|
|||
end
|
||||
|
||||
context 'with oauth_metadata' do
|
||||
let(:oauth_metadata) { helper.jira_connect_app_data([subscription], installation)[:oauth_metadata] }
|
||||
let(:oauth_metadata) { helper.jira_connect_app_data([subscription])[:oauth_metadata] }
|
||||
|
||||
subject(:parsed_oauth_metadata) { Gitlab::Json.parse(oauth_metadata).deep_symbolize_keys }
|
||||
|
||||
|
|
@ -76,30 +74,6 @@ RSpec.describe JiraConnectHelper do
|
|||
expect(oauth_metadata).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with self-managed instance' do
|
||||
let_it_be(:installation) { create(:jira_connect_installation, instance_url: 'https://gitlab.example.com') }
|
||||
|
||||
it 'points urls to the self-managed instance' do
|
||||
expect(parsed_oauth_metadata).to include(
|
||||
oauth_authorize_url: start_with('https://gitlab.example.com/oauth/authorize?'),
|
||||
oauth_token_url: 'https://gitlab.example.com/oauth/token'
|
||||
)
|
||||
end
|
||||
|
||||
context 'and jira_connect_oauth_self_managed feature is disabled' do
|
||||
before do
|
||||
stub_feature_flags(jira_connect_oauth_self_managed: false)
|
||||
end
|
||||
|
||||
it 'does not point urls to the self-managed instance' do
|
||||
expect(parsed_oauth_metadata).not_to include(
|
||||
oauth_authorize_url: start_with('https://gitlab.example.com/oauth/authorize?'),
|
||||
oauth_token_url: 'https://gitlab.example.com/oauth/token'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'passes group as "skip_groups" param' do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe API::Entities::Ml::Mlflow::RunInfo do
|
||||
let_it_be(:candidate) { create(:ml_candidates) }
|
||||
|
||||
subject { described_class.new(candidate).as_json }
|
||||
|
||||
context 'when start_time is nil' do
|
||||
it { expect(subject[:start_time]).to eq(0) }
|
||||
end
|
||||
|
||||
context 'when start_time is not nil' do
|
||||
before do
|
||||
allow(candidate).to receive(:start_time).and_return(1234)
|
||||
end
|
||||
|
||||
it { expect(subject[:start_time]).to eq(1234) }
|
||||
end
|
||||
|
||||
describe 'end_time' do
|
||||
context 'when nil' do
|
||||
it { is_expected.not_to have_key(:end_time) }
|
||||
end
|
||||
|
||||
context 'when not nil' do
|
||||
before do
|
||||
allow(candidate).to receive(:end_time).and_return(1234)
|
||||
end
|
||||
|
||||
it { expect(subject[:end_time]).to eq(1234) }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'experiment_id' do
|
||||
it 'is the experiment iid as string' do
|
||||
expect(subject[:experiment_id]).to eq(candidate.experiment.iid.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'run_id' do
|
||||
it 'is the iid as string' do
|
||||
expect(subject[:run_id]).to eq(candidate.iid.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'run_uuid' do
|
||||
it 'is the iid as string' do
|
||||
expect(subject[:run_uuid]).to eq(candidate.iid.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'artifact_uri' do
|
||||
it 'is not implemented' do
|
||||
expect(subject[:artifact_uri]).to eq('not_implemented')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'lifecycle_stage' do
|
||||
it 'is active' do
|
||||
expect(subject[:lifecycle_stage]).to eq('active')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe API::Entities::Ml::Mlflow::Run do
|
||||
let_it_be(:candidate) { create(:ml_candidates) }
|
||||
|
||||
subject { described_class.new(candidate).as_json }
|
||||
|
||||
it 'has run key' do
|
||||
expect(subject).to have_key(:run)
|
||||
end
|
||||
|
||||
it 'has the id' do
|
||||
expect(subject[:run][:info][:run_id]).to eq(candidate.iid.to_s)
|
||||
end
|
||||
|
||||
it 'data is empty' do
|
||||
expect(subject[:run][:data]).to be_empty
|
||||
end
|
||||
end
|
||||
|
|
@ -212,12 +212,6 @@ RSpec.describe Gitlab::ImportExport::Json::StreamingSerializer do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.batch_size' do
|
||||
it 'returns default batch size' do
|
||||
expect(described_class.batch_size(exportable)).to eq(described_class::BATCH_SIZE)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#serialize_relation' do
|
||||
context 'when record is a merge request' do
|
||||
let(:json_writer) do
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ RSpec.describe Gitlab::ImportExport::LegacyRelationTreeSaver do
|
|||
it 'uses FastHashSerializer' do
|
||||
expect(Gitlab::ImportExport::FastHashSerializer)
|
||||
.to receive(:new)
|
||||
.with(exportable, tree, batch_size: Gitlab::ImportExport::Json::StreamingSerializer::BATCH_SIZE)
|
||||
.with(exportable, tree)
|
||||
.and_return(serializer)
|
||||
|
||||
expect(serializer).to receive(:execute)
|
||||
|
|
|
|||
|
|
@ -45,30 +45,4 @@ RSpec.describe JiraConnectInstallation do
|
|||
expect(subject).to contain_exactly(subscription.installation)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#oauth_authorization_url' do
|
||||
let_it_be(:installation) { create(:jira_connect_installation) }
|
||||
|
||||
subject { installation.oauth_authorization_url }
|
||||
|
||||
before do
|
||||
allow(Gitlab).to receive_message_chain('config.gitlab.host') { 'http://test.host' }
|
||||
end
|
||||
|
||||
it { is_expected.to eq('http://test.host') }
|
||||
|
||||
context 'with instance_url' do
|
||||
let_it_be(:installation) { create(:jira_connect_installation, instance_url: 'https://gitlab.example.com') }
|
||||
|
||||
it { is_expected.to eq('https://gitlab.example.com') }
|
||||
|
||||
context 'and jira_connect_oauth_self_managed feature is disabled' do
|
||||
before do
|
||||
stub_feature_flags(jira_connect_oauth_self_managed: false)
|
||||
end
|
||||
|
||||
it { is_expected.to eq('http://test.host') }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,4 +9,35 @@ RSpec.describe Ml::Candidate do
|
|||
it { is_expected.to have_many(:params) }
|
||||
it { is_expected.to have_many(:metrics) }
|
||||
end
|
||||
|
||||
describe '#new' do
|
||||
it 'iid is not null' do
|
||||
expect(create(:ml_candidates).iid).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'by_project_id_and_iid' do
|
||||
let_it_be(:candidate) { create(:ml_candidates) }
|
||||
|
||||
let(:project_id) { candidate.experiment.project_id }
|
||||
let(:iid) { candidate.iid }
|
||||
|
||||
subject { described_class.with_project_id_and_iid(project_id, iid) }
|
||||
|
||||
context 'when iid exists', 'and belongs to project' do
|
||||
it { is_expected.to eq(candidate) }
|
||||
end
|
||||
|
||||
context 'when iid exists', 'and does not belong to project' do
|
||||
let(:project_id) { non_existing_record_id }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
|
||||
context 'when iid does not exist' do
|
||||
let(:iid) { 'a' }
|
||||
|
||||
it { is_expected.to be_nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,9 +14,18 @@ RSpec.describe API::Ml::Mlflow do
|
|||
create(:ml_experiments, user: project.creator, project: project)
|
||||
end
|
||||
|
||||
let_it_be(:candidate) do
|
||||
create(:ml_candidates, user: experiment.user, start_time: 1234, experiment: experiment)
|
||||
end
|
||||
|
||||
let_it_be(:another_candidate) do
|
||||
create(:ml_candidates,
|
||||
experiment: create(:ml_experiments, project: create(:project)))
|
||||
end
|
||||
|
||||
let(:current_user) { developer }
|
||||
let(:ff_value) { true }
|
||||
let(:scopes) { %w[api] }
|
||||
let(:scopes) { %w[read_api api] }
|
||||
let(:headers) do
|
||||
{ 'Authorization' => "Bearer #{create(:personal_access_token, scopes: scopes, user: current_user).token}" }
|
||||
end
|
||||
|
|
@ -46,6 +55,22 @@ RSpec.describe API::Ml::Mlflow do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples 'Requires api scope' do
|
||||
context 'when user has access but token has wrong scope' do
|
||||
let(:scopes) { %w[read_api] }
|
||||
|
||||
it { expect(response).to have_gitlab_http_status(:forbidden) }
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'Requires read_api scope' do
|
||||
context 'when user has access but token has wrong scope' do
|
||||
let(:scopes) { %w[read_user] }
|
||||
|
||||
it { expect(response).to have_gitlab_http_status(:forbidden) }
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'Bad Request' do |error_code = nil|
|
||||
it "is Bad Request" do
|
||||
expect(response).to have_gitlab_http_status(:bad_request)
|
||||
|
|
@ -109,6 +134,7 @@ RSpec.describe API::Ml::Mlflow do
|
|||
end
|
||||
|
||||
it_behaves_like 'shared error cases'
|
||||
it_behaves_like 'Requires read_api scope'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -145,6 +171,7 @@ RSpec.describe API::Ml::Mlflow do
|
|||
end
|
||||
|
||||
it_behaves_like 'shared error cases'
|
||||
it_behaves_like 'Requires read_api scope'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -183,6 +210,157 @@ RSpec.describe API::Ml::Mlflow do
|
|||
|
||||
it_behaves_like 'Not Found', '404 Project Not Found'
|
||||
end
|
||||
|
||||
it_behaves_like 'shared error cases'
|
||||
it_behaves_like 'Requires api scope'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Runs' do
|
||||
describe 'POST /projects/:id/ml/mflow/api/2.0/mlflow/runs/create' do
|
||||
let(:route) do
|
||||
"/projects/#{project.id}/ml/mflow/api/2.0/mlflow/runs/create"
|
||||
end
|
||||
|
||||
let(:params) { { experiment_id: experiment.iid.to_s, start_time: Time.now.to_i } }
|
||||
let(:request) { post api(route), params: params, headers: headers }
|
||||
|
||||
it 'creates the run' do
|
||||
expected_properties = {
|
||||
'experiment_id' => params[:experiment_id],
|
||||
'user_id' => current_user.id.to_s,
|
||||
'start_time' => params[:start_time],
|
||||
'artifact_uri' => 'not_implemented',
|
||||
'status' => "RUNNING",
|
||||
'lifecycle_stage' => "active"
|
||||
}
|
||||
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
expect(response).to match_response_schema('ml/run')
|
||||
expect(json_response['run']).to include('info' => hash_including(**expected_properties), 'data' => {})
|
||||
end
|
||||
|
||||
describe 'Error States' do
|
||||
context 'when experiment id is not passed' do
|
||||
let(:params) { {} }
|
||||
|
||||
it_behaves_like 'Bad Request'
|
||||
end
|
||||
|
||||
context 'when experiment id does not exist' do
|
||||
let(:params) { { experiment_id: non_existing_record_iid.to_s } }
|
||||
|
||||
it_behaves_like 'Not Found - Resource Does Not Exist'
|
||||
end
|
||||
|
||||
it_behaves_like 'shared error cases'
|
||||
it_behaves_like 'Requires api scope'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /projects/:id/ml/mflow/api/2.0/mlflow/runs/get' do
|
||||
let_it_be(:route) do
|
||||
"/projects/#{project.id}/ml/mflow/api/2.0/mlflow/runs/get"
|
||||
end
|
||||
|
||||
let_it_be(:candidate) { create(:ml_candidates, user: experiment.user, start_time: 1234, experiment: experiment) }
|
||||
|
||||
let(:params) { { 'run_id' => candidate.iid } }
|
||||
|
||||
it 'gets the run' do
|
||||
expected_properties = {
|
||||
'experiment_id' => candidate.experiment.iid.to_s,
|
||||
'user_id' => candidate.user.id.to_s,
|
||||
'start_time' => candidate.start_time,
|
||||
'artifact_uri' => 'not_implemented',
|
||||
'status' => "RUNNING",
|
||||
'lifecycle_stage' => "active"
|
||||
}
|
||||
|
||||
expect(response).to have_gitlab_http_status(:success)
|
||||
expect(response).to match_response_schema('ml/run')
|
||||
expect(json_response['run']).to include('info' => hash_including(**expected_properties), 'data' => {})
|
||||
end
|
||||
|
||||
describe 'Error States' do
|
||||
context 'when run id is not passed' do
|
||||
let(:params) { {} }
|
||||
|
||||
it_behaves_like 'Not Found - Resource Does Not Exist'
|
||||
end
|
||||
|
||||
context 'when run id does not exist' do
|
||||
let(:params) { { run_id: non_existing_record_iid.to_s } }
|
||||
|
||||
it_behaves_like 'Not Found - Resource Does Not Exist'
|
||||
end
|
||||
|
||||
context 'when run id exists but does not belong to project' do
|
||||
let(:params) { { run_id: another_candidate.iid.to_s } }
|
||||
|
||||
it_behaves_like 'Not Found - Resource Does Not Exist'
|
||||
end
|
||||
|
||||
it_behaves_like 'shared error cases'
|
||||
it_behaves_like 'Requires read_api scope'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /projects/:id/ml/mflow/api/2.0/mlflow/runs/update' do
|
||||
let(:route) { "/projects/#{project.id}/ml/mflow/api/2.0/mlflow/runs/update" }
|
||||
let(:params) { { run_id: candidate.iid.to_s, status: 'FAILED', end_time: Time.now.to_i } }
|
||||
let(:request) { post api(route), params: params, headers: headers }
|
||||
|
||||
it 'updates the run' do
|
||||
expected_properties = {
|
||||
'experiment_id' => candidate.experiment.iid.to_s,
|
||||
'user_id' => candidate.user.id.to_s,
|
||||
'start_time' => candidate.start_time,
|
||||
'end_time' => params[:end_time],
|
||||
'artifact_uri' => 'not_implemented',
|
||||
'status' => 'FAILED',
|
||||
'lifecycle_stage' => 'active'
|
||||
}
|
||||
|
||||
expect(response).to have_gitlab_http_status(:success)
|
||||
expect(response).to match_response_schema('ml/update_run')
|
||||
expect(json_response).to include('run_info' => hash_including(**expected_properties))
|
||||
end
|
||||
|
||||
describe 'Error States' do
|
||||
context 'when run id is not passed' do
|
||||
let(:params) { {} }
|
||||
|
||||
it_behaves_like 'Not Found - Resource Does Not Exist'
|
||||
end
|
||||
|
||||
context 'when run id does not exist' do
|
||||
let(:params) { { run_id: non_existing_record_iid.to_s } }
|
||||
|
||||
it_behaves_like 'Not Found - Resource Does Not Exist'
|
||||
end
|
||||
|
||||
context 'when run id exists but does not belong to project' do
|
||||
let(:params) { { run_id: another_candidate.iid.to_s } }
|
||||
|
||||
it_behaves_like 'Not Found - Resource Does Not Exist'
|
||||
end
|
||||
|
||||
context 'when run id exists but status in invalid' do
|
||||
let(:params) { { run_id: candidate.iid.to_s, status: 'YOLO', end_time: Time.now.to_i } }
|
||||
|
||||
it_behaves_like 'Bad Request'
|
||||
end
|
||||
|
||||
context 'when run id exists but end_time is invalid' do
|
||||
let(:params) { { run_id: candidate.iid.to_s, status: 'FAILED', end_time: 's' } }
|
||||
|
||||
it_behaves_like 'Bad Request'
|
||||
end
|
||||
|
||||
it_behaves_like 'shared error cases'
|
||||
it_behaves_like 'Requires api scope'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
30
yarn.lock
30
yarn.lock
|
|
@ -1007,10 +1007,10 @@
|
|||
ts-node "^9"
|
||||
tslib "^2"
|
||||
|
||||
"@eslint/eslintrc@^1.3.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d"
|
||||
integrity sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==
|
||||
"@eslint/eslintrc@^1.3.2":
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356"
|
||||
integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.3.2"
|
||||
|
|
@ -5294,12 +5294,12 @@ eslint-visitor-keys@^3.3.0:
|
|||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||
|
||||
eslint@8.23.0:
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040"
|
||||
integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==
|
||||
eslint@8.23.1:
|
||||
version "8.23.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.1.tgz#cfd7b3f7fdd07db8d16b4ac0516a29c8d8dca5dc"
|
||||
integrity sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==
|
||||
dependencies:
|
||||
"@eslint/eslintrc" "^1.3.1"
|
||||
"@eslint/eslintrc" "^1.3.2"
|
||||
"@humanwhocodes/config-array" "^0.10.4"
|
||||
"@humanwhocodes/gitignore-to-minimatch" "^1.0.2"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
|
|
@ -5318,7 +5318,6 @@ eslint@8.23.0:
|
|||
fast-deep-equal "^3.1.3"
|
||||
file-entry-cache "^6.0.1"
|
||||
find-up "^5.0.0"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob-parent "^6.0.1"
|
||||
globals "^13.15.0"
|
||||
globby "^11.1.0"
|
||||
|
|
@ -5327,6 +5326,7 @@ eslint@8.23.0:
|
|||
import-fresh "^3.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
is-glob "^4.0.0"
|
||||
js-sdsl "^4.1.4"
|
||||
js-yaml "^4.1.0"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.4.1"
|
||||
|
|
@ -5868,11 +5868,6 @@ function.prototype.name@^1.1.5:
|
|||
es-abstract "^1.19.0"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
functional-red-black-tree@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
functions-have-names@^1.2.2:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
||||
|
|
@ -7487,6 +7482,11 @@ js-cookie@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414"
|
||||
integrity sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==
|
||||
|
||||
js-sdsl@^4.1.4:
|
||||
version "4.1.4"
|
||||
resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.4.tgz#78793c90f80e8430b7d8dc94515b6c77d98a26a6"
|
||||
integrity sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
|
|
|
|||
Loading…
Reference in New Issue