Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3f107e3

Browse files
docs(289): public 2026Q2 security posture doc — BLP-02 closure narrative (#291)
1 parent 7a01315 commit 3f107e3

1 file changed

Lines changed: 183 additions & 0 deletions

File tree

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# tachi Security Posture — 2026Q2 Hardening Cycle
2+
3+
**Assessment Window**: 2026-05-02 → 2026-05-10
4+
**Audit-Eligible State**: post-`v4.35.0`
5+
**Document Author**: tachi maintainers
6+
**Last Updated**: 2026-05-10
7+
8+
---
9+
10+
## Audience
11+
12+
This document serves three readers:
13+
14+
- **Adopter SecOps reviewer** evaluating tachi as a security-aware AI-coding harness for a managed environment.
15+
- **Procurement reviewer** requesting evidence of recent posture work for vendor due diligence.
16+
- **Future contributor** needing context on what was hardened in 2026Q2 and why.
17+
18+
Every claim below links to a public artifact (ADR, PR, file, or docs page) on this repository. No private context is required to validate any claim.
19+
20+
---
21+
22+
## Executive summary
23+
24+
Between 2026-05-02 and 2026-05-10, tachi shipped a five-feature enterprise hardening cycle that:
25+
26+
- **Closed 11 internal `/security` findings** against the substitution, config-loading, and disclosure surfaces (zero CRITICAL, three HIGH, four MEDIUM, three LOW, one INFO).
27+
- **Closed 3 external-community-review checklist items** named in a public 2026-05-02 review: private vulnerability disclosure channel, Claude Code permission baseline, and pre-commit secret-scanning.
28+
- **Released as `v4.28.0``v4.35.0`** across multiple `release-please` cycles (including one operational hot-fix at `v4.28.1`).
29+
30+
The cycle did not increase tachi's command surface and did not change its operational mode. All changes are posture-defensive: harder substitution semantics, stricter config parsing, a documented private disclosure channel, a self-contained Claude Code permission baseline, and an opt-in pre-commit secret-scanning hook.
31+
32+
Public Architecture Decision Records governing the cycle: **ADR-038**, **ADR-040**, **ADR-041**, **ADR-042**. (ADR-039 is operational test architecture, not part of the posture cycle.)
33+
34+
---
35+
36+
## Per-feature posture map
37+
38+
The cycle organized work into five sub-features (F-1 through F-5). Each row below is procurement-defensible: rationale, controls, and remediation are all in the public artifacts cited.
39+
40+
### F-1 — Substitution Surface Hardening
41+
42+
**ADR**: [ADR-038](../architecture/02_ADRs/ADR-038-placeholder-substitution-strategy.md)
43+
**Release**: `v4.28.0` (PR [#249](https://github.com/davidmatousek/tachi/pull/249))
44+
**Hot-fix follow-on**: `v4.28.1` (operational test-architecture stabilization, PR [#253](https://github.com/davidmatousek/tachi/pull/253))
45+
46+
**Posture change**: replaced `sed`-based substitution in [scripts/init.sh](../../scripts/init.sh) with a Bash-3.2-compatible string-replacement primitive. Eliminated the multi-hop execution chain pattern in which adversarially-crafted project paths could influence subsequent shell invocations. Tightened `PROJECT_PATH` validation, `read -p` input handling, personalization gitignore semantics, and constitution path migration.
47+
48+
**Adopter-visible change**: `scripts/init.sh` now refuses paths containing characters that would alter substitution semantics. No legitimate adopter path is rejected.
49+
50+
**Findings closed**: 5 (sed swap, `PROJECT_PATH` disposition, `read -p` validation, personalization gitignore, constitution sed migration).
51+
52+
---
53+
54+
### F-2 — Source-Pattern Hardening
55+
56+
**ADR**: [ADR-040](../architecture/02_ADRs/ADR-040-config-file-parsing-hardening.md)
57+
**Release**: bundled into the `v4.29.0`+ release cadence (PR [#257](https://github.com/davidmatousek/tachi/pull/257))
58+
59+
**Posture change**: introduced a canonical KV-load primitive `aod_template_load_kv_file` in [.aod/scripts/bash/template-config-load.sh](../../.aod/scripts/bash/template-config-load.sh). The primitive uses a read-buffer → strict-KV-regex → `printf -v` pattern, replacing four legacy `source` and `eval` call sites. New environment variable `AOD_FETCH_TIMEOUT` (default `60s`) bounds remote fetches. Adds a follow-on file-size cap and regular-file check on the KV loader.
60+
61+
**Adopter-visible change**: malformed or oversized config files now fail loudly at load time instead of silently injecting unintended shell semantics.
62+
63+
**Findings closed**: 5 (`defaults.env` source, `aod-kit-version` source, `eval` call, TOCTOU on config read, clone timeout).
64+
65+
---
66+
67+
### F-3 — SECURITY.md and Private Disclosure Channel
68+
69+
**Public docs**: [SECURITY.md](../../SECURITY.md), [README.md `## Community`](../../README.md)
70+
**Release**: `v4.33.0` (PR [#273](https://github.com/davidmatousek/tachi/pull/273))
71+
72+
**Posture change**: rewrote [SECURITY.md](../../SECURITY.md) to the GitHub-canonical five-section structure (Supported Versions / Reporting a Vulnerability / What to expect / Scope / Out-of-scope) and enabled GitHub **Private Vulnerability Reporting** on the repository. Researchers can now coordinate disclosure through the upstream GitHub flow without relying on email triage.
73+
74+
**Adopter-visible change**: a documented disclosure channel is in place. Verified continuously via the dedicated GitHub API endpoint.
75+
76+
**Findings closed**: 1 (`A05:2021 Security Misconfiguration` — missing private disclosure channel).
77+
78+
**Governance**: F-3 is a documentation-only change; per the project Constitution Principle VII §Exceptions, no automated test coverage was added. Verification is via post-merge `/security` re-scan + manual UI inspections.
79+
80+
---
81+
82+
### F-4 — Claude Code Permission Baseline
83+
84+
**ADR**: [ADR-041](../architecture/02_ADRs/ADR-041-claude-permissions-baseline.md)
85+
**Public docs**: [docs/standards/CLAUDE_PERMISSIONS.md](../standards/CLAUDE_PERMISSIONS.md)
86+
**Configuration**: [.claude/settings.json](../../.claude/settings.json)
87+
**Release**: `v4.34.0` (PR [#278](https://github.com/davidmatousek/tachi/pull/278))
88+
89+
**Posture change**: introduced a curated `~80 LOC` [.claude/settings.json](../../.claude/settings.json) baseline organized into four categories — read-only auto-approve, local-state auto-approve, destructive deny + ask, and network host-allowlist. The companion [CLAUDE_PERMISSIONS.md](../standards/CLAUDE_PERMISSIONS.md) is **self-contained** (`~250 LOC`): a SecOps reviewer can read it end-to-end and produce an audit report without reverse-engineering rule names or maintainer intent. Per-rule rationale is one-to-one cross-checked against `settings.json` via the AC-2 verification recipe (FR-002).
90+
91+
The baseline includes a 19-domain WebFetch host-allowlist spanning the GitHub, Anthropic, OWASP, MITRE, and NIST families, each domain motivated by a documented network dependency.
92+
93+
**Adopter-visible change**: SecOps-reviewed managed environments can ship the baseline as-is and audit it against this document. Three documented opt-out paths (per-tool CLI flag / fork-and-edit / managed-settings layer) cover legitimate override scenarios.
94+
95+
**Findings closed**: 0 vulnerability IDs (this is posture-gap closure, not vulnerability remediation), but addresses the second item on the public 2026-05-02 community review checklist.
96+
97+
**Calibration trade-offs** documented in CLAUDE_PERMISSIONS.md §Known-Limitations:
98+
- `Bash(rm -rf:*)` matches literal command-line strings; `bash -c 'rm -rf …'` does not match. Calibration: **deny rules are casual-typo, not adversarial**. Adversarial bypass surface is out-of-scope and addressed via PreToolUse hooks (defense-in-depth) per ADR-041.
99+
- Process wrappers (`npx`, `docker exec`, `devbox run`, `mise exec`, `direnv exec`) re-shell-out commands and similarly bypass the deny tier. Same calibration applies.
100+
- Subdomain matching is **not transitive** (Claude Code Issues [#15260](https://github.com/anthropics/claude-code/issues/15260), [#11972](https://github.com/anthropics/claude-code/issues/11972), [#1217](https://github.com/anthropics/claude-code/issues/1217)). The 19-domain explicit list is the correct posture given upstream behavior.
101+
102+
---
103+
104+
### F-5 — Pre-commit Secret-Scanning Defaults
105+
106+
**ADR**: [ADR-042](../architecture/02_ADRs/ADR-042-pre-commit-secret-scanning-default.md)
107+
**Public docs**: [docs/standards/PRECOMMIT_HOOKS.md](../standards/PRECOMMIT_HOOKS.md)
108+
**Configuration**: [.pre-commit-config.yaml](../../.pre-commit-config.yaml), [.gitleaks.toml](../../.gitleaks.toml)
109+
**CI parity**: [.github/workflows/gitleaks.yml](../../.github/workflows/gitleaks.yml)
110+
**Release**: `v4.35.0` (PR [#283](https://github.com/davidmatousek/tachi/pull/283))
111+
112+
**Posture change**: ships an opt-in pre-commit secret-scanning hook (gitleaks `v8.30.1` pinned). The hook runs through a stderr-augmenting wrapper at [.aod/scripts/bash/precommit-wrap.sh](../../.aod/scripts/bash/precommit-wrap.sh) that adds a four-item structured refusal contract (rule ID + file:line + bypass guidance + docs link). The CI parity workflow runs full-repo scans on PRs with binary-direct download and SHA256 verification — explicitly avoiding the proprietary gitleaks-action license trap. Both the local and CI variants emit SARIF for GitHub Code Scanning compatibility.
113+
114+
**Adopter-visible change**: at `init.sh` time, adopters are prompted (default Y in TTY contexts; skipped in non-TTY; flag overrides `--no-precommit` / `--precommit`) to install the pre-commit hook. Existing adopters can opt-in via `pre-commit install` after a `git pull`. There is no auto-install on `git pull`.
115+
116+
**Adopter extensibility**: the [.gitleaks.toml](../../.gitleaks.toml) configuration is tachi-tuned and can be extended by adopters. Two custom warn-only rules (`tachi-personalization-env`, `tachi-security-exceptions-jsonl`) document tachi-specific signal patterns.
117+
118+
**Findings closed**: 0 vulnerability IDs (posture-gap closure for the third community review item).
119+
120+
**Maintenance cadence**: each gitleaks minor release triggers a child Issue under follow-on-282 with empirical re-test against fixtures at [tests/fixtures/gitleaks-rule-interaction/](../../tests/fixtures/gitleaks-rule-interaction/).
121+
122+
---
123+
124+
## Adopter action checklist
125+
126+
If you are deploying tachi into a managed environment, the following checklist captures the procurement-defensible verifications you can run today:
127+
128+
- [ ] **Substitution surface**: read [scripts/init.sh](../../scripts/init.sh) and confirm the F-1 substitution primitive matches your shell-injection threat model. Run `bash scripts/init.sh --help` to see the supported invocation flags.
129+
- [ ] **Config loader**: read [.aod/scripts/bash/template-config-load.sh](../../.aod/scripts/bash/template-config-load.sh) for the F-2 KV-load primitive. Confirm `AOD_FETCH_TIMEOUT` default of `60s` matches your operational tolerance.
130+
- [ ] **Disclosure channel**: confirm the GitHub Private Vulnerability Reporting toggle is enabled on your fork via `gh api repos/<owner>/<fork>/private-vulnerability-reporting`. Expected response: `{"enabled":true}`.
131+
- [ ] **Claude Code permissions**: read [docs/standards/CLAUDE_PERMISSIONS.md](../standards/CLAUDE_PERMISSIONS.md) end-to-end and decide whether the baseline matches your audit-policy requirements. The four-category framing maps cleanly to typical SecOps review questions.
132+
- [ ] **Pre-commit secret-scanning**: from your fork, run `pre-commit install` and validate the hook fires on a deliberately-injected secret. Read [docs/standards/PRECOMMIT_HOOKS.md](../standards/PRECOMMIT_HOOKS.md) for the bypass contract.
133+
- [ ] **CI parity**: confirm `.github/workflows/gitleaks.yml` is in your fork and that PRs trigger the workflow. Verify SARIF artifacts upload to GitHub Code Scanning.
134+
- [ ] **Re-scan**: from a fresh clone of the cycle-closing tag (`v4.35.0`), run the project's `/security` scan and compare against the public ADR-cited baseline. Zero new findings expected on the F-1 → F-5 surfaces.
135+
136+
---
137+
138+
## Known limitations & calibration trade-offs
139+
140+
The cycle accepts the following calibration trade-offs explicitly, in line with each cited ADR's Decision section:
141+
142+
- **Adversarial bypass is out of scope.** Deny rules in F-4's permission baseline are calibrated against the casual-typo case. Adversarial bypass paths (`bash -c`, process wrappers) are documented and remediated via defense-in-depth (PreToolUse hooks) outside the F-4 surface.
143+
- **Subdomain matching is not transitive.** F-4's 19-domain WebFetch list is the correct posture given upstream Claude Code semantics. Compaction options are tracked separately and gated on upstream behavior change.
144+
- **Pre-commit hooks are opt-in.** F-5 does not auto-install on `git pull`. Adopters with airgapped or restricted-network developer environments can decline the hook without losing other tachi capabilities.
145+
- **The internal /security tool is logic-level.** F-1 through F-5 close logic-level findings; they do not replace SAST, SCA, or secrets-only scanners. tachi's complementary positioning is documented in [.claude/rules/scope.md](../../.claude/rules/scope.md).
146+
147+
---
148+
149+
## Out-of-scope (deferred to future cycles)
150+
151+
The following items were deliberately out of scope for the 2026Q2 cycle and are tracked separately:
152+
153+
- **Cryptographic signature verification of tachi releases.** Deferred pending procurement-driven trigger. Current SHA-pin tripwire in `.aod/aod-kit-version` is the documented sufficient defense against the actively-exploitable supply-chain threat surface. Sigstore / cosign / minisign infrastructure will be evaluated when an enterprise procurement signal warrants the multi-day investment.
154+
- **Adversarial bypass remediation.** PreToolUse hook scaffolding is the documented defense-in-depth path; F-4 is the calibration baseline, not the adversarial layer.
155+
- **Enterprise managed-settings.json packaging.** Rejected in ADR-041 §Alternatives-Considered #4 — tachi is a project-level open-source tool, and managed-settings packaging is an enterprise IT deployment artifact rather than an upstream concern.
156+
157+
---
158+
159+
## Re-assessment cadence
160+
161+
- **Every adopter `/aod.update` cycle**: re-read the §Built-in-Read-Only-Set maintenance note in [CLAUDE_PERMISSIONS.md](../standards/CLAUDE_PERMISSIONS.md) and verify against the latest Claude Code release.
162+
- **Every gitleaks minor release**: re-test against [tests/fixtures/gitleaks-rule-interaction/](../../tests/fixtures/gitleaks-rule-interaction/) before bumping the pin in [.pre-commit-config.yaml](../../.pre-commit-config.yaml). Cadence accountability is tracked under Issue [#287](https://github.com/davidmatousek/tachi/issues/287).
163+
- **Every quarter**: re-scan the F-1 → F-5 surfaces with the project's `/security` tool and confirm zero regression. The next quarterly review is documented in this folder as `SECURITY_POSTURE_<YYYY>Q<N>.md`.
164+
165+
---
166+
167+
## Cross-references
168+
169+
| Public artifact | Purpose |
170+
|---|---|
171+
| [SECURITY.md](../../SECURITY.md) | Disclosure channel + supported versions (F-3) |
172+
| [docs/standards/CLAUDE_PERMISSIONS.md](../standards/CLAUDE_PERMISSIONS.md) | Per-rule rationale + four-category framing (F-4) |
173+
| [docs/standards/PRECOMMIT_HOOKS.md](../standards/PRECOMMIT_HOOKS.md) | Operator handbook for the pre-commit hook (F-5) |
174+
| [docs/architecture/02_ADRs/ADR-038-…](../architecture/02_ADRs/) | F-1 substitution decision |
175+
| [docs/architecture/02_ADRs/ADR-040-…](../architecture/02_ADRs/) | F-2 config-parsing decision |
176+
| [docs/architecture/02_ADRs/ADR-041-…](../architecture/02_ADRs/) | F-4 permissions decision |
177+
| [docs/architecture/02_ADRs/ADR-042-…](../architecture/02_ADRs/) | F-5 secret-scanning decision |
178+
| [.claude/rules/scope.md](../../.claude/rules/scope.md) | tachi's complementary scanning-column positioning |
179+
| [CHANGELOG.md](../../CHANGELOG.md) | Release-level change history (`v4.28.0` through `v4.35.0`) |
180+
181+
---
182+
183+
*This document is an as-of-`v4.35.0` snapshot. Future cycle posture documents follow the same template and live in this folder. For questions about adopter validation or to coordinate a vendor security review, please open a GitHub Issue or use the private disclosure channel documented in [SECURITY.md](../../SECURITY.md).*

0 commit comments

Comments
 (0)