GDPR and AI-Generated Code: What Data Leaves the Machine?

GDPR Article 25 requires privacy by design. BrassCoders's --offline flag delivers it: zero bytes leave the machine during an OSS scan. Here's how that maps to your GDPR obligations.

Copper Sun Brass Team · · 8 min read
securitycomplianceoss-core

GDPR Article 25 requires privacy by design — not compliance bolted on after the fact, but technical measures baked into systems at design time. Most of that obligation falls on the software you write. A smaller but real question applies to the tools you use to write it. When an AI-assisted development tool analyzes your codebase, what data flows where, and what does that mean for your Article 25 obligations?

BrassCoders was built around a direct answer. The --offline flag makes zero-data-egress the default scan mode. No bytes leave the machine. No data processor relationship is established. The GDPR data-transfer analysis becomes moot.

This post maps BrassCoders’s data handling to specific GDPR obligations. It doesn’t cover the full data inventory — that’s documented at What BrassCoders Sends to Its Servers and What Leaves Your Machine When an LLM Reviews Your Code. This post covers the GDPR-specific framing.

GDPR Article 25: Privacy by Design for Code

BrassCoders’s --offline flag is a direct implementation of GDPR Article 25’s data minimization and default-protective-settings requirements: the scan collects zero data for external transmission because it transmits nothing at all. Article 25 of the General Data Protection Regulation requires controllers to implement appropriate technical and organizational measures — at the time of design, not after deployment — so that, by default, only personal data necessary for each specific purpose is processed. Applied to development tooling, this means the default scan mode should minimize data egress. It should not expand it.

The standard model for AI code review tools runs in the opposite direction. The tool sends your code to an external API, where it is processed on infrastructure you don’t control. That design choice creates obligations: you need a data processing agreement with the tool vendor, an Article 46 transfer mechanism if the vendor processes data outside the EU, and documentation of the transfer in your Records of Processing Activities. The full Article 25 text is on EUR-Lex if you want the regulatory language verbatim. Most teams make those commitments implicitly, because the developer typed a diff into a browser tab and no one reviewed what was being consented to.

BrassCoders’s offline default eliminates those obligations entirely for OSS-core scans. No data transfers means no processor relationship, no Article 46 analysis, no DPA required.

The Offline Scan: No Data Processing Question

BrassCoders in --offline mode makes zero outbound network calls. The Apache 2.0-licensed OSS core reads files from your project root, runs 12 scanners locally, and writes YAML findings to .brass/ — all without a single byte leaving the machine. This is verifiable in source and auditable at runtime with a network capture tool.

The 12 scanners are local processes bundled with BrassCoders: Bandit and Pylint for Python static analysis, Pyre/Pysa (Meta’s taint analyzer) for interprocedural taint flows, Semgrep and ast-grep for pattern matching, and detect-secrets (Yelp’s entropy-based credential scanner) for secret discovery. Six additional custom scanners cover AI-pattern detection, privacy and PII matching, secret patterns, performance hints, content moderation, and JavaScript/TypeScript analysis.

None of those scanners make network calls during analysis. BrassCoders adds no network layer on top of them.

From a GDPR standpoint, this is the cleanest possible outcome. No controller-processor relationship to document, no cross-border transfer to authorize, no Article 30 Records of Processing Activities entry to write. The scan runs with the same compliance footprint as running grep locally. GDPR’s data-transfer rules have nothing to attach to.

Pass --offline explicitly to any scan:

brasscoders --offline scan /path/to/project

The Paid Plan: What Leaves the Machine and What Doesn’t

BrassCoders Paid sends a tightly scoped payload to our gateway — never raw source code. Two payloads travel per scan: already-redacted scanner findings and a short project signature of at most 7,500 characters derived from your README, manifest, entrypoint, and top-level filenames.

The findings payload has already been redacted before transmission. Two enforcement layers run at the source. The privacy scanner masks matched values before the finding is returned: a credit card number becomes 4111****1111, and the code snippet is cleared. The YAML writer then strips known privacy-sensitive metadata keys (matched_text, code_snippet, context_line, raw_match, context) from any privacy-type finding before serialization. For secrets, the scanner records only the secret type and a short hash for deduplication; the secret value is never written to any BrassCoders-owned object. For sensitive finding types (SECURITY, PRIVACY, SECRET, CREDENTIAL, PII), the transmitted representation includes only file path, line number, type, and scrubbed title — description and snippet fields are excluded as defense in depth.

The project signature is not source code. It’s a bounded text string built from four sources: the first 5,000 characters of your README, the first 2,000 characters of your manifest, the first 3,000 characters of your entrypoint, and the names (not contents) of files in your project root. Total cap: 7,500 characters.

What does this mean for GDPR? Whether the Paid plan payload constitutes personal data processing depends on whether your findings contain personal data after redaction. For most codebases, the redacted findings are security and code-quality metadata about code structure — not personal data. For teams whose code processes EU personal data extensively, it’s worth reviewing the full field inventory before activating the Paid plan.

One disclosure worth stating directly: a GDPR-compliant Data Processing Agreement has not yet been drafted. If your compliance process requires a signed DPA before using the Paid plan, the right answer for now is to run --offline and contact brass@coppersuncreative.com. The DPA gap is real; we’re not pretending otherwise.

AI-Generated Code and Personal Data Patterns

BrassCoders’s privacy scanner detects personal data patterns written into code — the kind AI assistants generate without flagging. This is the Article 25 application most relevant to teams building with AI assistance.

AI coding assistants generate code that processes data. They write database queries, API handlers, form processors, and logging functions. Left unreviewed, that generated code can bake in privacy violations: logging fields that contain email addresses or IPs without consent basis, storing data longer than stated in a privacy policy, transmitting personal data to third-party APIs without disclosure. These patterns don’t violate GDPR at the code level in isolation — GDPR applies to processing, not code. But the code implements the processing, and if the code is wrong, the processing is wrong.

BrassCoders’s privacy scanner runs locally, reads the code your AI assistant wrote, and flags the patterns. It detects PII-handling code — email-field assignments, IP logging, identifier storage — and surfaces them as findings in .brass/privacy_analysis.yaml. The YAML lands in your project root. Your AI assistant (Claude Code, Cursor, or whichever you’re using) reads it at context load and can triage each finding before you commit.

The division of labor matters. BrassCoders reports the raw pattern: a function at line 47 logs the user_email field. The AI assistant triages the context: it checks whether the service is transactional, whether the log is internal-only, whether the retention period matches the privacy policy. BrassCoders doesn’t infer context. The AI assistant does. That split is intentional.

A Practical GDPR Checklist for AI-Assisted Teams

BrassCoders gives European development teams a concrete starting point for Article 25 compliance in their AI-assisted workflow. The checklist below maps BrassCoders capabilities to GDPR obligations — it’s not legal advice, and your DPO should review it, but it’s a working framework.

For every project that processes EU personal data:

Run brasscoders --offline scan in your CI pipeline on every pull request. No data leaves the machine. No DPA required. The privacy scanner flags PII-handling patterns in generated code before they reach production.

Review .brass/privacy_analysis.yaml in your pre-merge gate. Each finding names the file, line, and pattern type. Your AI assistant can triage them against your data processing register. Each flagged pattern should have a documented legal basis and a retention limit.

For the Paid plan: read the full data inventory at What BrassCoders Sends to Its Servers and assess whether the Paid plan payload constitutes personal data under your organization’s classification. For most codebases, the redacted findings are code-structure metadata, not personal data. If uncertain, use --offline.

Document the tool in your Article 30 Records of Processing Activities. In offline mode, BrassCoders is a local analysis tool with no data transfers to record — the entry is minimal. In Paid mode, the gateway is a sub-processor and the data flow should be documented.

One gap to track: data residency. The BrassCoders gateway currently runs on US-East infrastructure via Vercel. There is no EU-region option yet. If your data residency requirements prohibit US-East processing, --offline is the answer for now. Region pinning is on the roadmap.

The short version: brasscoders --offline scan is the GDPR-compatible default. Zero bytes off the machine means no data processor relationship, no Article 46 analysis, no DPA required. Install it and run it on every commit.

pip install brasscoders
brasscoders --offline scan /path/to/project

BrassCoders is free, Apache 2.0 licensed, and available on PyPI as brasscoders. The Paid plan at $12/month adds AI-powered enrichment with the tightly scoped payload described above. Cancel any time via brasscoders portal.

Frequently Asked Questions

Does BrassCoders process personal data?

It depends on the scan mode. With --offline (the OSS core default), zero bytes leave your machine — no data processor relationship is established, and GDPR's data-transfer obligations simply don't apply. The BrassCoders Paid plan sends already-redacted scanner findings plus a short project signature to our gateway; whether that constitutes personal data processing depends on whether your findings contain personal data after redaction. See the full data inventory at coppersun.dev/blog/what-brass-sends-to-its-servers/ for field-by-field detail.

Is brasscoders --offline GDPR compliant?

Zero bytes leave the machine in --offline mode. No data is transmitted, no sub-processor relationship is established, and no Article 46 transfer mechanism is required. The scan behaves the same as running flake8 locally: it reads files from your project root, writes YAML findings to .brass/ inside that root, and exits. GDPR's data-transfer rules have nothing to attach to.

Does the BrassCoders Paid plan require a Data Processing Agreement?

Potentially, yes — and we're being direct about the current state. A GDPR-compliant DPA template has not yet been drafted. If your compliance process requires a DPA before using the Paid plan, run --offline in the interim and contact brass@coppersuncreative.com. The full inventory of what the Paid plan transmits is documented at coppersun.dev/blog/what-brass-sends-to-its-servers/.

What is GDPR Article 25?

Article 25 of the General Data Protection Regulation (GDPR) requires controllers to implement data protection by design and by default — building privacy into systems from the start rather than adding it later. In practice this means: collect only what you need (data minimization), default settings must be the most protective option, and technical measures must be baked in at design time. For development tooling, it applies when the code being scanned processes EU personal data.

Should I use --offline if my code processes EU personal data?

Yes, if you have any uncertainty about your GDPR posture. With --offline, BrassCoders reads and analyzes your project entirely on your machine. No findings leave. No project metadata leaves. The compliance question collapses: there's no data processing by BrassCoders in the GDPR sense because there's no data transfer at all. Run brasscoders --offline scan /path/to/project.