Files
server-deploy/internal/appbundle

Local package verifier

Verify(directory, expectedDigest) accepts an absolute staging directory and a canonical sha256: digest of its exact manifest.json bytes. It returns the validated manifest, matching payload bytes keyed by relative path, and manifest digest. On failure it returns a zero Verified and fixed diagnostic text without embedding file contents, decoder errors, or filesystem paths.

The manifest is limited to 1 MiB, each payload to 4 MiB, and all payloads together to 16 MiB. Metadata checks precede opening regular files; actual reads also have a limit plus one overflow-detection byte and must match the observed size. The manifest digest is checked before shared wire.Decode parses it.

Inventory is derived from at most 128 declared files and their parent directories. Each directory is enumerated one entry at a time; an unexpected entry fails immediately. Symlinks, special files, empty/unnecessary directories, and unlisted files are rejected. Lowercase portable paths prevent case collisions. Files and subdirectories are opened relative to os.Root, with identity checks around open.

The caller must select a trusted staging directory with trusted ancestors and prevent concurrent mutation. These checks do not provide a transactional snapshot or complete protection against hostile concurrent filesystem changes. Consumers should use the returned bytes rather than reopen package files.

This authenticates bytes against a caller-provided trust anchor. It does not authenticate a publisher, validate Compose semantics, or authorize execution. Signature trust stores and executable policy are outside this package.

Tests use local temporary directories. Symlink cases skip only Windows error 1314 (missing symlink privilege). Linux-specific FIFO cases verify rejection without opening the FIFO; run tests with a timeout, for example:

go test ./internal/appbundle -count=1 -timeout=30s
go vet ./internal/appbundle