opentide

Vocabulary format

opentide vocabularies are TOML files (`.vocab.toml`) defining allowed enum values for object and configuration fields. Canonical copies live in `vocabularies/`; opentide bundles them at build time.

Requirements

  • Every vocabulary file MUST validate against schemas/vocabulary.schema.json.
  • Every vocabulary file MUST declare name and field at the top level.
  • Vocabulary files MUST NOT declare a top-level version property; versioning is per [[keys]] entry (see RFC 0003).
  • Entry keys MUST be declared in [[keys]] tables unless using stages for scoped vocabularies.
  • Clients MUST NOT override vocabulary files in .opentide/configurations/; extensions use schema.toml [[vocabulary.*]] entries only.
  • The field value MUST match the YAML/JSON field path the vocabulary constrains (e.g. tlp, att&ck, detection.methodology).
  • Sync direction MUST be specifications → opentide (canonical data originates here).

Definition

Top-level properties

PropertyTypeRequiredDescription
namestringyesHuman-readable vocabulary name
fieldstringyesField path this vocabulary applies to
descriptionstringnoVocabulary description
iconstringnoDisplay icon for UI/schema generation
key"name" | "id"noWhether entries are keyed by name or id (default: name-based)
modelbooleannoWhen true, vocabulary models a nested object type
keysarray of KeyEntrynoEnum entries
stagesarraynoScoped stage identifiers for multi-stage vocabularies
sourcestringnoUpstream a generated vocabulary is ingested from (e.g. mitre-attack)
source_versionstringnoUpstream release the keys were last refreshed from (e.g. ATT&CK 20.0)
source_fetched_atstringnoUTC timestamp (ISO 8601) of the upstream fetch

source, source_version and source_fetched_at are provenance only. They are not a contract revision and MUST NOT be read as one; contracts come from per-key version and removed.

Top-level version is not permitted. Vocabulary contract revisions (field::major.minor) are derived from per-key lifecycle metadata, not file stamps.

[[keys]] entry

PropertyTypeRequiredDescription
idstringnoStable identifier (e.g. TLP:AMBER)
namestringyes*Display/slug value used in YAML
versionstringyesContract line when this key enters the vocabulary (major.minor, e.g. 1.0)
removedstringnoContract line when this key leaves (major.minor); excludes key from contracts at or above this revision
descriptionstringnoEntry description (markdown in schema)
iconstringnoEntry icon
mispstringnoMISP taxonomy mapping
tide.vocab.stagesstring | listnoStage scope for this entry

* Required when key = "name" (default).

Per-key bump rules

Change typeKey metadataContract effect
Add new keyset version to introducing minor linenew minor contract available (e.g. killchain::1.1)
Remove keyset removed at next majormajor contract line
Rename keyremoved on old key + new key at majormajor
Description/icon-only editno changenone

Contract resolution

A vocabulary contract field::M.m resolves to all keys where:

  • version <= M.m (cumulative minor semantics), and
  • removed is absent or removed > M.m.

Object schema revisions pin explicit contracts via schemas/pins/ manifests (see RFC 0003).

Staged vocabularies

Entries MAY be scoped to lifecycle stages via tide.vocab.stages. Metaschema fields use tide.vocab.scoped and tide.vocab.stages keywords to filter allowed values at generation and validation time.

  • A field bound to a staged vocabulary MUST declare tide.vocab.scoped, and its authored values MUST be <stage>::<key>. The prefix is what tells two stages' identically-named keys apart, and omitting it makes those values unreachable (see RFC 0005).
  • Stage identifiers naming a human-facing category SHOULD be capitalised (Host, Protocol). A stage naming an external framework keeps that framework's own spelling (misp, att&ck).
  • Key names MAY themselves contain :: as hierarchy within the key (AWS::Compute::EC2), and a key's first token MAY coincide with a stage identifier (Security::Kerberos is a Protocol key). A consumer resolving an authored value MUST therefore try the whole value as a key name before reading its leading token as a stage identifier.
  • Scoping a field changes no key's lifecycle, so it MUST NOT trigger a vocabulary contract revision under RFC 0003.

Example file

name = "Traffic Light Protocol"
field = "tlp"
description = "TLP classification for information sharing."
key = "name"

[[keys]]
id = "TLP:CLEAR"
name = "clear"
version = "1.0"
description = "Recipients can spread this to the world."

Relationships

Defaults & overrides

MechanismAllowed?
Edit vocabularies/*.vocab.toml here (via RFC)Yes
Client copy of .vocab.toml in configurationsNo
schema.toml [[vocabulary.*]] extensionYes

opentide sync interface

LocationRole
specifications/vocabularies/Canonical source (this repo)
opentide/src/opentide/data/vocabulary/Runtime bundle (copied at build)
schemas/vocabulary.schema.jsonValidation schema for TOML files

The sync script is an opentide build concern; this spec defines the data contract only.

Examples

History

VersionDateNotes
1.12026-10-19removed excludes a key from contracts at or above its revision; the description said "at or below" while Contract resolution already required removed > M.m. Document the source, source_version and source_fetched_at provenance keys.
1.12026-06-26Per-key version/removed; no top-level file version (RFC 0003)
1.02026-06-25Initial spec from opentide vocabulary.schema.json

On this page