takeout

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package takeout defines the Take-Out of restore Path A: its directory layout, its manifest, and the key-free integrity check both halves of the path run on it (decisions.md, "Restore paths (contract)").

The split of powers is the whole point and is enforced by the package layout:

  • The admin half, takeout/remote, runs with S3 access only. Extract has no key parameter of any kind and therefore *cannot* decrypt: the admin moves ciphertext, nothing else (decisions.md #2, #15).
  • The user-side half lives in the subpackage takeout/decrypt, which runs on the user's own machine with the Recovery Key, touches no network and needs no OpenCloud (decisions.md, Path A). Keeping it out of the admin's packages is what lets the admin's binary be built without any code that unwraps a Data Key or restores a repository, rather than merely not calling it.
  • This package sits under both and links neither an S3 client nor an unwrap path, so each side can read the format without the other's capabilities (phase 10.6).

A Take-Out is a plain directory so it stays readable by hand and by future tooling:

<out>/manifest.json     provenance + integrity records (no key material)
<out>/recovery.ocbke    the RK-wrapped Data Key envelope (ciphertext)
<out>/repo/...          the Space's kopia repository, copied verbatim

This layout is a long-term promise in the same sense as the key envelope: the decrypt tool is the family's last resort and must keep reading old Take-Outs.

Index

Constants

View Source
const (
	// ManifestFormat identifies a Take-Out directory.
	ManifestFormat = "opencloud-backup-takeout"
	// ManifestVersion is the current Take-Out manifest version. Bump additively;
	// the decrypt tool must keep reading every version.
	ManifestVersion = 1

	// ManifestFile is the manifest's name inside a Take-Out directory.
	ManifestFile = "manifest.json"
	// EnvelopeFile is the RK-wrapped Data Key envelope's name inside a
	// Take-Out directory.
	EnvelopeFile = "recovery.ocbke"
	// RepoDir is the kopia repository's directory inside a Take-Out.
	RepoDir = "repo"
)

Variables

View Source
var (
	// ErrNoTakeOut means the directory is not (or is no longer) a Take-Out.
	ErrNoTakeOut = errors.New("takeout: not a take-out directory (manifest.json missing)")
	// ErrNoEnvelope means the target holds no key envelope for the Space, so a
	// Take-Out from it could never be decrypted.
	ErrNoEnvelope = errors.New("takeout: no recovery key envelope found for this space")
	// ErrCorrupt means the Take-Out failed its integrity check.
	ErrCorrupt = errors.New("takeout: take-out is damaged")
	// ErrNewerTakeOut means the manifest declares a format version this build
	// does not know. The Take-Out is not damaged; a newer decrypt reads it.
	ErrNewerTakeOut = errors.New("takeout: take-out format is newer than this tool")
)

Errors surfaced to operators and users. They stay coarse on purpose: an unwrap failure must not hint at which part of the input was wrong, and no error ever carries key material.

Functions

func Verify

func Verify(ctx context.Context, dir string) error

Verify re-reads a Take-Out and checks it against its own manifest. It needs no key: the integrity of the ciphertext is verifiable by whoever holds the copy.

func WriteManifest

func WriteManifest(dir string, m Manifest) error

WriteManifest serializes the manifest into a Take-Out directory.

Types

type BlobRef

type BlobRef struct {
	ID     string `json:"id"`
	Size   int64  `json:"size"`
	SHA256 string `json:"sha256"`
}

BlobRef records one copied repository blob. The digest is over ciphertext and reveals nothing about the backed-up data; it exists so a Take-Out can be verified offline before anyone depends on it. It is part of the manifest format, so it is defined here and not by the code that copies the blobs.

type EnvelopeRef

type EnvelopeRef struct {
	Version        int    `json:"version"`
	Kind           string `json:"kind"`
	KDF            string `json:"kdf"`
	ArgonTime      uint32 `json:"argon_time,omitempty"`
	ArgonMemoryKiB uint32 `json:"argon_memory_kib,omitempty"`
	ArgonLanes     uint8  `json:"argon_lanes,omitempty"`
}

EnvelopeRef describes the copied key envelope without revealing anything secret: format version, wrap kind and the (public) KDF parameters.

type Manifest

type Manifest struct {
	Format      string    `json:"format"`
	Version     int       `json:"version"`
	SpaceID     string    `json:"space_id"`
	CreatedAt   time.Time `json:"created_at"`
	Source      SourceRef `json:"source"`
	RepoDir     string    `json:"repo_dir"`
	EnvelopeRef string    `json:"envelope_file,omitempty"`
	// Envelope is absent when the Take-Out was forced without one.
	Envelope   *EnvelopeRef `json:"envelope,omitempty"`
	BlobCount  int          `json:"blob_count"`
	TotalBytes int64        `json:"total_bytes"`
	// Blobs records every copied repository blob (id, size, ciphertext digest)
	// so the copy can be verified offline.
	Blobs []BlobRef `json:"blobs"`
}

Manifest is the Take-Out's self-description. It contains no key material.

func ReadManifest

func ReadManifest(dir string) (Manifest, error)

ReadManifest loads the manifest of a Take-Out directory.

func (Manifest) EnvelopePath

func (m Manifest) EnvelopePath(dir string) string

EnvelopePath returns the file holding the RK-wrapped Data Key envelope.

func (Manifest) RepoPath

func (m Manifest) RepoPath(dir string) string

RepoPath returns the directory holding the copied repository.

type SourceRef

type SourceRef struct {
	Endpoint string `json:"endpoint,omitempty"`
	Bucket   string `json:"bucket,omitempty"`
	Prefix   string `json:"prefix,omitempty"`
	// RepoPrefix and EnvelopeKey are the exact object keys that were copied.
	RepoPrefix  string `json:"repo_prefix"`
	EnvelopeKey string `json:"envelope_key"`
}

SourceRef records where a Take-Out came from. It is provenance only and holds no credentials — a Take-Out is handed to an end user.

Directories

Path Synopsis
Package decrypt is the user-side half of Path A: unwrap the Data Key with the Recovery Key and restore a snapshot out of a Take-Out directory.
Package decrypt is the user-side half of Path A: unwrap the Data Key with the Recovery Key and restore a snapshot out of a Take-Out directory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL