backend

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package backend defines where ciphertext lives. The Backend interface is the seam between client-side-crypto and provider-holds-plaintext storage models: RcloneStorage is the only MVP implementation. A future KeyVaultBackend can implement the same interface and simply ignore the crypto layer.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("namespace not found")

ErrNotFound is returned by Get when no blob exists for the namespace.

View Source
var ErrRcloneMissing = errors.New("rclone not found in PATH")

ErrRcloneMissing is returned when no rclone binary is on PATH.

Functions

func CreateRemote

func CreateRemote(ctx context.Context, name, kind string, params map[string]string) error

CreateRemote drives `rclone config create` into the user's global rclone config. Params pass via argv: briefly visible in /proc, but with no shell nothing lands in history. This is acceptable because storage credentials only ever guard ciphertext. Revisit if rclone grows a stdin-based config path.

func ListRemotes

func ListRemotes(ctx context.Context) ([]string, error)

ListRemotes returns the names of the user's configured rclone remotes.

func RcloneInstalled

func RcloneInstalled() bool

RcloneInstalled reports whether an rclone binary is available.

func RemoteType

func RemoteType(ctx context.Context, name string) (string, error)

RemoteType returns a remote's backend type (for example "b2" or "s3"). Reads the local rclone config only, no network.

Types

type Backend

type Backend interface {
	// Get returns the stored ciphertext for a namespace (or ErrNotFound).
	Get(ctx context.Context, namespace string) ([]byte, error)
	// Put stores ciphertext. Implementations SHOULD retain prior versions.
	Put(ctx context.Context, namespace string, ciphertext []byte) error
	// List returns known namespaces.
	List(ctx context.Context) ([]string, error)
}

type HeaderStore

type HeaderStore interface {
	// GetHeader returns the raw header object (or ErrNotFound).
	GetHeader(ctx context.Context) ([]byte, error)
	// PutHeader stores the raw header object.
	PutHeader(ctx context.Context, raw []byte) error
}

HeaderStore is implemented by client-side-crypto backends, which keep the key-slot header next to the namespace blobs (see internal/crypto: LUKS2-style wrapped master key). Backends where the provider holds plaintext have no key material and won't implement it.

type RcloneStorage

type RcloneStorage struct {
	Remote string // rclone remote name, e.g. "b2"
	Base   string // path within the remote, e.g. "my-bucket/notenv"
	// Versioned: the remote retains old versions on overwrite (B2 does
	// natively), so the .prev backup copy (~3s server-side on B2) is
	// redundant and skipped.
	Versioned bool
}

RcloneStorage implements Backend by shelling out to a system rclone. This keeps the binary small and the dependency explicit; embedding the library is a possible later optimization.

func (*RcloneStorage) Get

func (s *RcloneStorage) Get(ctx context.Context, namespace string) ([]byte, error)

func (*RcloneStorage) GetHeader

func (s *RcloneStorage) GetHeader(ctx context.Context) ([]byte, error)

func (*RcloneStorage) List

func (s *RcloneStorage) List(ctx context.Context) ([]string, error)

func (*RcloneStorage) Preflight

func (s *RcloneStorage) Preflight(ctx context.Context) error

Preflight verifies rclone is installed and the remote exists.

func (*RcloneStorage) Probe

func (s *RcloneStorage) Probe(ctx context.Context) error

Probe round-trips a marker object through the configured base path so a bad credential or bucket fails here, with context, not at the first real `set` days later.

func (*RcloneStorage) Put

func (s *RcloneStorage) Put(ctx context.Context, namespace string, ciphertext []byte) error

func (*RcloneStorage) PutHeader

func (s *RcloneStorage) PutHeader(ctx context.Context, raw []byte) error

PutHeader writes the header object. Only called on creation today; when rotation lands (`notenv key ...`) it MUST grow a previous-version backup first, because a clobbered header locks the user out of every blob under it.

Jump to

Keyboard shortcuts

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