Incident report

Exposure of source code on a public repository

[owner/repo]

TLP:AMBER+STRICT
Incident ID[incident ID]
Severity[SEV-1 to SEV-4]
Status[Open / Contained / Closed]
Version0.1 draft
Report date[date]
Prepared by[name, role]
Approved by[name, role]
Distribution[names or groups]

TLP:AMBER+STRICT: Recipients may share on a need-to-know basis within their organisation only. All times are UTC (ISO 8601).

1Summary

What happened. [Whose code, pushed where, by which role (not who to blame), public for how long.]

What we found. [e.g. A search of N public sources on date found no surviving public copy.]

Secrets. [Secret types found by the history scan, or none.]

What remains. Copies cloned while the code was public cannot be detected by anyone, so the code is treated as disclosed.

Public copies today
[result]

[N sources checked]

Credentials in the code
[result]

Run leak scan on the full history.

Source code
Disclosed

May have been cloned while it was public.

Decisions needed

  1. Confirm that every credential in section 5 has been rotated and the old value revoked.
  2. Decide on notifications (section 7), with legal advice where personal data may be involved.
  3. Approve the actions in section 8, each with an owner and a due date.

2Incident details

ItemDetail
Repositories[owner/repo]
Exposure window[start to end, UTC; source: account security log]
How the code was exposed[e.g. company repository pushed to a personal public account]
How it was detected[alert email, colleague, monitoring]
Personal or customer data[none / yes: which categories]
Copies searched since[date]

3Timeline

Time (UTC)EventSource
[date hh:mm]Repository first pushed or made publicAccount security log; snapshot metadata.json
[date hh:mm]Exposure detected: [how][alert email, colleague, monitoring]
[date hh:mm]Copy contained (made private, deleted or taken down)[source]
[date hh:mm]First secret revoked[provider console or audit log]
[date hh:mm]Last secret revoked[provider console or audit log]
[date hh:mm]Search for surviving copiesleak hunt
[date hh:mm]Notifications sent[to whom]

4Investigation: where copies could survive

[N] checks. Each answer is saved as evidence (appendix A).

#CheckResultDetail
1The repository itself[result][detail]
2Direct forks[result][detail]
3Same-name forks, traced to their root[result][detail]
4Wayback Machine[result][detail]
5Software Heritage[result][detail]
6Code search (Sourcegraph)[result][detail]
7GitLab projects of the same name[result][detail]
8Uploader's other repositories[result][detail]
9Uploader's public gists[result][detail]
10Public activity (90 days)[result][detail]
11Original commits in other repositories[result][detail]

5Secrets to rotate

TypeFindingsFilesFirst committedOwnerStatus
[type][n][n][date][owner][status]

Types and counts only. Never write secret values in this report.

6Impact and risk

RiskBefore actionsAfter actionsWhy
Use of exposed credentialsHigh[level]Exposed keys are harvested within minutes. Rotation removes the risk; logs show whether anything was used.
Disclosure of code and designMediumMediumCannot be undone: exposes logic, endpoints and architecture.
Personal or customer data[level][level]Notification duties may apply (section 7).
Reputation and contracts[level][level]Reduced by prompt, factual communication and evidence of new controls.

7Notification assessment

Who may need to be toldRequired?DeadlineOwner and status
Data protection authority, if personal data is at risk (for example GDPR Article 33)[yes / no]72 hours from awareness[owner, status]
Affected individuals, if the risk to them is high (for example GDPR Article 34)[yes / no]Without undue delay[owner, status]
Customers and partners under contract[yes / no][per contract][owner, status]
Providers of the exposed credentials[yes / no][deadline][owner, status]

Engineering guidance, not legal advice. Confirm obligations with your legal or data protection team.

8Actions

ActionOwnerDueStatus
Rotate every credential in section 5, revoking the old values[owner][date][status]
Review access and billing logs from first push to the last revocation[owner][date][status]
Remove every copy marked Found; check every Not checked source by hand[owner][date][status]
Repeat the search for copies after 7 days[owner][date][status]
Send the notifications decided in section 7[owner][date][status]
Hold a blameless post-incident review[owner][date][status]

9Root cause and lessons learned

Root cause. [The condition that allowed the exposure, e.g. no control prevented company code from being pushed to a personal account.]

Contributing factors. [e.g. long-lived credentials stored in the code; no secret scanning before commit.]

What went well. [e.g. rotation started within 15 minutes of detection.]

Describe conditions and controls, not individuals. The full review uses the post-incident review template.

AEvidence and chain of custody

EvidenceLocationSHA-256
Copy hunt[folder][SHA-256 of MANIFEST.sha256]
Secret scan[file][SHA-256]

Held by. [name, storage location, access restricted to]

BMethod and limitations

Method

  • Read-only queries to public services. No credential was used or tested.
  • Secret scanning of every commit on every branch with gitleaks; values redacted.
  • Each answer saved with its raw response and a checksum manifest.

Limitations

  • Private clones made while the code was public cannot be detected.
  • Results are a point in time; repeat the search after 7 days.
  • Some archives (archive.today, grep.app) must be checked by hand.

CSeverity scale

LevelMeaning (example scale; use your organisation's own if it has one)
SEV-1Working production credentials or personal data publicly exposed, and not yet contained.
SEV-2Credentials exposed but all revoked, or proprietary code publicly exposed.
SEV-3Internal code exposed with no secrets and limited sensitivity.
SEV-4Non-sensitive material exposed and already contained.

DDocument history

VersionDateAuthorChange
0.1[date][name]Draft generated by Spillkit 3.8.1
TLP:AMBER+STRICTPrepared with Spillkit 3.8.1 ยท Contains no secret values