Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,21 @@ You can read more about the technical specifications for a collection, such as t

#### Releasing a Release-Track Snapshot

For a virtual track's recurring schedule, use **Find a schedule** in the Config
tab: typing `hou` suggests **Hourly — at minute 0**, and typing `every 15`
suggests **Every 15 minutes**. Select a suggestion to apply it; unmatched text
does not change the schedule. The controls below let you customize the selected
schedule, and the generated expression is shown before saving. All times are
UTC. Hourly runs at the selected minute of each clock hour; 15/30-minute
intervals align to the clock rather than the time you click Save.

Saving only a schedule leaves the virtual track's composition and draft
unchanged. Deduplication configuration supports the strategy selector;
preferred tier and preferred status are not supported by the API.

The release preview offers minor and major relative tags as well as an exact `MAJOR.MINOR` version. Relative tags are calculated from the tagged snapshot immediately before the selected draft. When releasing an older draft, the exact version must also remain below the next tagged snapshot; the dialog shows these exclusive bounds. Optional release notes are stored on that snapshot and become the `x-mitre-collection` description in exported STIX bundles.

The release-track page follows a draft-then-tag flow: the Board tab manages what the next draft contains (candidates, staged objects, and for virtual tracks the Create Draft action), and the Releases tab previews and tags a draft from its card. Any snapshot can be exported from its card as a STIX 2.0 bundle, a STIX 2.1 bundle, or Workbench JSON. Historical snapshot exports can also copy a concise summary. Every snapshot seals its content when its members are written, so exports replay the exact members, relationships, and supporting objects in either STIX version; released snapshots also show their stable bundle identifier and SHA-256 hashes. Saving a relationship resets its source and target to work-in-progress in place without creating new revisions of those objects. Administrators can delete a track's most recent release from the Releases tab by confirming its version; its version becomes available again and later drafts are kept. A track can carry an alias (a short lowercase slug set in the Config tab) that works in place of its ID in page URLs and API paths; the track list opens aliased tracks by their alias. The dashboard's Data Quality page adds a domain consistency report: relationships whose objects share no domain (and objects with no domain) can never ship in the same bundle, so fix them at the source rather than expecting the bundle to pull in related objects. Only the most recent release offers a delete button, a progress bar with a status message appears under the page header while a long operation runs (creating a draft, preparing or committing a release, deleting a release or the track, saving the configuration), and deleting an entire track lives in the danger zone at the bottom of the Config tab.
The release-track page follows a draft-then-tag flow: the Board tab manages what the next draft contains (candidates, staged objects, and for virtual tracks the Create Draft action), and the Releases tab previews and tags a draft from its card. Any snapshot can be exported from its card as a STIX 2.0 bundle, a STIX 2.1 bundle, or Workbench JSON. Historical snapshot exports can also copy a concise summary. Every snapshot seals its content when its members are written, so exports replay the exact members, relationships, and supporting objects in either STIX version; released snapshots also show their stable bundle identifier and SHA-256 hashes. Saving a relationship resets its source and target to work-in-progress in place without creating new revisions of those objects. Administrators can delete a track's most recent release from the Releases tab by confirming its version; its version becomes available again and later drafts are kept. A track can carry an alias (a short lowercase slug set in the Config tab) that works in place of its ID in page URLs and API paths; the track list opens aliased tracks by their alias. Virtual-track schedules are configured in the Config tab as manual, recurring, or specific dates; recurring schedules use guided cadence/day/time controls that generate a five-field UTC cron expression, and specific dates use controlled future UTC date and time inputs. Scheduled drafts run only when the connected REST API has its global scheduler enabled. The dashboard's Data Quality page adds a domain consistency report: relationships whose objects share no domain (and objects with no domain) can never ship in the same bundle, so fix them at the source rather than expecting the bundle to pull in related objects. Only the most recent release offers a delete button, a progress bar with a status message appears under the page header while a long operation runs (creating a draft, preparing or committing a release, deleting a release or the track, saving the configuration), and deleting an entire track lives in the danger zone at the bottom of the Config tab.

Each cached snapshot card displays server-generated SHA-256 hashes for the exact UTF-8 JSON files produced by its STIX 2.0 and STIX 2.1 bundle downloads. The adjacent copy buttons copy a hash for external file-integrity verification. Snapshot notes are locked while the bundle is cached; delete the cache, edit the notes, and cache the bundle again to generate matching hashes.

Expand Down
9 changes: 1 addition & 8 deletions src/app/classes/release-tracks/composition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,13 @@
// aggregates content from component tracks
// -----------------------------------------------------------------------------

import { DeduplicationStrategyType, SnapshotTierType } from './enums';
import { DeduplicationStrategyType } from './enums';
import { ComponentTrack, ComponentSnapshotResolution } from './component-track';
import { WorkflowStatusType } from 'src/app/utils/types';

export interface Composition {
component_tracks?: ComponentTrack[];
deduplication?: {
strategy?: DeduplicationStrategyType;
// When resolving conflicts between versions, which snapshot tier should be
// preferred (e.g., prefer from 'staged' over 'candidate' or vice-versa).
tier_resolution?: SnapshotTierType;
// When resolving conflicts, prefer the object with the highest workflow
// status (e.g., 'reviewed' over 'awaiting-review').
status_resolution?: WorkflowStatusType;
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/app/classes/release-tracks/release-track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ export interface ReleaseTrack {
export interface SnapshotSchedule {
mode?: SnapshotScheduleModeType;
cron?: string | null;
dates?: Date[] | undefined;
dates?: (Date | string)[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,17 @@ describe('ReleaseTracksConnectorService', () => {
);
});

it('should replace a virtual track schedule through the virtual namespace', () => {
const schedule = { mode: 'cron' as const, cron: '15 9 * * 1,3' };

service.updateSchedule('release-track--virtual', schedule).subscribe();

expect(http.put).toHaveBeenCalledWith(
`${environment.integrations.rest_api.url}/release-tracks/release-track--virtual/virtual/schedule`,
schedule
);
});

it('should promote an exact quarantined revision', () => {
const body = {
object_ref: 'attack-pattern--one',
Expand Down
18 changes: 18 additions & 0 deletions src/app/services/connectors/rest-api/release-tracks.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
ReleaseTrackSnapshotOptions,
ReviewPayload,
SnapshotHistoryOptions,
SnapshotSchedule,
StixBundlePayload,
StixObjectRef,
UpdateMetadataPayload,
Expand Down Expand Up @@ -561,6 +562,23 @@ export class ReleaseTracksConnectorService extends ApiConnector {
);
}

/** Replace the active registry-backed schedule for a virtual track. */
public updateSchedule(id: string, body: SnapshotSchedule): Observable<any> {
const url = `${this.apiUrl}/release-tracks/${id}/virtual/schedule`;
return this.http
.put<{ snapshot_schedule: SnapshotSchedule }>(url, body)
.pipe(
tap(result =>
logger.log(
`updated virtual snapshot schedule for track ${id}`,
result
)
),
catchError(this.handleError_raise()),
share()
);
}

/**
* POST /api/release-tracks/:id/virtual/quarantine/promote
* Resolve one quarantined object to an exact revision in a new virtual draft.
Expand Down
Loading
Loading