How to Initialize a Case
Use this guide to open a VulnerabilityCase after validating a report.
Initialization seats the case, attaches at least one report, seats at least one participant, and attaches any opening notes.
You finish with a case whose roster and report are in place and whose ledger has its genesis entry.
Prerequisites
- A running Vultron instance you can drive. The demo containers are the quickest route — see Tutorial: Run the Receive-Report Demo for the two steps that get you a container shell.
- An actor identity on that instance, holding the role each step names.
- Working knowledge of the ActivityStreams verb, object, and target shape, summarized in Vultron and ActivityPub.
-
Working knowledge of the case model: the objects a case is made of, in The Case Model, and who is allowed to change them, in The CASE_MANAGER and the Case Ledger. Where a guide's messages are case-scoped, they route through the CASE_MANAGER and their results appear on the case ledger.
-
A report at Report Management (RM) state
RM.VALID. See How to Report a Vulnerability. - The actor Uniform Resource Identifiers (URIs) of any participants you already know about, such as the Reporter.
The exchange
The flowchart below shows the activities case initialization can use.
The two as:Add activities branch from Create(VulnerabilityCase) because each attaches a different kind of object to the new case.
A participant is not attached: it is invited, and it joins when it accepts.
---
title: Case Creation and the Objects Attached to It
---
flowchart LR
subgraph as:Create
CreateCase["Create Case<br/>Create(VulnerabilityCase)"]
end
subgraph as:Add
AddReportToCase["Add Report to Case<br/>Add(VulnerabilityReport)"]
AddNoteToCase["Post a note to the case<br/>Add(Note)"]
end
subgraph as:Invite
RmInviteToCase["Invite Actor to Case<br/>Invite(Actor)"]
end
subgraph as:Accept
RmAcceptInviteToCase["Accept Invite to Case<br/>Accept(Invite(Actor))"]
end
CreateCase --> AddReportToCase
CreateCase --> RmInviteToCase
RmInviteToCase --> RmAcceptInviteToCase
CreateCase --> AddNoteToCase
Seat the case
-
Send
Create(VulnerabilityCase), carrying the newVulnerabilityCaseas itsobject. Set yourself as Case Owner.Create case
Mints the vulnerability case, seats its initial participants and links the report.
- When… the Case Manager has opened a case for a submitted report
- Send:
Create(VulnerabilityCase) - Send to: a participant
- Sent by: the addressee of the case proposal or vulnerability report offer
- Reference: Create case
Example activity
{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Create", "id": "urn:uuid:abc2d325-41a6-485d-90d7-d3e9c5a7d54e", "name": "https://vultron.example/organizations/vendorco Create VendorCo Case #31763808", "context": "https://demo.vultron.local/VulnerabilityReport/e28f4965-7838-4644-b4a8-10604c7ee92f", "content": "We've created a case from this report.", "actor": "https://vultron.example/organizations/vendorco", "object": { "id": "https://demo.vultron.local/VulnerabilityCase/615c9287-a98d-458f-86e0-7db242389a95", "type": "VulnerabilityCase", "name": "VendorCo Case #31763808", "published": "2026-10-23T20:17:07+00:00", "updated": "2026-10-23T20:17:07+00:00", "attributedTo": "https://vultron.example/organizations/vendorco", "caseParticipants": [ { "id": "urn:uuid:89326be2-5ebf-4da5-baf3-992017977d34", "type": "CaseParticipant", "name": "VendorCo", "published": "2026-10-23T20:17:07+00:00", "updated": "2026-10-23T20:17:07+00:00", "attributedTo": "https://vultron.example/organizations/vendorco", "caseRoles": [ "vendor" ], "participantStatuses": [ { "id": "urn:uuid:42d2b2b8-1934-4645-b526-b3ed736f57fd", "type": "ParticipantStatus", "name": "START vf", "context": "urn:uuid:89326be2-5ebf-4da5-baf3-992017977d34", "published": "2026-10-23T20:17:07+00:00", "updated": "2026-10-23T20:17:07+00:00", "attributedTo": "https://vultron.example/organizations/vendorco", "rmState": "START", "vfState": "vf", "caseEngagement": true, "cvdRole": [ "VENDOR" ], "@context": "https://certcc.github.io/Vultron/ns/context.jsonld" } ], "embargoConsents": [], "joined": true, "@context": "https://certcc.github.io/Vultron/ns/context.jsonld" } ], "actorParticipantIndex": {}, "vulnerabilityReports": [ { "id": "https://demo.vultron.local/VulnerabilityReport/e28f4965-7838-4644-b4a8-10604c7ee92f", "type": "VulnerabilityReport", "name": "FDR-8675309", "published": "2026-10-23T20:17:06+00:00", "updated": "2026-10-23T20:17:06+00:00", "content": "I found a vulnerability!", "attributedTo": "https://vultron.example/users/finndervul", "@context": "https://certcc.github.io/Vultron/ns/context.jsonld" } ], "caseStatuses": [ { "id": "urn:uuid:c1f29255-03d7-488b-aa0c-ba942f2c0905", "type": "CaseStatus", "name": "NONE pxa", "context": "https://demo.vultron.local/VulnerabilityCase/615c9287-a98d-458f-86e0-7db242389a95", "published": "2026-10-23T20:17:07+00:00", "updated": "2026-10-23T20:17:07+00:00", "attributedTo": "https://vultron.example/organizations/vendorco", "emState": "NONE", "pxaState": "pxa", "@context": "https://certcc.github.io/Vultron/ns/context.jsonld" } ], "notes": [], "embargoRegister": [], "pendingEmbargoProposalIndex": {}, "caseActivity": [], "genesisHash": "8282781b3e7e5b77efecb468453488039a5b459704c7993297da921025006689", "ledgerPosition": { "logIndex": -1, "entryHash": "8282781b3e7e5b77efecb468453488039a5b459704c7993297da921025006689" }, "parentCases": [], "childCases": [], "siblingCases": [], "activeParticipants": [ "urn:uuid:89326be2-5ebf-4da5-baf3-992017977d34" ], "@context": "https://certcc.github.io/Vultron/ns/context.jsonld" } } -
Attach the report with
Add(VulnerabilityReport), targeting the case. Only the Case Owner may send it, and the receiving actor must be the case's CASE_MANAGER, so mint the case through the create-case trigger (which seats the creator as Case Owner and CASE_MANAGER) rather than as a bareCreate(VulnerabilityCase).Add report to case
Adds a vulnerability report to the case named by the target.
- When… the Case Owner links a further report to an existing case
- Send:
Add(VulnerabilityReport)[target=VulnerabilityCase] - Send to: the case manager
- Sent by: the case owner
- Reference: Add report to case
Example activity
{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Add", "id": "urn:uuid:1af8e484-b1ec-4204-8928-05811c2ae8d5", "name": "https://vultron.example/organizations/vendorco Add FDR-8675309 to urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "content": "We're adding this report to this case.", "actor": "https://vultron.example/organizations/vendorco", "target": "urn:uuid:d483d06d-400e-47fd-9b8a-9a2643e3a4b0", "object": { "id": "https://demo.vultron.local/VulnerabilityReport/e28f4965-7838-4644-b4a8-10604c7ee92f", "type": "VulnerabilityReport", "name": "FDR-8675309", "published": "2026-10-23T20:17:06+00:00", "updated": "2026-10-23T20:17:06+00:00", "content": "I found a vulnerability!", "attributedTo": "https://vultron.example/users/finndervul", "@context": "https://certcc.github.io/Vultron/ns/context.jsonld" } } -
Seat each participant you already know by asking the CASE_MANAGER to invite it, naming its roles; it joins when it accepts. See How to Seat a Participant on an Existing Case.
Add(CaseParticipant)does not seat a member: it reinstates one the Case Owner removed. - If the case needs opening context, post it as a note with one
Add(Note)that targets the case and carries the note inline. Set the note'scontextto the case as well. See How to Post a Status Update or a Case Note.
If every report, participant, and note is known when you create the case, carry them inline on the Create(VulnerabilityCase) activity and skip steps 2 through 4.
Participants carried inline are seated by case initialization itself.
The steps are separated here because they are easier to follow one at a time, not because a conformant implementation must emit them individually.
If a participant becomes known later, invite it the same way — see How to Invite an Actor to a Case.
A second report needs its own Add
A case can accumulate reports.
When a second report arrives for a case that already has one, attach it with Add(VulnerabilityReport) rather than creating a new case.
Verify
| What you sent | What to confirm |
|---|---|
Create(VulnerabilityCase) |
The case exists and names you as Case Owner. |
Add(VulnerabilityReport) |
The case lists the report. |
Accept(Invite(Actor)) |
The case roster holds the participant with its roles. |
Add(Note) |
The note appears on the case. |
Every one of these is committed to the case ledger by the CASE_MANAGER and fanned out to each participant, so each participant's replica should show the same roster.
See it end to end
Try it: vultron-demo initialize-case
vultron-demo initialize-case
Or with Docker Compose:
DEMO=initialize-case docker compose -f docker/docker-compose.yml run --rm demo
Further reading
- Case Management Messages — the wire format and a rendered example for each activity above
- Activity Vocabulary Design — why creation and attachment are separate verbs, and when inlining an object is worth having
- The CASE_MANAGER and the Case Ledger — who commits the activities above and how they reach every participant's replica
- Case Ledger Synchronization — the replication protocol in detail