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
12 changes: 12 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
"browser": "src/main.ts"
},
"configurations": {
"snapshot-preview": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.snapshot-preview.ts"
}
]
},
"production": {
"fileReplacements": [
{
Expand Down Expand Up @@ -98,6 +106,10 @@
"buildTarget": "app:build"
},
"configurations": {
"snapshot-preview": {
"buildTarget": "app:build:snapshot-preview",
"proxyConfig": "scripts/snapshot-preview.proxy.json"
},
"production": {
"buildTarget": "app:build:production"
}
Expand Down
70 changes: 70 additions & 0 deletions docs/local-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,76 @@ npm run build-prod
If variables are omitted, the generated asset uses the package version and
reports its commit and build date as `unknown`.

### Virtual snapshot design preview

Run `npm run preview:snapshots`, then open
<http://localhost:4300/dashboard/release-management/release-track--snapshot-preview>.
This opt-in configuration runs Angular on port 4300 and an in-memory fixture API
on loopback port 4311. It never proxies to the production or local REST API.
Normal `npm start` and build configurations are unchanged.

The preview includes a current quarantined draft, a tagged snapshot using another
deduplication strategy, and a tagged snapshot with quarantine enabled but no
conflicts. Open each card to compare contents and button visibility. The current
draft contains eleven distinct manifest objects: five members, three relationships,
two supporting objects, and one non-exported LinkById render dependency.
The source filter demonstrates seven Enterprise ATT&CK objects, three Research
extensions objects, and two objects whose source was not recorded. PowerShell
is one shared revision attributed to both component tracks, not a duplicate row.
Quarantine comparison serves two distinct exact STIX revisions, including changed
descriptions, platforms, and ATT&CK versions. Both can be inspected as raw JSON
or opened in the existing read-only detail dialog; **View in Object Library**
opens the ordinary object page without closing the comparison.
Quarantine selection simulates creating a new draft; earlier snapshots are preserved.
Restart the preview to reset its in-memory data. Other write operations are not
simulated and return an explicit preview-only error.

The identity and marking-definition fixtures return plain arrays unless the
request explicitly sets `includePagination=true`, which returns `{ data,
pagination }`. Detail dialogs load marking definitions without pagination; the
fixture includes the referenced statement marking so the dialog shows one
statement. Collection-index listings also return a plain array. When smoke-testing
View details, check console error logs and notifications as well as uncaught
exceptions: connector errors are caught and can leave the object visible.

All eleven manifest rows provide working **Preview** and **View in Object
Library** actions. The fixture serves typed current/exact object endpoints,
enriched relationship endpoints and their filtered lookups, identity field
options, and tactic technique listings. Supporting-object previews reuse the
identity and marking-definition views. `/relationship/:id` is a read-only detail
route, with no relationship creation or editing entry point.

Snapshot-history fixtures follow the current `next` contract: `tagged`, `limit`,
and `offset` select the returned page; `counts` describes the filtered history;
`latest_snapshot_modified` and `latest_tagged_snapshot_modified` identify the
unfiltered live snapshots. The draft-cleanup endpoint returns an empty operation
list so Releases can exercise its automatic refresh without simulated cleanup.

The complete-manifest mockup uses a **proposed**, not yet implemented production
response field on exact Workbench snapshot exports:

```typescript
content_manifest_entries: Array<{
kind: 'primary' | 'secondary' | 'relationship' | 'supporting' | 'link_target';
object_ref: string;
object_modified?: string;
stix?: object;
source_tracks?: Array<{ track_id: string; track_name?: string }>;
}>;
```

Entries are combined by exact object ID and revision, retaining all roles and
recorded source tracks. Track IDs identify sources; names are display labels.
Absent origin metadata remains **Source not recorded** and is never reconstructed
from current component contents.
Non-exported dependencies remain visible; entries without payloads show their
exact reference rather than fetching a latest revision. The generated collection
projection is excluded. Production API responses currently omit this field;
the UI then shows the snapshot's exported graph and explicitly discloses that
non-exported render dependencies cannot be listed. A real complete-manifest read
contract is required before this design can provide full manifest browsing
against production data.


## Note: Recommended setup using Visual Studio Code Workspaces

Expand Down
111 changes: 110 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,57 @@ snapshot. Standard tracks retain their most recent rolling draft plus preserved
release sources and drafts referenced by virtual provenance, so these labels
describe surviving snapshots rather than every past action.

Virtual release tracks open on **Releases**, not a Board. **Open Snapshot** on
each card enters a read-only, URL-addressable contents view for that exact
snapshot. Search by name, STIX ID, ATT&CK ID, or revision, combine **STIX type**
and **Source track** filters, and inspect the selected revision's JSON. Each row
shows its recorded component origins. A deduplicated revision contributed by
multiple tracks appears once and matches any of its sources. **Source not
recorded** identifies objects without captured origin metadata; current component
membership is never substituted for snapshot provenance. Relationships and supporting objects
are included; the generated collection projection is not a manifest member.
**Back to Releases** returns to the snapshot cards. Standard tracks retain
their Board workflow.

The Releases history filter and pagination remain available for virtual tracks.
Automatic history and cleanup refresh runs while Releases is visible, and pauses
in Config, inside a snapshot, or while a dialog or edit is active. Virtual track
descriptions can be edited from the Releases introduction.

Every contents row offers **Preview**, **View in Object Library**, and JSON
inspection when its payload is available. Preview opens the pinned snapshot
revision read-only, including relationships, identities, and marking definitions.
Closing it preserves the table's filters and position. If a manifest contains only
an exact reference, Preview retrieves that revision and reports failures inline
instead of substituting the latest object. Relationship previews use endpoint
revisions from the same snapshot.

**View in Object Library** opens the object's library page in a new tab; that
page can show newer workspace content than the snapshot. Relationship library
pages are read-only. Object previews fit their content width and remain within
the viewport rather than inheriting the wider quarantine modal's dimensions.

**View Quarantined Objects** appears inside a snapshot only when that snapshot's
deduplication strategy is `quarantine` and its quarantine contains entries.
The modal groups competing revisions by object and shows their component sources
side by side on wider screens, stacked on narrow screens. Each revision's
**View JSON** can remain open independently; **Compare JSON** opens all revisions
in that group for comparison. JSON comes from the exact revision endpoint and
retains the original STIX fields. **View details** opens that revision read-only
without losing the comparison or selection. **View in Object Library**
opens the ordinary object page in a new tab and is explicitly distinct from the
historical revision views. Retrieval failures or mismatched revisions are shown
inline with Retry; they never substitute the latest revision.
An editor can select an exact revision in the latest untagged snapshot; resolving
it creates a new draft rather than changing the viewed snapshot. Historical
and tagged snapshots are review-only.

The [isolated design preview](local-dev.md#virtual-snapshot-design-preview)
demonstrates the complete manifest, including non-exported LinkById dependencies.
The current production API does not expose those dependency records. Against
that API, the contents view explicitly labels its exported-only coverage instead
of claiming to list the complete manifest.

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
Expand Down Expand Up @@ -154,7 +205,7 @@ while you are viewing it, the automatic history refresh lets you select a surviv

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. For virtual tracks, each snapshot card shows its own Composition Resolution provenance: the exact component track snapshot, tagged version, snapshot creation timestamp, resolution strategy and filters, and source/filter/contribution counts used for that materialization. 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. A standard release preserves its exact pre-release draft, which remains hidden while the release exists. Administrators can convert the most recent tagged release back to a draft from the Releases tab by confirming its version. Standard tracks restore the preserved pre-release draft; virtual tracks retain the same snapshot and composition provenance while removing its tag and publication metadata. Conversion is blocked when any downstream virtual snapshot resolved that release. Tagged releases cannot be deleted directly. Editors can separately delete the current draft, provided it is not the track's only snapshot, a preserved source of a tagged release, or a resolved component of a downstream virtual snapshot. Administrators can also correct a tagged snapshot's version from its card when the replacement remains valid between adjacent releases. 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 tagged release offers Convert to draft, and only the current draft offers Delete draft, a progress bar with a status message appears under the page header while a long operation runs, 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: standard tracks use the Board to manage candidates and staged objects; virtual tracks use Releases to browse atomic snapshots, with Create Draft in the page header. The Releases tab previews and tags a draft from its card. For virtual tracks, each snapshot card has a collapsible Component provenance section: the exact component track snapshot, tagged version, snapshot creation timestamp, resolution strategy and filters, and source/filter/contribution counts used for that materialization. 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. A standard release preserves its exact pre-release draft, which remains hidden while the release exists. Administrators can convert the most recent tagged release back to a draft from the Releases tab by confirming its version. Standard tracks restore the preserved pre-release draft; virtual tracks retain the same snapshot and composition provenance while removing its tag and publication metadata. Conversion is blocked when any downstream virtual snapshot resolved that release. Tagged releases cannot be deleted directly. Editors can separately delete the current draft, provided it is not the track's only snapshot, a preserved source of a tagged release, or a resolved component of a downstream virtual snapshot. Administrators can also correct a tagged snapshot's version from its card when the replacement remains valid between adjacent releases. 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 tagged release offers Convert to draft, and only the current draft offers Delete draft, a progress bar with a status message appears under the page header while a long operation runs, and deleting an entire track lives in the danger zone at the bottom of the Config tab.

On a virtual track's **Board**, **Composition Resolution** starts collapsed to
leave more room for Members and Quarantine. Click its heading, or focus it and
Expand Down Expand Up @@ -269,6 +320,64 @@ The Workbench will attribute edits to you when you edit existing objects or crea

Edits you make in the knowledge base are attributed to your _organization identity_, which is unique to your Workbench instance. The organization identity can be edited from the admin page accessible from the application homepage; when you first open the application you will be prompted to edit the organization identity to ensure the placeholder identity is not used. Changes to your organization identity will automatically update objects in the knowledge base, but attribution within exported collections will not be automatically affected.

### Managing Allowed Values

Administrators can open **Dashboard → Admin → Allowed Values**, immediately
below **Validation Bypasses** in the sidebar. The searchable, sortable table
contains **one row per property and domain**, not one row per value or object
type. It starts with 15 configured rules, fitting on the default 25-row page.
Each row shows supported object types, a value count, and a compact preview.
The page identifies the backend ADM version supplying the permitted choices.

**Add New Property** opens a guided workflow:

1. Choose a supported property.
2. Choose an ADM-valid domain and one object type.
3. Select permitted values from a searchable checklist.
4. Review the configuration and choose **Create property**.

If that property/domain is already configured, choose **Open existing editor**
instead of creating a duplicate. New scopes are available only where the
installed backend ADM accepts the property for that domain and object type;
this does not create arbitrary STIX schema fields.

**Edit values** uses the same checklist, with one object-type selector above it
instead of repeated applicability controls for every value:

- Check an approved value to enable it; uncheck it to keep it disabled.
- **Remove** clears that value's configuration for the selected object type.
- Switch object type to edit another scope. Other types' settings are retained.
- **Save all values** applies the draft atomically; **Cancel** discards it.

Enum fields have no freeform value input. For the data-source/component field,
enter the two names separately and choose **Validate and add**. ADM must accept
the combined value before it enters the draft. Unvalidated input blocks saving
until it is approved or cleared.

Saving an empty set leaves the configured rule available for later editing.

Supported properties remain the original configurable fields: platforms for
analytics, techniques, software, data sources and assets; technique tactic/impact
types, permissions and data-source/component names; collection layers; asset
sectors and related-asset sectors; and identity classes and sectors. Available
domains and permissible values are derived from the backend ADM Zod schemas.

Changes persist across restarts. Open or reopen an editor to load the latest
enabled choices. An existing unavailable selection remains visible but is not a
newly selectable option. Remove list/subtype selections using their chip's
remove control; once removed, they cannot be reselected unless an administrator
re-enables or adds the value.

Allowed Values configuration is always ADM-validated, including disabled
options. General validation settings and **ADM Validation Bypasses** cannot
permit non-compliant configuration values. The frontend uses the backend's
catalog, so a different frontend ADM package version cannot broaden choices.

Legacy configuration values that no longer comply with ADM are marked
**unavailable** and excluded from dropdowns. They remain stored until the rule
is saved; the editor explains that saving removes those unavailable settings.
Existing ATT&CK objects are never rewritten by this configuration workflow.

### Quality Control Workflows

The ATT&CK Workbench provides optional quality control workflows to assist in the creation of ATT&CK data. Objects are marked with a "workflow status," reflecting their place in the quality control pipeline:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"preview:snapshots": "node scripts/snapshot-preview.mjs",
"build": "ng build",
"postbuild": "npm run generate:build-info",
"build-prod": "ng build --configuration production",
Expand Down
Loading
Loading