Campaign
A remediation campaign: a named, time-boxed push to drive a chosen set of vulnerabilities, dependencies or repositories to a defined done state. Fields, YAML, HCL and CLI samples, and how apply treats it.
A remediation campaign: a named, time-boxed push to drive a chosen set of vulnerabilities, dependencies or repositories to a defined done state. The scope chooses the cohort, the done criteria decide when each member of it is closed, and the campaign records which members were admitted, when, and what later scan closed each one. What a campaign has achieved is runtime state, reported in status and never declared: its cohort, progress, freeze time and whether it has completed. The cohort is evaluated after apply, the first time the campaign is opened or refreshed. The repositories the scope and the criteria name must resolve when the document is applied, as they must when the console saves a campaign. Removing the document archives the campaign rather than deleting it, so the record of what was committed to, and whether it happened, is kept; an archived campaign is no longer part of the tenant’s config, and applying the document again starts a new campaign.
apiVersion |
vulnetix.com/v1 |
kind |
Campaign |
| Group | Campaigns |
| Status | Served. The config engine plans and applies it. |
| Objects per tenant | many, keyed by metadata.name |
| Token and role | An owner or admin session, or a vmt_ config management token with the owner or admin role that lists Campaign in its kinds. See Management tokens. |
| Terraform resource | vulnetix_campaign, imported by name (see Terraform and OpenTofu) |
| CLI | vulnetix config apply, CLI v3.168.0 and later. |
| Pinned schema | v1.15.0/Campaign.schema.json |
| Newest schema | latest/Campaign.schema.json |
| First released in | v1.6.0 |
| Print the built-in copy | vulnetix config schema Campaign |
Minimal
Only the fields the kind requires. From examples/Campaign/minimal.yaml.
YAML
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/Campaign.schema.json
apiVersion: vulnetix.com/v1
kind: Campaign
metadata:
name: log4shell
spec:
name: Log4Shell clean-up
target: vulnerabilities
done:
criteria:
- type: gone-from-scans
HCL (resource vulnetix_campaign)
# Only the arguments the kind requires. From config-schemas examples/Campaign/minimal.yaml.
resource "vulnetix_campaign" "log4shell" {
name = "log4shell"
display_name = "Log4Shell clean-up"
done = {
criteria = [
{
type = "gone-from-scans"
},
]
}
target = "vulnerabilities"
}
CLI (applies it)
export VULNETIX_CONFIG_TOKEN=vmt_... # a config management token
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/Campaign.schema.json
apiVersion: vulnetix.com/v1
kind: Campaign
metadata:
name: log4shell
spec:
name: Log4Shell clean-up
target: vulnerabilities
done:
criteria:
- type: gone-from-scans
EOF
Advanced
Every field the kind supports, with a when expression where it takes one. From examples/Campaign/advanced.yaml.
YAML
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/Campaign.schema.json
# Every scope dimension is shown; a real campaign sets the few it needs.
apiVersion: vulnetix.com/v1
kind: Campaign
metadata:
name: kev-burndown-q1
labels:
team: platform-security
annotations:
ticket: https://tracker.example.com/SEC-118
spec:
name: KEV burndown, Q1
description: Close every internet-exposed finding in the CISA KEV catalogue before the audit.
target: vulnerabilities
timing: frozen
deadline: 2027-03-31
ownerEmail: appsec-lead@example.com
scope:
repos:
- acme/payments-api
- acme/web
category: sca
filters:
identity:
findingId: [CVE-2021-44228]
repoName: [acme/payments-api]
branchName: [main]
commitSha: [4f2a9c1]
source: [vulnetix]
category: [sca]
packageName: [log4j-core]
packageVersion: [2.14.1]
packageEcosystem: [maven]
purl: [pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1]
cpe: ["cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*"]
vendor: [apache]
product: [log4j]
weakness:
cwes: [CWE-502]
aliases: [GHSA-jfh8-c2jp-5v3q]
ruleKeys: [java.lang.security.audit.jndi-injection]
cleanCodeCategories: [intentionality]
impact:
minCvss: 7
minCwss: 50
minEpss: 0.1
minEpssPercentile: 0.9
minCess: 5
exploitAsserted:
kev: true
vulncheckKev: true
msrcExploited: true
ransomware: true
exploitObserved:
any: true
sources: [shadowserver]
reachability:
verdicts: [REACHABLE]
assessedOnly: true
exposure:
internetExposed: true
audiences: [public]
supplyChain:
malicious: true
squatted: true
abandoned: true
badActor: true
scorecardBelow: 4
attackChain:
attackPathIds: [ap-ingress-payments]
techniques: [T1190]
tactics: [TA0001]
lifecycle:
eol: true
unmaintained: true
licence:
expressions: [GPL-3.0-only]
violatesPolicy: true
exclusions:
testCode: true
devDeps: true
transitiveDeps: true
suppressed: true
minConfidence: 0.5
done:
join: any
criteria:
- type: gone-from-scans
repos: [acme/payments-api]
category: sca
- type: safe-version
- type: eol-supported
mode: supported
contributors:
- principal: 2b7e1516-28ae-4d2a-a6ab-f7158809cf4f
displayName: Dana Reyes
role: owner
- login: payments-oncall
role: contributor
- email: auditor@example.com
displayName: External auditor
role: contact
HCL (resource vulnetix_campaign)
# Every argument the kind supports. From config-schemas examples/Campaign/advanced.yaml.
resource "vulnetix_campaign" "kev_burndown_q1" {
name = "kev-burndown-q1"
contributors = [
{
display_name = "Dana Reyes"
principal = "2b7e1516-28ae-4d2a-a6ab-f7158809cf4f"
role = "owner"
},
{
login = "payments-oncall"
role = "contributor"
},
{
display_name = "External auditor"
email = "auditor@example.com"
role = "contact"
},
]
deadline = "2027-03-31"
description = "Close every internet-exposed finding in the CISA KEV catalogue before the audit."
display_name = "KEV burndown, Q1"
done = {
criteria = [
{
category = "sca"
repos = ["acme/payments-api"]
type = "gone-from-scans"
},
{
type = "safe-version"
},
{
mode = "supported"
type = "eol-supported"
},
]
join = "any"
}
owner_email = "appsec-lead@example.com"
scope = {
category = "sca"
exclusions = {
dev_deps = true
min_confidence = 0.5
suppressed = true
test_code = true
transitive_deps = true
}
filters = {
attack_chain = {
attack_path_ids = ["ap-ingress-payments"]
tactics = ["TA0001"]
techniques = ["T1190"]
}
exploit_asserted = {
kev = true
msrc_exploited = true
ransomware = true
vulncheck_kev = true
}
exploit_observed = {
any = true
sources = ["shadowserver"]
}
exposure = {
audiences = ["public"]
internet_exposed = true
}
identity = {
branch_name = ["main"]
category = ["sca"]
commit_sha = ["4f2a9c1"]
cpe = ["cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*"]
finding_id = ["CVE-2021-44228"]
package_ecosystem = ["maven"]
package_name = ["log4j-core"]
package_version = ["2.14.1"]
product = ["log4j"]
purl = ["pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1"]
repo_name = ["acme/payments-api"]
source = ["vulnetix"]
vendor = ["apache"]
}
impact = {
min_cess = 5
min_cvss = 7
min_cwss = 50
min_epss = 0.1
min_epss_percentile = 0.9
}
licence = {
expressions = ["GPL-3.0-only"]
violates_policy = true
}
lifecycle = {
eol = true
unmaintained = true
}
reachability = {
assessed_only = true
verdicts = ["REACHABLE"]
}
supply_chain = {
abandoned = true
bad_actor = true
malicious = true
scorecard_below = 4
squatted = true
}
weakness = {
aliases = ["GHSA-jfh8-c2jp-5v3q"]
clean_code_categories = ["intentionality"]
cwes = ["CWE-502"]
rule_keys = ["java.lang.security.audit.jndi-injection"]
}
}
repos = ["acme/payments-api", "acme/web"]
}
target = "vulnerabilities"
timing = "frozen"
labels = {
team = "platform-security"
}
annotations = {
ticket = "https://tracker.example.com/SEC-118"
}
}
CLI (applies it)
export VULNETIX_CONFIG_TOKEN=vmt_... # a config management token
vulnetix config apply -f - --manager gitops:acme/platform --auto-approve <<'EOF'
# yaml-language-server: $schema=https://github.com/Vulnetix/config-schemas/releases/latest/download/Campaign.schema.json
# Every scope dimension is shown; a real campaign sets the few it needs.
apiVersion: vulnetix.com/v1
kind: Campaign
metadata:
name: kev-burndown-q1
labels:
team: platform-security
annotations:
ticket: https://tracker.example.com/SEC-118
spec:
name: KEV burndown, Q1
description: Close every internet-exposed finding in the CISA KEV catalogue before the audit.
target: vulnerabilities
timing: frozen
deadline: 2027-03-31
ownerEmail: appsec-lead@example.com
scope:
repos:
- acme/payments-api
- acme/web
category: sca
filters:
identity:
findingId: [CVE-2021-44228]
repoName: [acme/payments-api]
branchName: [main]
commitSha: [4f2a9c1]
source: [vulnetix]
category: [sca]
packageName: [log4j-core]
packageVersion: [2.14.1]
packageEcosystem: [maven]
purl: [pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1]
cpe: ["cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*"]
vendor: [apache]
product: [log4j]
weakness:
cwes: [CWE-502]
aliases: [GHSA-jfh8-c2jp-5v3q]
ruleKeys: [java.lang.security.audit.jndi-injection]
cleanCodeCategories: [intentionality]
impact:
minCvss: 7
minCwss: 50
minEpss: 0.1
minEpssPercentile: 0.9
minCess: 5
exploitAsserted:
kev: true
vulncheckKev: true
msrcExploited: true
ransomware: true
exploitObserved:
any: true
sources: [shadowserver]
reachability:
verdicts: [REACHABLE]
assessedOnly: true
exposure:
internetExposed: true
audiences: [public]
supplyChain:
malicious: true
squatted: true
abandoned: true
badActor: true
scorecardBelow: 4
attackChain:
attackPathIds: [ap-ingress-payments]
techniques: [T1190]
tactics: [TA0001]
lifecycle:
eol: true
unmaintained: true
licence:
expressions: [GPL-3.0-only]
violatesPolicy: true
exclusions:
testCode: true
devDeps: true
transitiveDeps: true
suppressed: true
minConfidence: 0.5
done:
join: any
criteria:
- type: gone-from-scans
repos: [acme/payments-api]
category: sca
- type: safe-version
- type: eol-supported
mode: supported
contributors:
- principal: 2b7e1516-28ae-4d2a-a6ab-f7158809cf4f
displayName: Dana Reyes
role: owner
- login: payments-oncall
role: contributor
- email: auditor@example.com
displayName: External auditor
role: contact
EOF
Fields
Paths use dots for nesting and [] for the items of a list. Required means required whenever the parent object is present. A default is what the server uses when the field is left out.
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
apiVersion |
string | yes | exactly vulnetix.com/v1 |
The document format version. Every kind in this release is vulnetix.com/v1. | |
kind |
string | yes | exactly Campaign |
Always Campaign. | |
metadata |
object | yes | no other keys | ||
metadata.name |
string | yes | pattern ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ |
The object’s name, unique per kind within a tenant. It is the natural key: plan, apply, export and the Terraform provider all address an object by kind and name. | |
metadata.org |
string | no | format uuid |
The tenant (organization UUID) the document belongs to. When set, plan and apply refuse to run against any other tenant. | |
metadata.labels |
object | no | map of string to string (length 0 to 256); keys match ^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$ |
Free key/value labels. Stored with the object, never interpreted by the server. | |
metadata.annotations |
object | no | map of string to string (length 0 to 4096) | Free key/value notes for people and tools, such as a ticket link. | |
spec |
object | yes | no other keys | ||
spec.name |
string | yes | pattern ^\S(.*\S)?$; length 1 to 256 |
The campaign’s name, as the console shows it. | |
spec.description |
string | no | length 1 to 4096 | What the campaign is for, in a sentence or two. | |
spec.target |
string | yes | vulnerabilities, dependencies, repositories |
What the cohort is made of. vulnerabilities: findings. dependencies: dependencies in use. repositories: both the findings and the dependencies of the repositories in scope. Fixed once the campaign exists: a changed target is refused, because the cohort it already admitted would no longer fit it. | |
spec.timing |
string | no | frozen |
frozen, scopeCreep |
frozen: the cohort is locked the first time the campaign is evaluated, so entities found later never join and the burndown’s denominator cannot move. scopeCreep: every evaluation admits whatever newly matches the scope. A frozen campaign’s scope and criteria cannot be changed; set scopeCreep first, which unfreezes it. |
spec.deadline |
string | no | format date-time, or format date |
When the campaign is due. Recorded as a deadline set by hand. | |
spec.ownerEmail |
string | no | format email; length 0 to 320 |
The email address of the person accountable for the campaign. | |
spec.scope |
object | no | no other keys | The filter that chooses the cohort. Left out, or empty, the campaign covers the whole estate. Every filter set narrows the cohort further. Some dimensions are recorded and not yet evaluated (attackChain, licence.violatesPolicy, supplyChain.scorecardBelow, exploitObserved.sources, weakness.cleanCodeCategories and weakness.ruleKeys); the console reports them as deferred. | |
spec.scope.repos |
array of string | no | items unique; each item: pattern ^[^\s/]+(/[^\s/]+)+$ |
The repositories the campaign covers. For a repositories campaign they are the target itself; for the others they narrow it. Each must resolve to a repository Vulnetix holds or can fetch from its forge. | |
spec.scope.category |
string | no | sca, sast, secrets, iac, license |
One finding category. Left out, every category. | |
spec.scope.filters |
object | no | no other keys | ||
spec.scope.filters.identity |
object | no | no other keys | Match findings by what they are and where they were found. Each list matches any of its values. | |
spec.scope.filters.identity.findingId |
array of string | no | items unique; each item: length 1 to 512 | Finding ids, such as CVE-2021-44228 or GHSA ids. | |
spec.scope.filters.identity.repoName |
array of string | no | items unique; each item: length 1 to 512 | Repository full names. | |
spec.scope.filters.identity.branchName |
array of string | no | items unique; each item: length 1 to 512 | Branch names. | |
spec.scope.filters.identity.commitSha |
array of string | no | items unique; each item: length 1 to 512 | Commit SHAs. | |
spec.scope.filters.identity.source |
array of string | no | items unique; each item: length 1 to 512 | The scanner or tool that reported the finding. | |
spec.scope.filters.identity.category |
array of string | no | items unique; each item: length 1 to 512 | Finding categories, as the findings list shows them. | |
spec.scope.filters.identity.packageName |
array of string | no | items unique; each item: length 1 to 512 | Package names. | |
spec.scope.filters.identity.packageVersion |
array of string | no | items unique; each item: length 1 to 512 | Package versions. | |
spec.scope.filters.identity.packageEcosystem |
array of string | no | items unique; each item: length 1 to 512 | Package ecosystems, such as npm or pypi. | |
spec.scope.filters.identity.purl |
array of string | no | items unique; each item: length 1 to 512 | Package URLs. | |
spec.scope.filters.identity.cpe |
array of string | no | items unique; each item: length 1 to 512 | CPE names. | |
spec.scope.filters.identity.vendor |
array of string | no | items unique; each item: length 1 to 512 | Vendors, as the advisory names them. | |
spec.scope.filters.identity.product |
array of string | no | items unique; each item: length 1 to 512 | Products, as the advisory names them. | |
spec.scope.filters.weakness |
object | no | no other keys | Match findings by weakness. | |
spec.scope.filters.weakness.cwes |
array of string | no | items unique; each item: length 1 to 512 | CWE ids, such as CWE-79. | |
spec.scope.filters.weakness.aliases |
array of string | no | items unique; each item: length 1 to 512 | Advisory aliases. | |
spec.scope.filters.weakness.ruleKeys |
array of string | no | items unique; each item: length 1 to 512 | Static analysis rule keys. Recorded, not yet evaluated. | |
spec.scope.filters.weakness.cleanCodeCategories |
array of string | no | items unique; each item: length 1 to 512 | Clean code categories. Recorded, not yet evaluated. | |
spec.scope.filters.impact |
object | no | no other keys | Minimum scores. A finding must reach every minimum set. | |
spec.scope.filters.impact.minCvss |
number | no | <= 10 | Minimum effective CVSS base score. | |
spec.scope.filters.impact.minCwss |
number | no | Minimum effective CWSS score. | ||
spec.scope.filters.impact.minEpss |
number | no | <= 1 | Minimum EPSS probability, from 0 to 1. | |
spec.scope.filters.impact.minEpssPercentile |
number | no | <= 1 | Minimum EPSS percentile, from 0 to 1. | |
spec.scope.filters.impact.minCess |
number | no | Minimum effective CESS score. | ||
spec.scope.filters.exploitAsserted |
object | no | no other keys | Findings someone with standing says are exploited. Each flag set must hold. | |
spec.scope.filters.exploitAsserted.kev |
boolean | no | In the CISA Known Exploited Vulnerabilities catalogue. | ||
spec.scope.filters.exploitAsserted.vulncheckKev |
boolean | no | In the VulnCheck KEV catalogue. | ||
spec.scope.filters.exploitAsserted.msrcExploited |
boolean | no | Marked exploited by the Microsoft Security Response Center. | ||
spec.scope.filters.exploitAsserted.ransomware |
boolean | no | Known to be used in ransomware campaigns. | ||
spec.scope.filters.exploitObserved |
object | no | no other keys | Findings with exploitation observed in the wild. | |
spec.scope.filters.exploitObserved.any |
boolean | no | Observed by any source. | ||
spec.scope.filters.exploitObserved.sources |
array of string | no | items unique; each item: length 1 to 512 | Observed by one of these sources. Recorded, not yet evaluated. | |
spec.scope.filters.reachability |
object | no | no other keys | Findings by reachability analysis. | |
spec.scope.filters.reachability.verdicts |
array of string | no | items unique; each item: length 1 to 512 | Reachability verdicts, such as REACHABLE or UNREACHABLE. Assessed and unreachable is a different state from never assessed, and either may be targeted. | |
spec.scope.filters.reachability.assessedOnly |
boolean | no | Only findings reachability analysis looked at. | ||
spec.scope.filters.exposure |
object | no | no other keys | Findings by exposure. | |
spec.scope.filters.exposure.internetExposed |
boolean | no | Only findings in services exposed to the internet. | ||
spec.scope.filters.exposure.audiences |
array of string | no | items unique; each item: length 1 to 512 | Exposure audiences, such as public or internal. | |
spec.scope.filters.supplyChain |
object | no | no other keys | Dependencies with supply chain risk. Each flag set must hold. | |
spec.scope.filters.supplyChain.malicious |
boolean | no | Known malicious packages. | ||
spec.scope.filters.supplyChain.squatted |
boolean | no | Typosquatted or namespace-squatted packages. | ||
spec.scope.filters.supplyChain.abandoned |
boolean | no | Abandoned packages. | ||
spec.scope.filters.supplyChain.badActor |
boolean | no | Packages published by a known bad actor. | ||
spec.scope.filters.supplyChain.scorecardBelow |
number | no | 0 to 10 | OpenSSF Scorecard score below this value. Recorded, not yet evaluated. | |
spec.scope.filters.attackChain |
object | no | no other keys | Findings on an attack path. Recorded, not yet evaluated. | |
spec.scope.filters.attackChain.attackPathIds |
array of string | no | items unique; each item: length 1 to 512 | Attack path ids. | |
spec.scope.filters.attackChain.techniques |
array of string | no | items unique; each item: length 1 to 512 | MITRE ATT&CK technique ids, such as T1190. | |
spec.scope.filters.attackChain.tactics |
array of string | no | items unique; each item: length 1 to 512 | MITRE ATT&CK tactic ids, such as TA0001. | |
spec.scope.filters.lifecycle |
object | no | no other keys | Findings by package lifecycle. | |
spec.scope.filters.lifecycle.eol |
boolean | no | Packages past end of life. | ||
spec.scope.filters.lifecycle.unmaintained |
boolean | no | Unmaintained packages. | ||
spec.scope.filters.licence |
object | no | no other keys | Findings by licence. | |
spec.scope.filters.licence.expressions |
array of string | no | items unique; each item: length 1 to 512 | SPDX licence expressions. | |
spec.scope.filters.licence.violatesPolicy |
boolean | no | Licences the licence policy refuses. Recorded, not yet evaluated. | ||
spec.scope.exclusions |
object | no | no other keys | Noise left out of the cohort. | |
spec.scope.exclusions.testCode |
boolean | no | Leave out findings in test code. | ||
spec.scope.exclusions.devDeps |
boolean | no | Leave out development dependencies. | ||
spec.scope.exclusions.transitiveDeps |
boolean | no | Leave out transitive dependencies. | ||
spec.scope.exclusions.suppressed |
boolean | no | Leave out suppressed findings. | ||
spec.scope.exclusions.minConfidence |
number | no | >= 0 | Leave out findings whose scanner confidence is below this value. Findings with no confidence score are kept. | |
spec.done |
object | yes | no other keys | When a member of the cohort is done. | |
spec.done.join |
string | no | all |
all, any |
all: a member is done when every criterion holds. any: when one does. |
spec.done.criteria |
array of object | yes | 1 to any items | The done criteria. For a vulnerabilities campaign: gone-from-scans, safe-version and eol-supported. For a dependencies campaign: package-removed, latest-version and safe-version-used. A repositories campaign takes either family. A finding the scanner marks fixed always closes, whatever the criteria. | |
spec.done.criteria[].type |
string | yes | gone-from-scans, safe-version, eol-supported, package-removed, latest-version, safe-version-used |
gone-from-scans: the finding is no longer reported. safe-version: the package moved to a version the advisory says is fixed. eol-supported: the package is on a supported release line. package-removed: the dependency is no longer used. latest-version: the dependency is on its latest version. safe-version-used: the dependency is on a version with no known vulnerability. | |
spec.done.criteria[].repos |
array of string | no | items unique; each item: pattern ^[^\s/]+(/[^\s/]+)+$ |
gone-from-scans only: the repositories whose scans must no longer report the finding, which may differ from the scope. Each must resolve as the scope’s repositories do. | |
spec.done.criteria[].category |
string | no | sca, sast, secrets, iac, license |
gone-from-scans only: the finding category whose scans count. | |
spec.done.criteria[].mode |
string | no | latest, supported |
eol-supported only. latest: the latest release line. supported: any release line still supported. | |
spec.contributors |
array of object | no | Who is on the hook. Each contributor is identified by exactly one of principal, login or email, because a console member, a code owner and an external contact are different identities. Plan lists each contributor added or removed, and apply changes only those. | ||
spec.contributors[].principal |
string | no | format uuid |
A console member, by their Vulnetix principal UUID. | |
spec.contributors[].login |
string | no | pattern ^[A-Za-z0-9-]+(\[bot\])?$; length 1 to 100 |
A GitHub login, such as a code owner. | |
spec.contributors[].email |
string | no | format email; length 0 to 320 |
An email address, for a contact outside the console. | |
spec.contributors[].displayName |
string | no | length 1 to 256 | The name to show. | |
spec.contributors[].role |
string | no | contributor |
owner, contributor, contact |
owner: accountable for the campaign. contributor: does the work. contact: kept informed. |
Rules
Conditions the schema enforces beyond each field’s own type. vulnetix config validate and the engine’s plan report a document that breaks one.
| On | Rule |
|---|---|
spec.contributors[] |
Exactly one of principal, login or email is set. |
Applying this kind
- Command.
vulnetix config apply -f <file>; the CLI line above says from which release. Plan first withvulnetix config plan: it shows each object as create, update, delete or no change, with aplanHashthat apply then holds to. Apply writes in one transaction. - Manager. Each object records the manager that applied it (
terraform,consoleorgitops:<repo>).--prunedeletes only objects its own manager owns. See The manager and the config engine. - Status.
uuid,statusand what the campaign has achieved. The phases the engine reports are explained under status phases.
How apply treats it
- The console’s create, update and archive writers and its scope and done validator. The plan’s campaign cap applies.
- Contributors are diffed per item.
- Delete archives the campaign. An archived campaign is not listed.
- Only an active campaign can be re-scoped.
- Names live in
ConfigManagedObject.
Terraform and OpenTofu
The resource is vulnetix_campaign in the vulnetix/resolve provider. Its arguments are the spec in snake case, beside name, labels and annotations from metadata. The Minimal and Advanced HCL are above. The provider’s own reference is vulnetix_campaign.
Import an object that already exists by its name:
# Import an existing Campaign by its name (metadata.name).
terraform import vulnetix_campaign.log4shell log4shell
Install, authentication and how state is read: Terraform and OpenTofu.
Check a file with vulnetix config validate -f <file>. See Validate documents. In an editor, start the file with the schema comment.