| <!-- SPDX-License-Identifier: Apache-2.0 |
| https://www.apache.org/licenses/LICENSE-2.0 --> |
| |
| <!-- START doctoc generated TOC please keep comment here to allow auto update --> |
| <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> |
| **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* |
| |
| - [Privacy-LLM setup](#privacy-llm-setup) |
| - [The two mechanisms recap](#the-two-mechanisms-recap) |
| - [Claude Code trust boundary](#claude-code-trust-boundary) |
| - [Variant 1 — Claude Code only (default)](#variant-1--claude-code-only-default) |
| - [Variant 2 — Local inference (Ollama)](#variant-2--local-inference-ollama) |
| - [Variant 3 — Local inference (vLLM)](#variant-3--local-inference-vllm) |
| - [Variant 4 — Apache-hosted endpoint](#variant-4--apache-hosted-endpoint) |
| - [Variant 5 — AWS Bedrock](#variant-5--aws-bedrock) |
| - [Variant 6 — Direct Anthropic API (opt-in)](#variant-6--direct-anthropic-api-opt-in) |
| - [Verifying the setup](#verifying-the-setup) |
| - [Updating after a framework version bump](#updating-after-a-framework-version-bump) |
| - [Status — provisional pending ASF Legal](#status--provisional-pending-asf-legal) |
| |
| <!-- END doctoc generated TOC please keep comment here to allow auto update --> |
| |
| <!-- SPDX-License-Identifier: Apache-2.0 |
| https://www.apache.org/legal/release-policy.html --> |
| |
| # Privacy-LLM setup |
| |
| How to configure the framework's privacy-aware LLM routing for |
| your adopting project. Pick a variant below; copy the matching |
| `<project-config>/privacy-llm.md` block into your project; verify |
| with `/magpie-setup-isolated-setup-verify` (or the privacy-llm-specific |
| check once PR-3 lands the gate-call wiring). |
| |
| The contract behind these recipes lives in |
| [`tools/privacy-llm/tool.md`](../../tools/privacy-llm/tool.md), |
| [`tools/privacy-llm/pii.md`](../../tools/privacy-llm/pii.md), and |
| [`tools/privacy-llm/models.md`](../../tools/privacy-llm/models.md). |
| This file is **how-to**; those are the **what** and **why**. |
| |
| ## The two mechanisms recap |
| |
| The framework treats two distinct privacy concerns separately: |
| |
| 1. **PII redaction** — applies to `<security-list>` content (the |
| reporter mail). The body is OK to flow through any approved |
| LLM. The reporter's own identity (name, email, etc.) flows |
| as-is — they sent the mail and are operationally known to the |
| security team. **What gets redacted** is PII the reporter |
| discloses about *other people* (third-party researchers, |
| victims, named individuals other than the reporter), replaced |
| with hash-prefixed identifiers (`N-a3f9d2`, …) before any LLM |
| step — *unless* the named individual is already a collaborator |
| on the `<tracker>` repo (their identity is already public/known |
| via collaborator status, no privacy gain from redacting). The |
| mapping is local to the user's machine. This applies under |
| **every** variant below — even Variant 1 (Claude-only). |
| 2. **Approved-LLM gate** — applies to `<private-list>` content |
| (PMC private mail) and any other private foundation lists. |
| The skill refuses to fetch unless every LLM in the active |
| stack is in the approved-model registry. |
| |
| Picking a variant below configures the **gate** (the LLM stack). |
| The redactor (mechanism 1) runs regardless and needs no |
| per-variant config beyond the home-dir storage path. |
| |
| ## Claude Code trust boundary |
| |
| The framework treats the Claude Code instance running the skills |
| as **default-approved**: a working position the maintainer chose |
| on 2026-05-04 in the absence of a ratified ASF Legal Affairs |
| list. This means: |
| |
| - A pure Claude-only deployment (Variant 1) needs no per-LLM |
| approval workflow — the gate is satisfied by construction. |
| - Adding **any** other LLM to the stack (a summarizer, a |
| delegated-analysis hop, an outbound classifier) requires |
| matching it against the registry per |
| [`tools/privacy-llm/models.md`](../../tools/privacy-llm/models.md). |
| - If ASF Legal subsequently rules that Anthropic-hosted endpoints |
| require a data-processing agreement for foundation private |
| data, the framework will narrow this default and bump the |
| registry version. Adopters using Variant 1 at that point will |
| need to re-evaluate. |
| |
| ## Variant 1 — Claude Code only (default) |
| |
| The simplest variant. Claude Code is the only LLM in the stack; |
| no external endpoints; the gate is auto-satisfied. |
| |
| **`<project-config>/privacy-llm.md`** content (copy verbatim, |
| substitute `<private-list>` for your project's actual list): |
| |
| ```markdown |
| ## Currently configured LLM stack |
| |
| - Claude Code (the agent running framework skills) |
| |
| ## Approved third-party endpoints (opt-in) |
| |
| (none — Claude Code is the only LLM) |
| |
| ## Private mailing lists for this project |
| |
| - private@<project>.apache.org |
| ``` |
| |
| **Setup steps:** |
| |
| 1. Place the file at `<project-config>/privacy-llm.md` in your |
| adopter repo (alongside `project.md`). |
| 2. Commit it. The file is project-config — it travels with the |
| repo, not per-machine. |
| 3. Run `/magpie-setup-isolated-setup-verify` to confirm the existing |
| secure-agent setup is in place — no new secure-setup steps |
| are needed for Variant 1. |
| |
| That is the entire variant. Every framework skill that consults |
| `<project-config>/privacy-llm.md` will see "Claude-only" and pass |
| the gate. |
| |
| ## Variant 2 — Local inference (Ollama) |
| |
| Use when the project wants a second LLM in the stack — typically |
| for delegated summarisation of long mail threads — without |
| sending data to any external service. |
| |
| **Prerequisites:** |
| |
| - [Ollama](https://ollama.ai) installed locally (`brew install |
| ollama` on macOS; per-distribution package on Linux). |
| - A model pulled (`ollama pull llama3.1:8b` or similar — the |
| framework does not prescribe which model). |
| - Ollama bound to `127.0.0.1` only (the default; do not expose to |
| external interfaces). |
| |
| **`<project-config>/privacy-llm.md`** content: |
| |
| ```markdown |
| ## Currently configured LLM stack |
| |
| - Claude Code (the agent running framework skills) |
| - Local Ollama at http://127.0.0.1:11434/ (model: llama3.1:8b) |
| |
| ## Approved third-party endpoints (opt-in) |
| |
| (none — local Ollama is local-only inference, default-approved) |
| |
| ## Private mailing lists for this project |
| |
| - private@<project>.apache.org |
| ``` |
| |
| **Setup steps:** |
| |
| 1. Confirm Ollama is reachable: `curl |
| http://127.0.0.1:11434/api/tags` returns the model list. |
| 2. Confirm Ollama is **not** reachable from outside the host: |
| `curl http://<your-LAN-IP>:11434/api/tags` should fail. |
| 3. Place the file at `<project-config>/privacy-llm.md`. Commit. |
| 4. The framework helper detects `127.0.0.1` (and `localhost`, |
| `::1`) hostnames as default-approved local inference; no |
| third-party-endpoint declaration is needed. |
| |
| ## Variant 3 — Local inference (vLLM) |
| |
| Same shape as Ollama but targeting vLLM for projects that need a |
| larger model than Ollama hosts comfortably or need OpenAI-API |
| compatibility for downstream tooling. |
| |
| **`<project-config>/privacy-llm.md`** content: |
| |
| ```markdown |
| ## Currently configured LLM stack |
| |
| - Claude Code (the agent running framework skills) |
| - Local vLLM at http://127.0.0.1:8000/v1/ (model: meta-llama/Llama-3.1-70B-Instruct) |
| |
| ## Approved third-party endpoints (opt-in) |
| |
| (none — local vLLM is local-only inference, default-approved) |
| |
| ## Private mailing lists for this project |
| |
| - private@<project>.apache.org |
| ``` |
| |
| Same `127.0.0.1`-or-`localhost` test as Ollama applies. |
| |
| ## Variant 4 — Apache-hosted endpoint |
| |
| Use when the ASF (or your project's PMC) hosts an inference |
| endpoint at an `*.apache.org` domain. These are |
| **default-approved** — anything served from an `*.apache.org` |
| hostname runs on infra under ASF governance. |
| |
| **`<project-config>/privacy-llm.md`** content (substitute the |
| actual endpoint): |
| |
| ```markdown |
| ## Currently configured LLM stack |
| |
| - Claude Code (the agent running framework skills) |
| - ASF inference at https://inference.apache.org/v1/ (model: llama3.1-asf) |
| |
| ## Approved third-party endpoints (opt-in) |
| |
| (none — *.apache.org endpoints are default-approved) |
| |
| ## Private mailing lists for this project |
| |
| - private@<project>.apache.org |
| ``` |
| |
| **Setup steps:** |
| |
| 1. Confirm the endpoint resolves under `*.apache.org`. The |
| framework helper greps the URL host suffix; `apache.org` is |
| the trigger. |
| 2. Confirm authentication if the endpoint requires it. ASF |
| endpoints typically authenticate via the user's ASF identity |
| (LDAP / OAuth); credentials live at |
| `~/.config/apache-magpie/<endpoint>-token.json` or similar |
| — never in the project tree |
| (see [`AGENTS.md` — Local setup](../../AGENTS.md#local-setup)). |
| 3. Place the file at `<project-config>/privacy-llm.md`. Commit. |
| |
| ## Variant 5 — AWS Bedrock |
| |
| **Opt-in.** AWS Bedrock with a region-bounded endpoint is a |
| common choice for projects whose contributors are split across |
| organisations and need a managed-inference fallback. The opt-in |
| mechanism reflects that the data-residency contract is |
| Bedrock-specific (region pinning, no-training, IAM-bounded |
| access) and the adopter's security team is responsible for |
| verifying it matches ASF expectations for foundation private |
| data. |
| |
| **Prerequisites:** |
| |
| - An AWS account the adopter's security team controls. |
| - Bedrock **enabled in a region you've verified for data |
| residency** (typically a region inside the EU or a region with |
| a Bedrock data-processing addendum that covers foundation |
| private data). |
| - The model the project uses **enabled in that region** (Bedrock |
| requires per-region model enablement). |
| - An IAM identity for the framework with |
| `bedrock:InvokeModel` (and nothing else) on the specific |
| model ARN. |
| - The IAM credentials at `~/.aws/credentials` (default AWS SDK |
| path; never in the project tree). |
| |
| **`<project-config>/privacy-llm.md`** content: |
| |
| ```markdown |
| ## Currently configured LLM stack |
| |
| - Claude Code (the agent running framework skills) |
| - AWS Bedrock at https://bedrock-runtime.eu-central-1.amazonaws.com |
| (model: anthropic.claude-3-5-sonnet-20241022-v2:0) |
| |
| ## Approved third-party endpoints (opt-in) |
| |
| - AWS Bedrock — eu-central-1 |
| - Data-residency contract: AWS DPA + Bedrock no-training default |
| (https://aws.amazon.com/service-terms/, section 50.4 last |
| reviewed YYYY-MM-DD) |
| - IAM principal: arn:aws:iam::<account>:role/<project>-bedrock-readonly |
| - Approved-by: <PMC-member-initials> <YYYY-MM-DD> |
| |
| ## Private mailing lists for this project |
| |
| - private@<project>.apache.org |
| ``` |
| |
| **Setup steps:** |
| |
| 1. Verify the region's data-residency contract matches your |
| project's expectations for foundation private data. Document |
| the link in the *Data-residency contract* line above. |
| 2. Verify Bedrock has *Model invocation logging* **disabled** (or |
| that any logging destination is inside the same compliance |
| boundary). The default is disabled. |
| 3. Provision the IAM role; place credentials at |
| `~/.aws/credentials`. |
| 4. Place the file at `<project-config>/privacy-llm.md` with the |
| *Approved-by* line filled in by a PMC member of the security |
| team. Commit. |
| |
| ## Variant 6 — Direct Anthropic API (opt-in) |
| |
| **Opt-in.** Direct calls to the Anthropic API outside of Claude |
| Code (e.g. for a delegated-summarisation hop) require a contract |
| covering data-processing for ASF private data — typically a |
| zero-data-retention agreement plus a no-training clause. |
| |
| **Prerequisites:** |
| |
| - An Anthropic account with a zero-data-retention agreement |
| applied to the API key. |
| - The API key at `~/.config/apache-magpie/anthropic-api.json` |
| or via `$ANTHROPIC_API_KEY` set from a home-dir-sourced |
| shell-rc — never in the project tree. |
| |
| **`<project-config>/privacy-llm.md`** content: |
| |
| ```markdown |
| ## Currently configured LLM stack |
| |
| - Claude Code (the agent running framework skills) |
| - Direct Anthropic API at https://api.anthropic.com/v1/ |
| (model: claude-3-5-sonnet-20241022) |
| |
| ## Approved third-party endpoints (opt-in) |
| |
| - Anthropic API direct |
| - Data-residency contract: ZDR + no-training agreement applied |
| to API key xxxxxx-… (Anthropic console → Privacy → ZDR |
| confirmed YYYY-MM-DD) |
| - Approved-by: <PMC-member-initials> <YYYY-MM-DD> |
| |
| ## Private mailing lists for this project |
| |
| - private@<project>.apache.org |
| ``` |
| |
| The *Approved-by* line is required because Direct-Anthropic is |
| opt-in. A `<project-config>/privacy-llm.md` that lists this |
| endpoint without the *Approved-by* line will be flagged by the |
| gate as incomplete. |
| |
| ## Verifying the setup |
| |
| Once `<project-config>/privacy-llm.md` is in place: |
| |
| 1. Run `/magpie-setup-isolated-setup-verify` to confirm the underlying |
| secure-agent setup is unchanged. |
| 2. (PR-3) Run the privacy-llm-specific check: |
| |
| ```bash |
| uv run --project <framework>/tools/privacy-llm/redactor \ |
| privacy-llm-check --reads-private-list |
| ``` |
| |
| Returns exit code 0 if the active stack is fully approved. |
| 3. Sanity-check the redactor end-to-end. The third party in this |
| example is `Other Researcher` (someone the reporter mentions |
| in their report; the reporter's own name would NOT be passed |
| to `--field`): |
| |
| ```bash |
| echo "I worked with Other Researcher (other@example.com) on this finding" | \ |
| uv run --project <framework>/tools/privacy-llm/redactor \ |
| pii-redact \ |
| --field name:"Other Researcher" \ |
| --field email:"other@example.com" |
| ``` |
| |
| Output should replace the two values with `N-…` and `E-…` |
| identifiers. |
| 4. List the resulting map: |
| |
| ```bash |
| uv run --project <framework>/tools/privacy-llm/redactor pii-list |
| ``` |
| |
| ## Updating after a framework version bump |
| |
| The registry of default-approved entries can change between |
| framework versions (e.g. ASF Legal ratifies a list, or a previously- |
| default-approved class is narrowed). After running |
| `/magpie-setup upgrade`, re-run the verification checks above. If |
| an entry that was previously default-approved is now opt-in, the |
| gate will surface the gap and the adopter follows the recipe for |
| the matching variant above. |
| |
| ## Status — provisional pending ASF Legal |
| |
| This document and the registry it points at are **provisional**: |
| they reflect the framework maintainer's current working position |
| in the absence of a ratified ASF Legal Affairs / Privacy policy |
| for AI-assisted handling of foundation private data. When such a |
| policy lands, the registry will be updated to point at it as |
| source-of-truth, and the variants above will be re-checked |
| against it. |
| |
| If you are a PMC member or ASF Legal Affairs reviewer reading |
| this and want to formalise the list: open an issue on |
| [`apache/magpie`](https://github.com/apache/magpie) |
| referencing this file. The framework will track ratification as |
| a project memory and bump the registry version once the ratified |
| list lands. |