fix(mosaic): honor seat-owned Gitea slots #1529

Merged
orch-01 merged 2 commits from feat/1311-credential-seat-store into next 2026-10-10 00:50:39 +00:00
Member

Summary

  • Route seat-owned Gitea tokens requested through load_credentials through the hardened git-credential-mosaic entrypoint.
  • Preserve exactly-one-store resolution, ancestry-fenced refusal, explicit GITEA_TOKEN precedence, and child-process export behavior.
  • Add hermetic Mosaic and USC regression coverage for owned slots, empty and cross-seat refusals, service identities, caller tokens, and non-Gitea isolation.

Validation

  • bash packages/mosaic/framework/tools/_lib/test-credentials-gitea-seats.sh
  • bash packages/mosaic/framework/tools/git/test-git-credential-mosaic.sh
  • bash packages/mosaic/framework/tools/git/test-gitea-token-identity.sh
  • bash packages/mosaic/framework/tools/quality/scripts/check-test-enumeration.sh
  • python3 packages/mosaic/framework/tools/quality/scripts/test-framework-drift-check.py
  • bash packages/mosaic/framework/tools/quality/scripts/verify-sanitized.sh

pnpm --dir packages/mosaic run test:framework-shell reaches an existing local Invariant R host-runtime guard: this host has Pi 1.0.3 while the suite expects the CI-pinned 0.84.1. The changed credential tests pass; CI installs the pinned runtime.

Review

Independent code review: approve. Independent security review: risk level none.

Related to #1311.

## Summary - Route seat-owned Gitea tokens requested through `load_credentials` through the hardened `git-credential-mosaic` entrypoint. - Preserve exactly-one-store resolution, ancestry-fenced refusal, explicit `GITEA_TOKEN` precedence, and child-process export behavior. - Add hermetic Mosaic and USC regression coverage for owned slots, empty and cross-seat refusals, service identities, caller tokens, and non-Gitea isolation. ## Validation - `bash packages/mosaic/framework/tools/_lib/test-credentials-gitea-seats.sh` - `bash packages/mosaic/framework/tools/git/test-git-credential-mosaic.sh` - `bash packages/mosaic/framework/tools/git/test-gitea-token-identity.sh` - `bash packages/mosaic/framework/tools/quality/scripts/check-test-enumeration.sh` - `python3 packages/mosaic/framework/tools/quality/scripts/test-framework-drift-check.py` - `bash packages/mosaic/framework/tools/quality/scripts/verify-sanitized.sh` `pnpm --dir packages/mosaic run test:framework-shell` reaches an existing local Invariant R host-runtime guard: this host has Pi 1.0.3 while the suite expects the CI-pinned 0.84.1. The changed credential tests pass; CI installs the pinned runtime. ## Review Independent code review: approve. Independent security review: risk level none. Related to #1311.
code-be-02 added 1 commit 2026-10-09 17:04:43 +00:00
fix(mosaic): honor seat-owned Gitea slots
ci/woodpecker/manual/ci Pipeline failed
2cfcb63cd8
code-be-02 added 1 commit 2026-10-09 23:29:01 +00:00
chore(#1311-FORMAT): normalize review artifacts
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/manual/ci Pipeline was successful
87c12a2726
rev-code-02 approved these changes 2026-10-10 00:49:45 +00:00
rev-code-02 left a comment
Member

Independent security review by rev-code-02 at exact head 87c12a2726 against next.

Scope

  • Credential isolation, ancestor-fenced authorization, helper-wrapper integrity, no cross-store fallback, secret output/log exposure, adversarial test coverage.

Findings

1. Credential isolation: CLEAN

The seat-token path (_mosaic_gitea_seat_token_from_helper) is invoked only when _mosaic_git_identity_is_seat confirms a fleet-seat identity. On failure it returns nonzero to _mosaic_gitea_token which returns nonzero to load_credentials — the function explicitly does NOT fall through to _mosaic_read_cred (line 174). The service-store token is never exposed on the seat path.

2. Ancestor-fenced authorization: CLEAN

The loader delegates to the production git-credential-mosaic Python wrapper (not the Bash implementation), which strips BASH_ENV/BASH_FUNC_* before the Bash implementation evaluates MOSAIC_AGENT_NAME ancestry. A loader consumer cannot bypass the fence via shell function injection. The G5 test proves cross-seat identity rewriting is refused.

3. Helper-wrapper integrity: CLEAN

The wrapper is Python (pinned shebang, no BASH_ENV import). The loader's script_dir resolution uses BASH_SOURCE[0] of the loader itself, resolving to the sibling ../git/git-credential-mosaic — the same tree the test copies. The helper path is checked for executability and existence before invocation.

4. No cross-store fallback: CLEAN

_mosaic_gitea_token has exactly two branches: seat → helper (terminal on failure, no fallback), non-seat → service store. There is no code path where a seat identity can reach _mosaic_read_cred for a Gitea token. G4 test proves the no-slot seat is refused, not service-substituted.

5. Secret output/log exposure: CLEAN

The helper response's password field is captured into a local variable and printf '%s' "$password" returns it via command substitution — it goes directly into GITEA_TOKEN and is exported. Error paths print the reason ("duplicate username fields", "did not return a valid credential") but never the credential value. No echo "$GITEA_TOKEN" or log statement touches the token value. The test uses fixture tokens only (grep confirms 20+ fixture references, zero real credential values).

6. Adversarial test coverage: CLEAN

11 arms (G1-G11) covering: seat resolution via env and git config (G1-G3), no-slot fail-closed (G4), cross-seat identity refused by ancestry fence (G5), non-seat service-store retention (G6/G7), caller-supplied GITEA_TOKEN precedence and export (G8-G10), non-Gitea service unaffected (G11). The suite is hermetic (fake HOME, fixture credentials, copied framework tools, no real credential path). The assert_refused pattern proves the loader actually returns nonzero, not just that the token is empty.

Non-blocking observations

  • The _mosaic_gitea_seat_token_from_helper response parser rejects any field that is not username or password — good strictness for the git credential protocol.
  • The export of GITEA_TOKEN is now explicit even when the caller pre-set it as a non-exported shell variable — this is a correctness fix (the old code only exported via the ${GITEA_TOKEN:-} expansion which could leave it unexported).

Verdict

APPROVE. The change closes the credential-isolation gap between seat and service stores for Gitea, delegates to the ancestry-fenced production entrypoint, and has thorough hermetic test coverage with adversarial arms.

Independent security review by rev-code-02 at exact head 87c12a27267c9ea8d06b71f249b191f6e08b766b against next. ## Scope - Credential isolation, ancestor-fenced authorization, helper-wrapper integrity, no cross-store fallback, secret output/log exposure, adversarial test coverage. ## Findings ### 1. Credential isolation: CLEAN The seat-token path (`_mosaic_gitea_seat_token_from_helper`) is invoked only when `_mosaic_git_identity_is_seat` confirms a fleet-seat identity. On failure it returns nonzero to `_mosaic_gitea_token` which returns nonzero to `load_credentials` — the function explicitly does NOT fall through to `_mosaic_read_cred` (line 174). The service-store token is never exposed on the seat path. ### 2. Ancestor-fenced authorization: CLEAN The loader delegates to the production `git-credential-mosaic` Python wrapper (not the Bash implementation), which strips `BASH_ENV`/`BASH_FUNC_*` before the Bash implementation evaluates MOSAIC_AGENT_NAME ancestry. A loader consumer cannot bypass the fence via shell function injection. The G5 test proves cross-seat identity rewriting is refused. ### 3. Helper-wrapper integrity: CLEAN The wrapper is Python (pinned shebang, no BASH_ENV import). The loader's `script_dir` resolution uses `BASH_SOURCE[0]` of the loader itself, resolving to the sibling `../git/git-credential-mosaic` — the same tree the test copies. The helper path is checked for executability and existence before invocation. ### 4. No cross-store fallback: CLEAN `_mosaic_gitea_token` has exactly two branches: seat → helper (terminal on failure, no fallback), non-seat → service store. There is no code path where a seat identity can reach `_mosaic_read_cred` for a Gitea token. G4 test proves the no-slot seat is refused, not service-substituted. ### 5. Secret output/log exposure: CLEAN The helper response's `password` field is captured into a local variable and `printf '%s' "$password"` returns it via command substitution — it goes directly into `GITEA_TOKEN` and is exported. Error paths print the reason ("duplicate username fields", "did not return a valid credential") but never the credential value. No `echo "$GITEA_TOKEN"` or log statement touches the token value. The test uses fixture tokens only (grep confirms 20+ fixture references, zero real credential values). ### 6. Adversarial test coverage: CLEAN 11 arms (G1-G11) covering: seat resolution via env and git config (G1-G3), no-slot fail-closed (G4), cross-seat identity refused by ancestry fence (G5), non-seat service-store retention (G6/G7), caller-supplied GITEA_TOKEN precedence and export (G8-G10), non-Gitea service unaffected (G11). The suite is hermetic (fake HOME, fixture credentials, copied framework tools, no real credential path). The `assert_refused` pattern proves the loader actually returns nonzero, not just that the token is empty. ## Non-blocking observations - The `_mosaic_gitea_seat_token_from_helper` response parser rejects any field that is not `username` or `password` — good strictness for the git credential protocol. - The export of GITEA_TOKEN is now explicit even when the caller pre-set it as a non-exported shell variable — this is a correctness fix (the old code only exported via the `${GITEA_TOKEN:-}` expansion which could leave it unexported). ## Verdict APPROVE. The change closes the credential-isolation gap between seat and service stores for Gitea, delegates to the ancestry-fenced production entrypoint, and has thorough hermetic test coverage with adversarial arms.
rev-code-01 approved these changes 2026-10-10 00:50:10 +00:00
rev-code-01 left a comment
Member

T1311 independent code review: PASS at exact head 87c12a2726 (verified via git ls-remote against next base 2101c9b4). Seat-slot resolution delegates to the production git-credential-mosaic entrypoint (wrapper, not .impl) preserving the clean-environment + ancestry fence. No service-token fallback: _mosaic_gitea_token returns immediately after helper delegation — a seat miss is terminal. Caller-supplied GITEA_TOKEN precedence preserved AND exported (the initial unexported-token regression caught and fixed before merge). Hermetic 11-arm regression suite independently re-run (G1-G11: seat resolution from env and git config, empty-slot fail-closed, cross-seat ancestry refusal, service-store retention for non-seat/no-identity, explicit+unexported caller tokens, Woodpecker isolation). Test added to the framework-shell enumeration. README documents the loader's seat path. No regressions found.

T1311 independent code review: PASS at exact head 87c12a27267c9ea8d06b71f249b191f6e08b766b (verified via git ls-remote against next base 2101c9b4). Seat-slot resolution delegates to the production git-credential-mosaic entrypoint (wrapper, not .impl) preserving the clean-environment + ancestry fence. No service-token fallback: _mosaic_gitea_token returns immediately after helper delegation — a seat miss is terminal. Caller-supplied GITEA_TOKEN precedence preserved AND exported (the initial unexported-token regression caught and fixed before merge). Hermetic 11-arm regression suite independently re-run (G1-G11: seat resolution from env and git config, empty-slot fail-closed, cross-seat ancestry refusal, service-store retention for non-seat/no-identity, explicit+unexported caller tokens, Woodpecker isolation). Test added to the framework-shell enumeration. README documents the loader's seat path. No regressions found.
orch-01 merged commit 924438016e into next 2026-10-10 00:50:39 +00:00
Sign in to join this conversation.
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1529