Skip to content

feat(secret-push): variadic targets + System.keychain backing (S-63)#90

Merged
tieubao merged 2 commits into
mainfrom
feat/secret-upsert-multi-host
May 10, 2026
Merged

feat(secret-push): variadic targets + System.keychain backing (S-63)#90
tieubao merged 2 commits into
mainfrom
feat/secret-upsert-multi-host

Conversation

@tieubao
Copy link
Copy Markdown
Member

@tieubao tieubao commented May 10, 2026

Summary

  • Promotes dotfiles secret push into a multi-host upsert: variadic targets, --backing-store=login|system, --local. Auto-detect delete-then-add subsumes seed + rotation on both backing stores.
  • New bash helper home/dot_local/bin/secret-upsert-target does the per-target dance (probe, delete, add via stdin, verify, neg-clear). Mirrors the fish/bash split from S-61.
  • Closes S-51 § Trade-offs row 2 + S-53 § Future work item 1.
  • Triggered by today's 2026-05-10 SA rotation event (operations cookbook included documents the actual rotation across Air + Mini).

Why now

Today's rotation went through the pre-S-63 flow: 6 commands across 3 sessions, with add -U against System.keychain silently failing on the first attempt (User interaction is not allowed + specified item already exists, exit 0, no value change). Decision 2 in the spec codifies the delete-then-add fix; Decision 6 closes the negative-cache footgun. Full design context in docs/specs/S-63-secret-rotate-multi-host.md.

What changed

Surface Change
dotfiles secret push Variadic targets, --backing-store=login|system, --local. Backwards-compat: existing single-target invocations behave identically.
home/dot_local/bin/secret-upsert-target NEW per-target helper.
docs/specs/S-63-secret-rotate-multi-host.md NEW framework spec (~400 lines, S-51 structure).
docs/operations/2026-05-10-sa-rotation-air-mini.md NEW author's specific rotation cookbook.
docs/specs/S-51-*.md, docs/specs/S-53-*.md Cross-references closed/updated.
docs/secrets-architecture.md Spec table extended (S-53/S-61/S-62/S-63), Q1 closed.
docs/tasks.md S-63 row, v0.6.4 banner bump.
docs/sync-log.md Hostname-tagged ship entry.
scripts/test-doc-discipline.sh Adds S-63 spec + new helper to FRAMEWORK_DOCS; cookbook to OPERATIONS_DOCS.

Test plan

  • scripts/test-doc-discipline.sh passes (11 framework docs placeholder-clean, 2 operations cookbooks contain expected personal markers).
  • fish -c 'dotfiles secret push' shows new usage with all four shape examples.
  • E2E smoke against mini-tieubao with --backing-store=system: 1 succeeded, 0 failed. op whoami via no-agent SSH confirms the expected SA Integration ID post-seed.
  • --local end-to-end on Air (deferred; today's local rotation already happened via the manual paste flow before this PR).
  • Multi-host (host-a host-b) sequential iteration test (not covered today since N=1 in the smoke; helper logic handles it but unverified at runtime).
  • Per-target failure isolation test (intentionally bad SSH alias mid-list).

The deferred items are the spec's test-plan rows 9, 10, 13, 14 — exercise on the next real rotation rather than synthesizing them here.

Versioning

v0.6.4 patch (additive; no breaking change to the existing push VAR target invocation form). Banner already bumped in tasks.md. Tag the release after this merges.

🤖 Generated with Claude Code

tieubao and others added 2 commits May 10, 2026 17:34
Promotes `dotfiles secret push` from a single-host login-keychain seed
into a multi-host upsert that handles both backing stores, both seed
and rotation cases, and verifies each target before claiming success.
Closes S-51 § Trade-offs row 2 + S-53 § Future work item 1. Triggered
by 2026-05-10 SA rotation event (rotation across Air + Mini that
exercised the gotchas this spec codifies).

New surface:
  - Variadic targets after VAR_NAME (one or more SSH aliases).
  - --backing-store=login|system flag (default login for backwards-compat).
  - --local opts the local machine into the iteration.
  - Per-target verdict + final summary; non-zero exit on any failure.
  - Sequential iteration (parallel sudo/biometric prompts interleave illegibly).

Auto-detect upsert (delete-then-add unconditionally) subsumes both
seed and rotation cases on both backing stores at the cost of one
extra keychain op. Required because add -U against System.keychain
over non-TTY SSH silently fails: macOS gates ACL updates behind a
GUI prompt that piped SSH cannot satisfy. Symptoms: User-interaction-
not-allowed + already-exists, exit 0, no value change. Login.keychain
doesn't gate ACL updates so -U worked there; S-53's System.keychain
path needed delete-then-add.

Negative-cache .miss cleanup as a side-effect of every successful
seed closes the rotated-but-still-empty-for-24h footgun (the cache
script's 24h TTL otherwise survives the rotate).

New bash helper home/dot_local/bin/executable_secret-upsert-target
does the per-target dance (probe sudo, delete, add via stdin, verify
by read-back, neg-clear). Pulled out of fish because remote sudo +
heredocs + fish quoting is unreadable past 2 layers. Mirrors the
fish/bash split from S-61.

Cross-references and cookbook:
  - S-51 trade-offs row 2 + spec chain table updated.
  - S-53 future-work item 1 closed.
  - secrets-architecture: spec table extended, Q1 closed, operations
    cookbook reference added.
  - tasks.md: S-63 row + v0.6.4 banner bump.
  - sync-log.md: hostname-tagged entry for the S-63 ship event.
  - New operations cookbook docs/operations/2026-05-10-sa-rotation-air-mini.md
    documents today's specific rotation across Air + Mini.

Doc discipline:
  - scripts/test-doc-discipline.sh extended with S-63 spec + new
    helper in FRAMEWORK_DOCS (placeholder-clean) and the new
    operations cookbook in OPERATIONS_DOCS (must contain personal
    markers). Test passes.

Tested:
  - Doc-discipline test: PASS.
  - Usage line shape: PASS.
  - E2E smoke against headless host (--backing-store=system): PASS;
    op whoami via no-agent SSH confirms expected SA Integration ID.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a notify-only sub-check under Step 2 that runs `op whoami` and
greps stderr for the specific 403 "Service Account Deleted" string.
On a hit, the report's notify-only band surfaces the S-63 push one-
liner so the user doesn't have to remember it.

Two cases produce the same error string and the output covers both:
  (a) keychain itself is stale (rotation just happened, no fix yet)
      → dotfiles secret push OP_SERVICE_ACCOUNT_TOKEN <hosts> --local --backing-store=system
  (b) keychain is fresh but THIS shell's env is older
      → exec fish (reloads env from the fresh keychain)

Fail-soft on every other op error (network down, op missing, signed
out) — those have other surfacing paths and aren't rotation signals.

Updates the Step 3d notify-only example to show how it renders.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tieubao tieubao merged commit dd3ae3a into main May 10, 2026
2 checks passed
@tieubao tieubao deleted the feat/secret-upsert-multi-host branch May 10, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant