--- since: 1.0.0 --- # astwire โ€” Security and Privacy astwire is designed around a **fully local execution model**. Target resolution, AST parsing, skeletonization, waste analysis, redaction, partitioning, and formatting all happen on the machine running the binary. astwire makes no network requests of its own โ€” the only external boundary is what you do with the output file afterward (for example, pasting it into a hosted LLM chat). ## Security and Privacy Architecture ```mermaid flowchart TD A["๐Ÿ” Local Codebase"] A --> B["๐ŸŽฏ Target Resolution
.gitignore / .astwireignore / skip patterns"] B --> C["๐Ÿ“– Read file content
local disk only"] C --> D["๐Ÿ›ก๏ธ Transform Pipeline
skeleton โ†’ strip-waste"] D --> E["๐Ÿ”’ Secret Redaction
always applied, before output"] E --> F{"Redaction pattern match?"} F -->|Yes| G["[REDACTED:SECRET]
replaces the matched span"] F -->|No| H["Content passes through unchanged"] G --> I["๐Ÿ“ฆ FileRecord
local in-memory"] H --> I I --> J["โœ‚๏ธ Partition + Format"] J --> K["๐Ÿ’พ Local Output File(s)
context.md / .xml / .json"] K --> L{"What do you do
with the output?"} L -->|"Paste into a hosted LLM"| M["โš ๏ธ Third-party provider boundary
outside astwire's control"] L -->|"Keep local / commit to a private repo"| N["โœ… Stays on this machine"] O["๐Ÿšซ astwire never does"] O -.-> P["Execute the analyzed code"] O -.-> Q["Make network requests"] O -.-> R["Upload source to any service"] O -.-> S["Write telemetry / usage logs"] classDef sensitive fill:#fff0f0,stroke:#d64545,stroke-width:2px,color:#5c2020 classDef security fill:#fff4df,stroke:#d59a2a,stroke-width:2px,color:#5c420b classDef local fill:#e8f7f1,stroke:#2b9a78,stroke-width:2px,color:#174d3d classDef external fill:#eeeaff,stroke:#7957c7,stroke-width:2px,color:#382568 classDef safe fill:#e8f1ff,stroke:#4a78c2,stroke-width:2px,color:#172b4d classDef never fill:#f5f3ed,stroke:#777777,stroke-width:1px,color:#444444 class A sensitive class B,C,D,E,F security class G,H,I,J,K,N local class M external class L safe class O,P,Q,R,S never ``` ## 1. Local Execution Guarantee Every stage in the pipeline โ€” target resolution, `ast.parse()`, skeleton transformation, whitespace cleansing, secret redaction, tokenization, partitioning, and formatting โ€” runs as pure local computation: - astwire performs static analysis via Python's standard-library `ast` module. It **never executes, imports, or evaluates** the code it analyzes. - astwire makes **no outbound network calls**. There is no telemetry, no update check, and no usage reporting built into the CLI itself. - Output is written only to the local filesystem, at the path given by `-o`/`--output` (default `context.xml`). The only way code content leaves the local machine is if *you* take the generated output file and paste, upload, or otherwise transmit it somewhere โ€” for example, into a hosted LLM's chat interface. That transmission is outside astwire's control and is governed by whatever service receives it. ## 2. Secret Redaction `redact_secrets()` (`redact.py`) runs unconditionally on every file's content โ€” it is **not** gated behind a flag, unlike `--skeleton` or `--strip-waste`. It matches four regex patterns, in this order: | Pattern name | Matches | | --- | --- | | AWS Key | `aws_access_key_id = "..."` with a 20-character uppercase/digit value | | Generic API Key | `(api_key\|api-key\|secret\|token\|password) [:=] "..."` with a 16+ character alphanumeric/`_`/`-` value | | Bearer Token | `Bearer <20+ char token>` (case-insensitive) | | Private Key Block | `-----BEGIN ... PRIVATE KEY-----` header lines | Every match is replaced with the literal string `[REDACTED:SECRET]`. > **Important โ€” this is best-effort redaction, not a complete secret scanner.** The generic pattern requires a recognizable key name (`api_key`, `secret`, `token`, `password`) immediately followed by `:`/`=` and a quoted value of at least 16 characters. A credential under a different variable name, split across lines, base64-encoded, or embedded in a data structure the regex doesn't match will pass through unredacted. Review generated output before sharing it with a third party, especially for code that legitimately handles credentials. Redaction happens **after** skeletonization and waste-stripping but is applied to the content as it exists at write time โ€” so a secret embedded inside a function body that gets skeletonized away by `--skeleton` never reaches the redaction step at all (it simply isn't in the output). ## 3. Gitignore and Ignore-File Compliance Target resolution honors nested `.gitignore` and `.astwireignore` files via `IgnoreEngine` (`gitignore.py`), using [`pathspec`](https://github.com/cpburnz/python-pathspec)'s `gitignore`-syntax matcher. This means files your project already excludes from version control (`.env`, `node_modules/`, build artifacts, etc.) are excluded from astwire's output by default, without additional configuration. **This now holds for `-i`/`--resolve-imports` too.** Per SPEC-1.0.md ยง5 ("Skip/ignore win over `-i`"), `expand_local_imports()` (`discover.py`) checks every resolved import target against the same `IgnoreEngine` and `targeting.skip` patterns used for plain target walks (`is_excluded(..., for_import=True)`), in addition to its own hard-deny on vendor-style dirnames (`node_modules/`, `vendor/`, `.venv/`, etc.). A file reachable only through an import is *not* bundled if `.gitignore`/`.astwireignore`/`skip` would have excluded it โ€” skip/ignore rules win over the import graph, not the other way around. ## 4. Git Subprocess Calls (`--since`) `--since` (`git_changes.py`) shells out to the system `git` binary (`subprocess.run`) to resolve the repository root, verify the given ref, and list changed/untracked files โ€” it does not use a bundled git implementation or make any network call itself. All of this stays local: `git diff`/`git ls-files` read the local working tree and object database only. As with the rest of astwire, no network request is made by this path unless your local `git` config itself is set up to do so (e.g. a ref that requires a prior `fetch` to exist โ€” astwire never runs `fetch` or contacts a remote). This module is deliberately narrow and does not call any AI/LLM API, does not cache results or write markers between runs (every invocation re-derives its answer from `git`), and never resolves a remote or base branch on your behalf โ€” `REF` is always exactly what you passed on the command line. Unlike the rest of astwire's pipeline, `--since`'s own seed list *is* gitignore-aware (it explicitly excludes paths `git` itself reports as ignored) โ€” consistent with the rest of the pipeline now that `-i` import-expansion is gitignore-aware too (Section 3). ## 5. Configuration File Trust `.astwire.toml` is discovered by walking upward from the resolution root (see [`astwire-architecture.md`](astwire-architecture.md)) and parsed with `tomllib`/`tomli`. It is a plain data file โ€” it cannot contain executable code, and a malformed or unreadable config file causes `load_config()` to silently fall back to defaults rather than raising. ## 6. Uninstallation Data Handling `astwire --uninstall` removes the installed binary and local configuration files it created: `.astwire.toml` and `.astwireignore` in the current directory, plus `.astwire.toml` under `$HOME` (`perform_uninstall()` does not currently remove a `$HOME/.astwireignore`, since astwire itself never writes one there). No data is transmitted anywhere as part of uninstallation. On Windows, the uninstall step is scheduled as a detached PowerShell process (since the running binary cannot delete its own locked executable file); this is a local process-spawn, not a network operation. ## 7. Security Recommendations 1. Review generated `context.md` / `.xml` / `.json` output before pasting it into a hosted LLM, especially for proprietary or regulated code. 2. Don't rely on `redact_secrets()` as your only line of defense โ€” combine it with `.gitignore`/`.astwireignore` exclusions for files that should never be read in the first place. 3. Prefer `--skeleton` mode when you only need interface shape (signatures, types, docstrings) rather than full implementation bodies โ€” it inherently reduces the amount of code content, including any secrets embedded in function bodies, that reaches the output. 4. `-i`/`--resolve-imports` respects `.gitignore`/`.astwireignore`/`skip` the same way plain target resolution does โ€” skip/ignore rules win over the import graph. If you need a file excluded from import-graph traversal specifically, add it to `.astwireignore` or `targeting.skip` in `.astwire.toml`. 5. Treat the `installers/` binaries and `.astwire.toml` the same way you'd treat any other local build artifact or config file with respect to your organization's source-control and secret-scanning policies.