Manifest sidecar / metadata (версия данных v1)

Этот документ описывает поля JSON-манифеста, которые агент сохраняет как storage.BackupManifest (iobackup/internal/storage/models.go) и отдаёт клиенту через GET /api/v1/artifacts/{backup_id} и .../manifest.

Версия схемы

Поле version на верхнем уровне JSON — строковая ревизия контракта. Агент записывает "1" для всех новых манифестов (ManifestSchemaVersionV1).

Записи без version могли быть созданы ранним билдом: при наличии checksum/artifact их по-прежнему можно верифицировать.

Поля верхнего уровня (legacy + vNext additive)

Поле Тип Назначение
manifest_id string Идентификатор записи манифеста (additive, 0.17-fix.40+).
backup_id string Первичный ключ артефакта / манифеста.
version string Версия схемы манифеста (обычно 1).
agent object Agent identity block (optional).
job_uid string Immutable job identity (optional for very old rows).
job_id string Исторический/текущий job_id.
job_revision_id string Job revision, с которой запускался run (optional for old rows).
job_revision number Номер revision (optional).
task_id string Какая task создала артефакт.
task_index number Индекс task в executed snapshot (optional).
task_hash string Hash executed task snapshot (optional).
run_id string В какой run выполнена запись.
request_id string Request id (optional).
correlation_id string Correlation id (optional).
trace_id string Distributed trace id (optional).
created_at RFC3339 time Момент фиксации манифеста.
operation string | object Legacy: "backup". vNext: { "type": "backup", "strategy": "full" }.
lineage object Backup lineage (full/incremental reserved).
repository object Repository model (исполняется только single_artifact/iobackup).
artifact_format object Logical/container format + naming version.
compression object Compression info.
checksums array Массив checksum entries (scope, algorithm, value).
artifacts array Список artifact descriptors (минимум role=data и role=manifest).
source object Source block: type, metadata, consistency.
destination object Destination block: type, metadata, write_policy.
provider_versions object Версии внешних tools/клиентов, зафиксированные агентом (additive).
checks object Verification state placeholders.
restore object Restore readiness placeholder.
data_encryption object Optional client-side streaming encryption metadata (0.43+): algorithm, framing, chunk size, optional wrap_provider_type / key_identifier (0.45.1+), legacy key_ref (older direct-mode manifests only), and/or envelope (wrapped DEK only — never raw DEK/KEK).
immutability object Reserved immutability metadata.
catalog object Reserved catalog metadata.
capabilities_used string array Capability-теги, задействованные при исполнении (additive).
status string Служебный статус манифеста (поверх run/task статусов).
retention_tags string array Отметки для политики retention (если добавлены).
metadata map string→string Legacy string metadata (не для секретов).
manifest_metadata object Расширяемый блок метаданных (additive); не для секретов.

Примечание о совместимости: legacy поля artifact, checksum, source_type, destination_type, а также operational поля status / retention_tags сохраняются для backward compatibility и аудита; основная контрактная модель v1 — через artifacts[], checksums[], source/destination, repository/lineage и связанные additive поля.

Идентификаторы: backup_id, manifest_id, artifact_id, repository.*

В блоке repository (см. spec.repository / ManifestRepository):

Без секретов в манифесте

В JSON манифеста не должно быть значений секретов (пароли, токены, raw vault payloads). Чувствительные поля в API и webhook проходят redaction; executed_job_snapshot в webhook по умолчанию выключен (include_job_snapshot: false).

Sidecar manifest

Минимальный исполняемый набор дескрипторов в artifacts[]: role=data (основной поток) и role=manifest (sidecar JSON). Sidecar удаляется вместе с data-артефактом при retention/delete, если destination поддерживает удаление обоих объектов. Если sidecar потерян, восстановление метаданных только из object storage будет ограничено (см. docs/features/retention/retention.md).

Checksum scopes (checksums[])

Каждый элемент: scope, algorithm, опционально value.

Scope Назначение
artifact Digest of the object bytes at rest on the destination (ciphertext when data_encryption.enabled=true).
plaintext Digest of the logical stream before encryption (populated when client-side encryption is enabled).
encrypted Same as artifact when encryption is enabled (explicit ciphertext scope for tooling).

Верификация и read из destination опираются на scope=artifact (или legacy поле checksum), см. internal/agent/manifest_v1.go.

Legacy объект artifact (для совместимости)

Соответствует ManifestArtifact:

Поле Описание
name Логическое имя файла/объекта.
content_type MIME.
path Ключ/path в destination провайдере.
size_bytes Размер потока/объекта.

Полей encryption верхнего уровня пока нет — шифрование в backlog как planned capability.

Verify

Verification API сравнивает фактический поток/read из destination с checksum/size_bytes из этой записи; при ошибке сохраняется VerificationResult.

Совместимость

Новые поля допускаются как additive (клиенты и UI должны игнорировать неизвестные ключи).

Redaction (0.17-fix.50)

Перед выводом через API/webhook/export чувствительные поля (password/token/vault refs, а также path/object_key) проходят через redaction layer.

provider_versions и capabilities_used (additive)

Оба поля опциональны; старые манифесты могут их не содержать.

Примеры JSON

Текущий full-backup манифест (full-ish, исполняемый сценарий)

{
  "version": "1",
  "manifest_id": "mfst_01JEXAMPLE",
  "backup_id": "bkp_01JEXAMPLE",
  "agent": { "id": "agent_01JEXAMPLE", "instance_id": "inst_01JEXAMPLE", "hostname": "host1" },
  "job_uid": "jobuid_01JEXAMPLE",
  "job_id": "filesystem-local",
  "job_revision_id": "jrev_01JEXAMPLE",
  "job_revision": 3,
  "task_id": "main",
  "task_index": 0,
  "task_hash": "tskhash_01JEXAMPLE",
  "run_id": "run_01JEXAMPLE",
  "request_id": "req_01JEXAMPLE",
  "correlation_id": "corr_01JEXAMPLE",
  "operation": { "type": "backup", "strategy": "full" },
  "lineage": { "backup_kind": "full", "sequence": 1 },
  "repository": { "type": "single_artifact", "engine": "iobackup" },
  "artifact_format": { "type": "tar_gzip", "naming_version": "v1" },
  "compression": { "algorithm": "gzip" },
  "checksums": [{ "scope": "artifact", "algorithm": "sha256", "value": "…" }],
  "artifacts": [
    { "role": "data", "name": "backup.tar.gz", "size_bytes": 123 },
    { "role": "manifest", "name": "manifest.json", "size_bytes": 456 }
  ],
  "source": { "type": "filesystem", "metadata": {}, "consistency": { "mode": "crash_consistent" } },
  "destination": { "type": "local", "metadata": {}, "write_policy": { "mode": "iobackup_owned" } },
  "checks": { "artifact_verify": "unknown", "decrypt_verify": "unknown", "format_verify": "unknown", "repository_verify": "unknown", "catalog_verify": "unknown", "restore_smoke": "reserved" },
  "restore": { "notes": "restore is not implemented in v1" },
  "immutability": { "enabled": false, "legal_hold": false },
  "catalog": { "enabled": false },
  "provider_versions": { "aws": "2.x", "tar": "1.x" },
  "capabilities_used": ["source.stream", "destination.stream_put"],
  "manifest_metadata": { "note": "additive metadata; do not put secrets here" }
}

Future filesystem_incremental (reserved / не исполняется)

{
  "version": "1",
  "backup_id": "bkp_future_incr",
  "operation": { "type": "backup", "strategy": "incremental" },
  "lineage": { "backup_kind": "incremental", "chain_id": "chn_01JEXAMPLE", "sequence": 2 },
  "repository": { "type": "content_addressed", "engine": "restic", "repository_id": "repo_demo" },
  "source": { "type": "filesystem_incremental", "metadata": {} },
  "restore": { "notes": "restore flow not implemented" }
}

Такой манифест в репозитории не должен появляться от текущего агента: source.type: filesystem_incremental отклоняется на валидации job. Пример нужен только для согласования схемы с roadmap.

См. также