ab63ead00e
A command can now declare what it is FOR, and Riposte's agent browses the estate by it: enrich, hunt, inspect, transform, collect, contain, remediate, identity, notify, ticket, manage. It is a second axis to the manifest-level `category`, which says what the product is. All 101 of HarfangLab's commands are "endpoint"; the analyst looking for a decoder and the one looking for an isolation are not looking in the same place, and the product axis cannot separate them. Optional, and the template says why it is worth writing anyway: a command that declares nothing is classified by Riposte from its id and description, which is a guess. A value outside the list is ignored and the command classified instead, so a typo costs the declaration rather than inventing a twelfth category that nothing else ever lands in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8cMrB8KPHVpL47rmKynDQ
127 lines
6.2 KiB
YAML
127 lines
6.2 KiB
YAML
# =============================================================================
|
|
# Integration manifest template — copy to integrations/<id>/manifest.yaml
|
|
# This file is named *.example.yaml on purpose so Riposte never ingests it
|
|
# (only files named exactly "manifest.yaml" are picked up).
|
|
# =============================================================================
|
|
|
|
id: example_integration # required · unique slug · [a-z0-9_]
|
|
name: Example Integration # required · shown in the UI
|
|
version: 1.0.0 # semver · bump on every change
|
|
description: One-line description of what this integration does.
|
|
# changelog: shown to operators when an update is available, so they can assess
|
|
# risk before updating. Describe notable/breaking changes for THIS version.
|
|
changelog: "1.0.0 — Initial release."
|
|
category: enrichment # free text: enrichment | containment | ticketing | ...
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# config_schema — per-instance settings the operator fills in when creating an
|
|
# instance. JSON-Schema shape: { properties: {...}, required: [...] }.
|
|
# Property fields: type (string|number|boolean), description, default,
|
|
# and x-soar-sensitive: true for secrets (encrypted in the vault, never returned).
|
|
# ---------------------------------------------------------------------------
|
|
config_schema:
|
|
properties:
|
|
base_url:
|
|
type: string
|
|
description: API base URL
|
|
default: https://api.example.com/v1
|
|
api_key:
|
|
type: string
|
|
description: API key / token
|
|
x-soar-sensitive: true
|
|
required:
|
|
- api_key
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# auth — authentication methods, referenced from commands via auth_ref.
|
|
# value_template: {{secret}} is replaced by the value of secret_field.
|
|
# api_key in header → name is the header (e.g. x-apikey, Authorization)
|
|
# bearer → typically name: Authorization, value_template: "Bearer {{secret}}"
|
|
# ---------------------------------------------------------------------------
|
|
auth:
|
|
- id: apikey
|
|
type: api_key # api_key | bearer | basic | oauth2_client_credentials
|
|
in: header # header | query
|
|
name: Authorization
|
|
value_template: "Bearer {{secret}}"
|
|
secret_field: api_key
|
|
|
|
commands:
|
|
# Every command declares `risk:` — read | safe_write | destructive. It is what
|
|
# the agent approval gate reads: `read` runs unattended, `safe_write` and
|
|
# `destructive` sit behind the operator's configured threshold. An omitted
|
|
# risk is treated as `destructive`, which is the safe default but makes a
|
|
# lookup as noisy as an isolation, so declare it rather than let it default.
|
|
# read — only queries; changes nothing outside Riposte
|
|
# safe_write — additive or reversible: a comment, a ticket, a tag, a
|
|
# sandbox submission, an alert status, a collection job
|
|
# destructive — changes the estate or weakens a control: containment and
|
|
# its removal, blocklists, exclusions, deletes, identity and
|
|
# credential operations, running code on a host
|
|
# --- Request-based command (recommended: declarative, no sandbox) ---------
|
|
#
|
|
# `category` says what the command is FOR. It is what the agent browses the
|
|
# estate by: an analyst who wants to decode a rewritten URL and one who wants
|
|
# to isolate a host are not looking in the same place, and every command of
|
|
# your integration shares the manifest-level `category` above, which describes
|
|
# the PRODUCT and cannot separate them.
|
|
#
|
|
# Optional. A command that declares none is classified from its id and
|
|
# description when Riposte projects it into an agent tool — a decent guess,
|
|
# and no more than that. Declaring it stops the guessing for that command,
|
|
# which is the point of the field: you know, the classifier infers.
|
|
#
|
|
# enrich reputation or analysis of an indicator by a third party
|
|
# hunt search telemetry: events, logs, process trees
|
|
# inspect fetch one object in detail — a detection, a host, a record
|
|
# transform decode, defang, parse, extract — acting on data, not on an estate
|
|
# collect gather artefacts: jobs, forensic packages, dumps
|
|
# contain isolate, block, quarantine, suspend
|
|
# remediate undo a control or delete: unisolate, unblock, restore, purge
|
|
# identity accounts: disable, reset a password, revoke a session
|
|
# notify send a message, an e-mail, a page
|
|
# ticket create or update a ticket or a case
|
|
# manage policies, exclusions, configuration, agent lifecycle
|
|
#
|
|
# A value outside this list is ignored and the command is classified instead,
|
|
# so a typo costs the declaration rather than inventing a category nothing
|
|
# else ever lands in.
|
|
- id: lookup
|
|
name: Lookup indicator
|
|
description: Fetches a report for an indicator over HTTP.
|
|
risk: read # required in practice · read | safe_write | destructive
|
|
category: enrich # optional · what the command is FOR (see above)
|
|
inputs_schema:
|
|
properties:
|
|
indicator:
|
|
type: string
|
|
description: The value to look up
|
|
required:
|
|
- indicator
|
|
outputs_schema:
|
|
properties: {}
|
|
request:
|
|
method: GET # GET | POST | PUT | PATCH | DELETE
|
|
path: /lookup/{indicator} # {indicator} is substituted from inputs
|
|
query: [] # input names to send as query params
|
|
body: [] # input names to send as JSON body fields
|
|
auth_ref: apikey
|
|
|
|
# --- Script-based command -------------------------------------------------
|
|
# No `request:` block. Provide scripts/<id>.py next to this manifest.
|
|
# The script receives inputs in the global dict __inputs__ and MUST print
|
|
# exactly one JSON object to stdout (that becomes the command output).
|
|
# See templates/scripts/example_command.py.
|
|
- id: example_command
|
|
name: Example scripted command
|
|
description: Demonstrates a Python-backed command.
|
|
risk: read
|
|
inputs_schema:
|
|
properties:
|
|
indicator:
|
|
type: string
|
|
required:
|
|
- indicator
|
|
outputs_schema:
|
|
properties: {}
|