Vultron and ActivityPub
This page is not normative
This page is not considered a core part of the Vultron Protocol as proposed in the main documentation. Although within the page we might provide guidance in terms of SHOULD, MUST, etc., the content here is not normative.
Vultron messages are ActivityStreams 2.0 (AS2) activities, delivered between actors over ActivityPub. AS2 is the wire vocabulary, not an analogy for it: every protocol message a Vultron actor sends is an AS2 activity, and every object it carries is either an AS2 object or a Vultron extension of one. This page gives you the shape of those activities so that the activity guides can name each one by its verb and object without re-explaining the fields.
Two other pages carry what this one leaves out. Message Types lists every activity the protocol uses, with its formal message name, its discriminating fields, and a rendered example. Activity Vocabulary Design explains why each verb was chosen.
The grammar of an activity
The AS2 vocabulary describes an activity as a sentence: an actor performs a verb on an object, optionally from an origin, to a target, in a context.
---
title: The Parts of an ActivityStreams Activity
---
flowchart LR
Actor -->|performs| Activity
Activity -->|on| Object
Activity -->|from| Origin
Activity -->|to| Target
Activity -->|using| Instrument
Activity -->|with| Result
Activity -->|in| Context
The diagram shows the seven relationships an AS2 activity can express.
Vultron uses four of them on nearly every message: actor, the verb (type), object, and either target or context to name the case.
The activity guides write an activity as Verb(Object), with a nested form when the object is itself an activity.
Offer(VulnerabilityReport) is an as:Offer whose object is a VulnerabilityReport; Accept(Offer(VulnerabilityReport)) is an as:Accept whose object is that Offer.
What a Vultron activity looks like
The message below is Report Submission (RS), implemented in ActivityStreams as Offer(VulnerabilityReport).
It was produced by the reference implementation; the identifiers and timestamps are placeholders.
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Offer",
"id": "urn:uuid:70f657e8-8640-414f-9b1a-2512f9664e3a",
"published": "2026-09-28T17:38:03+00:00",
"to": ["https://vendor.example/actors/psirt"],
"actor": "https://reporter.example/actors/finder",
"object": {
"@context": "https://certcc.github.io/Vultron/ns/context.jsonld",
"type": "VulnerabilityReport",
"id": "https://reporter.example/reports/CVE-2026-0001",
"name": "Buffer overflow in example-server",
"content": "Details of the finding.",
"attributedTo": "https://reporter.example/actors/finder"
}
}
Read it field by field.
| Field | What it carries | Where the guides rely on it |
|---|---|---|
type |
The AS2 verb | Every guide names its activities by verb and object |
actor |
The actor performing the activity | Case-management handshakes are sent by the CASE_MANAGER, with the requesting participant in attributedTo |
object |
The thing acted on: a Vultron object, or an earlier activity being answered | Accept, Reject, TentativeReject, and Read carry the activity they answer, not the object inside it |
target |
Where the object goes | Add names the case here, as do Remove(Note) and Remove(CaseParticipant); Offer(CaseParticipantRole) names the actor being offered the role |
origin |
Where the object comes from | Remove(Event), which terminates an embargo, names the case here rather than in target |
context |
The case an activity belongs to | Invite(Event) names the case here, and so does the Note an Add(Note) carries |
inReplyTo |
The earlier activity this one answers, when the verb alone does not say so | Add(Event) with inReplyTo activates an agreed embargo; without it, it imposes one |
to |
The recipient inboxes | A report is offered to each recipient separately; case traffic goes to the CASE_MANAGER |
Whether the case sits in target or context is not a matter of style.
A receiver tells activities apart by these fields, so an Add(CaseStatus) that names its case in context instead of target is not recognized as a status update.
Each guide states which field its activities use, and Message Types records the discriminator for every activity.
The Vultron vocabulary
The verbs are all standard AS2: Offer, Accept, Reject, TentativeReject, Read, Create, Add, Remove, Invite, Join, Ignore, Leave, Announce, and Update.
Vultron adds no verbs.
The objects are where Vultron extends AS2.
VulnerabilityReport, VulnerabilityCase, CaseParticipant, CaseParticipantRole, CaseStatus, ParticipantStatus, EmbargoEvent, CaseLedgerEntry, and ProcessingFault are Vultron types, declared in the Vultron JSON-LD context that each object cites in its own @context.
Standard AS2 objects appear too: an embargo proposal is an as:Event, a case note is an as:Note, and the actor invited to a case is an as:Actor.
The same verb carries different protocol messages depending on its object.
Accept(Offer(VulnerabilityReport)) is Report Valid (RV); Accept(Invite(Event)) is Embargo Proposal Acceptance (EA); Accept(Invite(Actor)) is an actor joining a case.
Read the object before the verb.
- Objects — each Vultron object type and its fields
- Activity guides — how to carry out each protocol task, activity by activity
- Message Types — the full mapping from formal message names to wire activities
Reading path: You maintain a vulnerability tracker and want it to talk to your partners
This page is part of Send your first message.
Before this page:
After this page: