VEX Documents API

Generate, manage, and publish VEX documents through the approval workflow via the API.

VEX (Vulnerability Exploitability eXchange) documents communicate how vulnerabilities affect your product. The API supports the full document lifecycle: generate, review, approve, and publish.

VEX Formats

CVEium CIS supports three VEX formats:

FormatValueStandard
CycloneDX VEXcyclonedx_vexOWASP CycloneDX
OpenVEXopenvexOpenSSF OpenVEX
CSAFcsafOASIS CSAF

Workflow

VEX documents progress through four states:

draft -> submitted -> approved -> published
  • draft: Editable. Can be regenerated or deleted.
  • submitted: Under review. Release chain is locked.
  • approved: Ready for publication.
  • published: Immutable. Creates a public disclosure.

Rejection returns a document from submitted back to draft.

List VEX Documents

GET /api/releases/{releaseId}/vex

Scope: vex:read

Returns all VEX documents for a release.

Generate a VEX Document

POST /api/releases/{releaseId}/vex

Scope: vex:write

Generates a new VEX document from the release's SBOM vulnerabilities and their current dispositions. Created in draft status.

Request body:

FieldTypeRequiredDescription
formatstringYescyclonedx_vex, openvex, or csaf
authorstringNoAuthor name (max 255 chars)

Example:

curl -X POST \
  -H "Authorization: Bearer cvk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"format": "cyclonedx_vex", "author": "CI Pipeline"}' \
  https://cis.cveium.com/api/releases/{release-id}/vex

Returns 201 with the generated VEX document including its full content.

Get a VEX Document

GET /api/vex/{vexId}

Scope: vex:read

Returns the VEX document with its full content.

Delete a Draft VEX Document

DELETE /api/vex/{vexId}

Scope: vex:write

Only draft VEX documents can be deleted. Returns 204 (No Content). Returns 409 if the document is not in draft status.

Regenerate a VEX Document

POST /api/vex/{vexId}/regenerate

Scope: vex:write

Re-generates VEX content from the current dispositions. Only works on draft documents. Increments the version number.

Submit for Approval

POST /api/vex/{vexId}/submit

Scope: vex:write

Transitions from draft to submitted. Locks the release chain — the release, SBOM, and all dispositions cannot be modified while under review.

Request body (optional):

FieldTypeDescription
commentstringSubmission notes (max 5000 chars)

Approve

POST /api/vex/{vexId}/approve

Scope: vex:write

Transitions from submitted to approved.

Request body (optional):

FieldTypeDescription
commentstringApproval notes (max 5000 chars)

Reject

POST /api/vex/{vexId}/reject

Scope: vex:write

Transitions from submitted back to draft. A comment is required explaining the rejection reason. Unlocks the release chain.

Request body:

FieldTypeRequiredDescription
commentstringYesRejection reason (1-5000 chars)

Publish

POST /api/vex/{vexId}/publish

Scope: vex:write

Transitions from approved to published. Creates an immutable snapshot in published_disclosures with a content hash and optional digital signature. The published disclosure is immediately available at /api/disclosures/{slug}.

Request body (optional):

FieldTypeDescription
commentstringPublication notes (max 5000 chars)

Response:

{
  "vexDocument": { "id": "...", "workflow_status": "published", ... },
  "disclosure": { "id": "...", "public_slug": "my-app-2.1.0-vex", ... }
}

Get Approval History

GET /api/vex/{vexId}/approvals

Scope: vex:read

Returns the full history of approval actions (submit, approve, reject, publish) with actor, comment, and timestamp.

{
  "data": [
    {
      "id": "...",
      "action": "submit",
      "actor_id": "...",
      "comment": "Ready for review",
      "created_at": "2026-02-18T10:00:00Z"
    },
    {
      "id": "...",
      "action": "approve",
      "actor_id": "...",
      "comment": "Looks good",
      "created_at": "2026-02-18T11:00:00Z"
    }
  ]
}

CI/CD Example

Full pipeline from SBOM upload to published disclosure:

# 1. Upload SBOM
SBOM_ID=$(curl -sf -X POST ... /api/sboms/upload | jq -r '.data.id')

# 2. Trigger CVE scan
curl -sf -X POST ... /api/cve-scan

# 3. Batch-triage vulnerabilities
curl -sf -X POST ... /api/dispositions/batch

# 4. Generate VEX
VEX_ID=$(curl -sf -X POST ... /api/releases/$RELEASE_ID/vex | jq -r '.data.id')

# 5. Submit -> Approve -> Publish
curl -sf -X POST ... /api/vex/$VEX_ID/submit
curl -sf -X POST ... /api/vex/$VEX_ID/approve
curl -sf -X POST ... /api/vex/$VEX_ID/publish

See the SBOMs & Scanning and Dispositions pages for the full curl syntax for each step.