Skip to content

feat(recovery): verify stdout physical backup tar - #249

Draft
seonghobae wants to merge 43 commits into
fix/recovery-evidence-weakref-coverage-b84f0c9from
feat/postgres-physical-backup-verification-b84f0c9
Draft

feat(recovery): verify stdout physical backup tar#249
seonghobae wants to merge 43 commits into
fix/recovery-evidence-weakref-coverage-b84f0c9from
feat/postgres-physical-backup-verification-b84f0c9

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Bounded physical-backup verification — ACTIVE DRAFT / EXPLICIT #233 CHILD

This branch defines a bounded PostgreSQL 18 verification seam for the single-tablespace stdout tar emitted by pg_basebackup --pgdata=- --format=tar --wal-method=fetch. The injected backup_manifest is staged through retained descriptor authority and no archive member is extracted to a caller-visible path. Protected main is unchanged.

Exact stack — refreshed 2026-08-20

  • protected main: b84f0c94154043a3473939c01bb6471de5a129ae;
  • exact predecessor/base: fix/recovery-evidence-weakref-coverage-b84f0c9@5951b7a4d779903b8924abaef2a387cae50b7f54 (test(recovery): cover stale evidence registry cleanup #233);
  • head branch: feat/postgres-physical-backup-verification-b84f0c9;
  • exact current head: 15fae06ae7544a5ee665c1770ca56902e9d9e5c0;
  • Draft and mechanically mergeable; and
  • fresh targeted branch inventory finds this as the only named physical-backup-verification lane. Fresh formal reviews and inline review threads are empty; absence of review is not approval.

Canonical documentation remains separately owned by Draft #229. No source or documentation was written directly to protected main.

Bounded product contract

The verifier snapshots caller backup-directory, exact base.tar, and absolute pg_verifybackup executable authority before use; requires one owner-only single-link base.tar; bounds directory enumeration, tar members, manifest bytes/copy chunks, and the shared operational timeout; stages only the manifest to anonymous temporary-file authority; binds child verification to the retained base-tar inode through a package-owned private directory; executes shell-free through inherited descriptors; suppresses diagnostics; and maps ordinary verifier/staging/inspection failures to fixed content-free errors while preserving process-control interruption.

Success proves only PostgreSQL's bounded backup-verification result for these bytes. It does not perform WAL replay/test restore/application validation/PITR, prove timeline/archive continuity, recover external keys/configuration, or establish RPO/RTO, HA/DR, CSAP, SOC 2, or certification claims.

Executable-authority lineage

Earlier RED 983ad508d94e23d51448dc075ea512d6d5e1c1c9 proved that allowing the effective service user to own pg_verifybackup retained chmod/in-place rewrite authority. GREEN 1c2d2289d6494a054626b257b0215e2c942f06e3 restricted the retained verifier to a root-owned regular executable with at least one execute bit and no group/other write authority.

A follow-up security review found the same privilege-transition gap for set-user-ID/set-group-ID mode bits: a root-owned verifier carrying either set-id bit satisfied that predicate and could execute with unintended effective user/group authority.

  • RED 1a31e4b2ee2832a8d2d70483dfee95d9d1c9f8f4 adds focused S_ISUID/S_ISGID regressions in the ownership suite and requires rejection before retained verifier authority escapes. The predecessor predicate would return the descriptor; no hosted RED success is claimed.
  • GREEN 15fae06ae7544a5ee665c1770ca56902e9d9e5c0 rejects stat.S_ISUID | stat.S_ISGID together with group/other write authority and updates the public Linux system-package trust contract.

The backup directory and base.tar remain effective-process-owned data capabilities under their existing private/non-writable-by-others rules. This does not claim signature verification, package-manager provenance, immutable-filesystem enforcement, cross-platform parity, or host-root compromise resistance.

Exact current-head validation

Fresh commit-scoped repository validation for unchanged exact 15fae06ae7544a5ee665c1770ca56902e9d9e5c0 is terminal-success where workflows materialized:

  • CI 32286154820: success; and
  • Release Acceptance 32286154882: success.

No exact-head Security Scan or SAST Semgrep workflow is present in the commit-scoped inventory for this stacked-base head, so those gates remain explicitly absent/non-passing evidence rather than inferred success. Fresh formal reviews and inline review threads are empty; absence of review is not approval. No predecessor workflow/review evidence transfers.

Queued, pending, cancelled, skipped-required, absent, neutral, stale, predecessor, status-only, synthetic, author-only, rate-limited, infrastructure-failed, dismissed, or conclusion-null evidence is non-passing.

Dependency / integration boundary — refreshed 2026-08-30

#233 remains the exact predecessor and must integrate first. Its former read-only central coverage/review failure is historical RCA rather than the current evidence-capability boundary. Unchanged #233 now has fresh exact-contributor-head CI, Release Acceptance, Trivy Security Scan, Semgrep SAST, and bounded Strix evidence under protected central semantics. None of that evidence transfers to this child.

#233 is still non-passing because its active same-head OpenCode formal state remains CHANGES_REQUESTED, that disposition has not been superseded by a genuinely fresh qualifying semantic review, and no qualifying approval exists under live governance. Mutable central/reviewer/provider truth belongs in pg #244; central .github remains read-only. Do not churn either head merely to manufacture events, copy central workarounds, or transfer evidence.

Keep this PR Draft until #233 integrates through then-live governance. Then retarget/reconcile this branch non-destructively against resulting protected main and reacquire every then-required exact-final-head/current-base quality/security/coverage/package/provenance/release/review/thread gate, including Security/SAST evidence that is presently absent on this exact child head. Merge only with zero valid findings and the qualifying independent non-author approval required by then-live policy.

Refs #204, #233, #244, #250, #251, #252.

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

Fresh exact-head audit on 5fe370e64528f961d46ec8daac7960681cbbae87 found one still-open boundedness defect; I am not editing this active source branch while its current exact-head workflow set is in flight.

_copy_manifest_to_private_file() runs before _run_pg_verifybackup() and therefore before the only timeout_seconds boundary. It calls archive.getmembers(), which materializes the complete tar member list, and then shutil.copyfileobj(manifest_source, manifest_file) with no manifest-byte limit. The public contract calls this a bounded verification seam, but an accepted owner-controlled base.tar can consume unbounded Python-side scan/memory/staging work before PostgreSQL's subprocess timeout begins. The current API also has no archive-size or manifest-size budget.

Treat this as a reliability/resource-exhaustion blocker for the Draft, not as evidence against the already-fixed descriptor/ownership work. Narrow test-first repair: add a realistic RED proving oversized/member-explosive input is rejected before unbounded staging; then bound the pre-verifier archive/manifest work without extracting caller-visible paths, preserve the content-free error boundary, and prove the existing success path plus exact owned statement/branch coverage. Do not duplicate #233's unrelated protected-main weakref coverage repair. Re-read this branch head before any source mutation because the PR body is stale relative to the current head.

@seonghobae
seonghobae changed the base branch from main to fix/recovery-evidence-weakref-coverage-b84f0c9 August 19, 2026 00:11
@opencode-agent opencode-agent Bot added area: operations Operability, observability, readiness, SLO, backup, or retention priority: medium Normal-priority or P2 work scope: research Research, statistical validation, or scientific evidence status: draft Draft pull request type: feature New or expanded product capability labels Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: operations Operability, observability, readiness, SLO, backup, or retention priority: medium Normal-priority or P2 work scope: research Research, statistical validation, or scientific evidence status: draft Draft pull request type: feature New or expanded product capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant