Skip to content

fix(kickoff): macOS Keychain auth fallback + protect --doc from agent rewrites#588

Merged
dollspace-gay merged 2 commits into
developfrom
fix/580-keychain-auth-and-doc-protection
May 11, 2026
Merged

fix(kickoff): macOS Keychain auth fallback + protect --doc from agent rewrites#588
dollspace-gay merged 2 commits into
developfrom
fix/580-keychain-auth-and-doc-protection

Conversation

@dollspace-gay
Copy link
Copy Markdown

Summary

Fixes both bugs in GH#580:

  • Bug 1 — macOS Keychain auth gap: container entrypoint only handled /host-auth/.credentials.json, so macOS hosts (OAuth lives in Keychain, no file on disk) booted the agent unauthenticated. Now resolves auth via fallback chain: credentials.json → /host-auth/*.env (sourced) → CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_API_KEY env passthrough. launch_container forwards those env vars via docker -e NAME (no value, so tokens stay out of ps). Emits a clear stderr warning when no source resolves instead of failing silently.
  • Bug 2 — agent rewrote the --doc file: four-layer defense — KICKOFF.md "Canonical Input" stanza, chmod 0444 on the worktree copy, container :ro overlay mount on top of the writable workspace, and a .kickoff-doc.json breadcrumb (rel_path + SHA-256) that crosslink kickoff status and report re-verify on the way out. Drift surfaces as a Mismatch line + tracing::error! so it cannot be silently shipped.

Closes GH#580. Tracked locally as #729.

Test plan

  • cargo test --bin crosslink — 2808 passed, 0 failed
  • cargo clippy --lib --bin crosslink -- -D warnings — clean
  • 5 new unit tests cover the integrity verdict matrix (NotProtected / Match / Mismatch / Missing on deletion / Missing on malformed breadcrumb)
  • Existing exclude-pattern tests updated for the new .kickoff-doc.json entry
  • bash -n entrypoint.sh — syntax ok
  • Manual smoke: crosslink kickoff run --container docker --doc .design/<doc>.md ... on macOS — verify Keychain-only hosts now authenticate via CLAUDE_CODE_OAUTH_TOKEN, and the agent cannot write to the mounted .design/<doc>.md
  • Manual smoke: deliberately edit the doc in the worktree post-launch → confirm crosslink kickoff status and report flag the mismatch

🤖 Generated with Claude Code

dollspace-gay and others added 2 commits May 11, 2026 12:26
… rewrites (#729, GH#580)

## Bug 1 — macOS Keychain auth gap

The container entrypoint only handled `/host-auth/.credentials.json`. On
macOS the claude CLI keeps OAuth in Keychain, so the file doesn't exist
and the agent boots unauthenticated.

- `entrypoint.sh` now resolves auth via a fallback chain:
  credentials.json → `/host-auth/*.env` (sourced) → `CLAUDE_CODE_OAUTH_TOKEN`
  / `ANTHROPIC_API_KEY` env passthrough. Emits a clear warning to stderr
  when no source resolves instead of failing silently.
- `launch_container` forwards those two env vars to the runtime via
  `-e NAME` (no value), so tokens stay out of `ps` listings.

## Bug 2 — agent rewrote the design doc passed via --doc

The kickoff agent edited the canonical design file mid-run, dropping
OPEN-question markers and reshaping headings.

Defense in depth:
- Prompt: KICKOFF.md gains a "Design Document — Canonical Input" stanza
  when `--doc` is supplied.
- chmod 0444 on the worktree copy of the doc at launch time.
- Container `:ro` overlay mount of the doc on top of the writable
  workspace mount.
- Launch-time breadcrumb (`.kickoff-doc.json`) records rel_path +
  SHA-256; `crosslink kickoff status` / `report` re-hashes on the way
  out and emits a Mismatch line + tracing::error! on drift.

## Tests

5 new unit tests cover the integrity verdict matrix (NotProtected /
Match / Mismatch / Missing-deleted / Missing-malformed). Existing
exclude-pattern tests updated for the new `.kickoff-doc.json` entry.

Full suite: 2808 passed, 0 failed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pure formatting — rejoins a let binding that fits on one line. No
behavior change. Verified `cargo fmt --check` clean and
`cargo clippy --lib --bin crosslink -- -D warnings` clean afterwards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dollspace-gay dollspace-gay self-assigned this May 11, 2026
@dollspace-gay dollspace-gay merged commit 6cab4de into develop May 11, 2026
10 checks passed
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.

kickoff agent: macOS-Keychain auth gap + unsanctioned rewrite of --doc design file

1 participant