GitHub Copilot study materials
GitHub Copilot study resources

Content Exclusion That Did Not Cover Nested Files

GitHub Copilot · Put your knowledge to work in context.

All case studies

Content Exclusion That Did Not Cover Nested Files

Northwind Health has 800 GitHub Copilot Enterprise seats and a strict policy that protected health information must never reach Copilot. Two weeks ago the security team added an enterprise-level content exclusion for the billing-service repository using the pattern billing-service/*. Yesterday a developer opened src/Invoices/InvoiceCalculator.cs from that repository in VS Code, selected the method that throws on a null patient ID, and asked Copilot Chat to explain the failure. The answer quoted the selected lines and suggested a guard clause. The developer saved the chat transcript and reported a policy breach. The security team says the repository is excluded and wants to know why Copilot still saw the file. They also want a fix they can validate before the next audit, without putting real patient data into a test repository. The developer is on the latest VS Code extension, authenticated through the enterprise, and working in a normal clone, not a fork.

1. The exclusion exists but Chat used the file. Rank the likely causes and the evidence you would collect for each before changing anything.

Read the worked answer

Rank causes by likelihood and collect evidence before changing the policy.

  1. Pattern scope (most likely). billing-service/* matches only direct children of the repository root. src/Invoices/InvoiceCalculator.cs is nested, so it is not excluded. Evidence: the exact pattern, the repo-relative path, and a canary test with a dummy file at root and one under src/. GitHub exclusion patterns use gitignore-style semantics; * does not cross /, while ** does.

  2. Propagation or session state. Policy changes can take time to reach clients, and an already-open IDE session may not reflect them immediately. Evidence: change timestamp, extension version, whether the developer reloaded the window, and a retest after the documented propagation window.

  3. Repository identity. Exclusions attach to repositories, not local folders. A fork, mirror, or transferred repo can have a different full name. Setup says normal clone, so this is lower priority, but verify the remote URL and repo full name.

  4. Context bypass. If the developer pasted the code or attached a non-excluded file, exclusion cannot help. Evidence: the transcript, the exact #file or selection used, and whether code was pasted.

The key reasoning: an exclusion is a policy match against repository and path; it is not a property of the developer's editor or of the file contents.

2. Rewrite the exclusion so nested files are covered, and describe a validation plan that does not use real patient data.

Read the worked answer

Use a repository-scoped pattern that covers nested paths, then validate with synthetic data.

For a repository-level exclusion, change billing-service/* to billing-service/** so all nested files are covered. If the policy is applied at the organization or enterprise level, confirm the pattern is attached to the correct repository and use the equivalent recursive pattern supported by that scope. Do not broaden to **/* unless the intent is to exclude everything; broad patterns are hard to audit.

Validation plan:

  • Create a private canary repository with a fake file at the root and a nested file, both containing a unique marker such as CANARY_PHI_12345 and no real data.
  • Apply the candidate pattern, wait for propagation, reload the IDE, and ask Copilot Chat to summarize each file by explicit #file reference.
  • Expected result: Copilot refuses or does not use the file; the editor shows the exclusion state. Also test a non-excluded file in the same repo to confirm Chat still works.
  • Record the test, timestamp, pattern, and result for the audit. Re-test after any policy change.

Do not validate by pasting real PHI; pasted content can still be processed even when the file is excluded.

3. What residual risk remains even after the pattern is fixed, and what control would you add?

Read the worked answer

Residual risk: exclusion is a guardrail, not a DLP boundary.

It cannot stop a developer from copying excluded code into Chat, a commit message, an issue, or another tool. It also does not cover content that arrives through other context, such as pasted snippets or files outside the excluded path. Propagation delays and pattern mistakes create windows of exposure. Finally, exclusion does not remove code already present in a local clone, build logs, or test fixtures.

Add controls in layers:

  • Prevent exfiltration at the endpoint: block paste into Copilot Chat for high-risk repos where the client supports it, or disable Copilot for that repository/team.
  • Detect: secret scanning, code scanning, and DLP on developer endpoints; monitor audit logs for policy changes and unusual Copilot enablement.
  • Govern: require a second approval for content-exclusion changes, document pattern tests, and review exclusions quarterly.
  • Train: tell developers that exclusion does not make pasted data safe and that Chat transcripts may be retained under the applicable plan.

The audit answer should say: the specific incident was caused by a non-recursive pattern; the fix is recursive; and the compensating controls are DLP, monitoring, and change control.