securewipe

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package securewipe destroys credential material on disk and says whether it succeeded.

Why this is its own package

Two copies of this code existed — pkg/secretbroker (the hub's lease mount) and pkg/executor/agent (an edge device's confined vault) — and both had the same defect: every step of the overwrite was written `_ =`. If the O_WRONLY open failed, or WriteAt failed, or Sync failed, the function still returned nil. Only the unlink was actually guaranteed, so a caller that logged "credential wiped" had been told the bytes were zeroed when they had merely been made unreachable through that name. On the os.TempDir() fallback path, where the lease directory is on a real filesystem rather than a tmpfs, that is the difference between a destroyed secret and a recoverable one.

The duplication is why the defect survived: fixing one copy would have left the other lying. Neither package could host the shared version — the agent must build for a device that carries no secret store, so it cannot import the broker, and the broker has no business importing an agent. Hence a leaf package that depends on nothing outside the standard library.

What "wiped" means here, and what it does not

File overwrites the bytes with zeros, fsyncs, and unlinks. That defeats a reader of the raw device on a conventional filesystem. It does not defeat:

  • a copy-on-write or log-structured filesystem (btrfs, ZFS, F2FS, APFS), where the overwrite lands in a new extent and the old one survives until it is reclaimed;
  • a filesystem-level or block-level snapshot taken while the file existed;
  • an SSD's flash translation layer, which may have already relocated the page.

This is why callers put lease directories on a tmpfs first (/dev/shm, /run) and treat the wipe as the fallback rather than the primary guarantee. See secretbroker.tmpfsCandidates.

Confinement

Dir refuses any directory whose name does not carry LeaseDirPrefix, and File refuses anything that is not a regular file. Both matter because on the agent side the paths originate from the control plane, which this system's threat model treats as a party that can be compromised: without the checks, "revoke this lease" is an arbitrary-unlink primitive on every enrolled device. See docs/security/model.md and pkg/executor/agent/vault.go.

Index

Constants

View Source
const LeaseDirPrefix = "cloop-lease-"

LeaseDirPrefix names every directory a lease's credential files live in, on the hub and inside a sandbox alike.

It is load-bearing rather than cosmetic: an agent refuses to unlink any path whose parent is not named this way, so a directory chosen for a sandbox must carry the prefix too. See secretbroker.SandboxLeaseDir.

Variables

This section is empty.

Functions

func Dir

func Dir(dir string) error

Dir wipes every credential file in a lease directory and removes it.

Only a directory whose name carries LeaseDirPrefix is accepted, and the walk is deliberately one level deep: a lease directory is flat by construction, so a subdirectory is something this system did not create and a recursive delete driven by a supplied path is precisely the primitive the confinement rules withhold. Anything unexpected is reported and left in place, which also leaves the directory non-empty so its own removal fails loudly rather than silently discarding the evidence.

A missing directory is not an error.

func File

func File(path string) error

File overwrites a credential file with zeros, syncs it, and unlinks it.

A missing file is not an error: something else having already cleaned up is the end state this function exists to reach.

Every failure is returned. That is the entire point of the function, and the reason it replaced two copies that returned nil unconditionally: a caller deciding whether to tell an operator "the credential is gone" needs to know whether it is. When the overwrite fails the unlink is still attempted and both errors are joined — an unlinked-but-not-zeroed file is a weaker outcome than a destroyed one, but a strictly better one than leaving the plaintext in place because the first step failed.

A symlink is removed, never followed. Following one would write zeros through the link into whatever it points at, which for a path supplied by a remote control plane is a write primitive rather than a wipe.

func IsLeaseDir

func IsLeaseDir(dir string) bool

IsLeaseDir reports whether dir's final element is a lease directory.

The prefix alone is not enough — "cloop-lease-" exactly would match every bare prefix — so a non-empty suffix is required.

Types

This section is empty.

Jump to

Keyboard shortcuts

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