Permission Leak Incident Timeline and Investigation Report¶
Use this template immediately when a permission leak is reported in production or pre-production. Record all timestamps in UTC. Do not paste leaked confidential content or raw credentials into this document.
1. Incident Overview¶
- Incident ID:
${INCIDENT_ID}(e.g.INC-20261028-RAG-01) - Severity: P1 - Critical (Unauthorised Data Disclosure)
- Status: Active | Contained | Remediated | Closed
- Reported date and time:
YYYY-MM-DDTHH:MM:SSZ - Lead investigator (Security engineer):
${SECURITY_LEAD_NAME} - GenAI engineer:
${GENAI_ENGINEER_NAME} - DevOps engineer:
${DEVOPS_ENGINEER_NAME} - Client security lead:
${CLIENT_SECURITY_CONTACT} - Affected search service and index:
${SEARCH_SERVICE}/${INDEX_NAME} - Affected query path: Chat | Search | Suggestions | Document Lookup | Citations | Export | Agent Tool
2. Summary of Exposure¶
Provide a concise, non-sensitive summary of what was reported.
- Reporter:
${REPORTER_ROLE_OR_ID} - Query submitted:
${REPORTED_QUERY} - Document(s) exposed:
${EXPOSED_DOCUMENT_IDS}(e.g.doc-hr-2026-salary-band.pdf) - Document sensitivity: Restricted HR | Legal Confidential | Commercial in Confidence | Internal Only
- Expected access: User has groups
${USER_GROUPS}, document requires${REQUIRED_GROUPS}. - Canary token observed:
${CANARY_TOKEN_ID}(if synthetic test canary was exposed)
3. Incident Timeline¶
Every action taken from detection to recovery must be recorded with exact UTC timestamps.
| Time (UTC) | Phase | Action taken | Performed by | Verification / Artifact |
|---|---|---|---|---|
HH:MM |
Detection | Incident reported; clock started; ticket logged. | Security engineer | Ticket ${TICKET_URL} created; reporter query captured. |
HH:MM |
Containment | Affected query path disabled or maintenance mode enabled. | DevOps engineer | Smoke query returns HTTP 503 or empty result set; no data served. |
HH:MM |
Notification | Client security lead formally notified per agreed SLA. | Security engineer | Email / incident bridge confirmation logged. |
HH:MM |
Evidence | Diagnostic and query audit logs frozen; log purge suspended. | DevOps engineer | Log analytics snapshot archived to ${AUDIT_ARCHIVE_URI}. |
HH:MM |
Reproduction | Leak reproduced in isolated sandbox using synthetic personas. | GenAI engineer | Test case fails with identical symptom in test_leakage.py. |
HH:MM |
Root cause | Cause identified using known issues table (Section 5). | GenAI engineer | Diagnostic trace identifies exact failure mechanism. |
HH:MM |
Remediation | Permissions corrected or code patch deployed; cache cleared. | GenAI engineer | Urgent revocation applied via PB-RAG-04-03. |
HH:MM |
Blast radius | Audit log scanned for all queries retrieving affected document. | Security engineer | User list and query count compiled in Section 5 below. |
HH:MM |
Regression test | Specific regression test added to snippets/test_leakage.py. |
GenAI engineer | Test fails before fix, passes after fix. |
HH:MM |
Verification | Full persona test suite run against test index; all pass. | Security engineer | Zero leakage verified; test run output attached. |
HH:MM |
Recovery | Affected query path re-enabled following two-person sign-off. | DevOps engineer | Production health probe 200 OK; access verified clean. |
HH:MM |
Post-mortem | Root cause report and corrective actions shared with client. | RAG Lead | Client incident report signed off. |
4. Root Cause Analysis¶
Select the identified primary failure mechanism and describe details:
- Missing security filter: The code path called the search index directly without appending
group_ids/any(...). - Empty group list handled as no filter: Directory lookup returned zero groups and the code executed an unfiltered query rather than failing closed.
- Lookup API invoked without permission check: Document was retrieved by key via the Lookup Document REST API, which has no native filter support.
- Direct or shared download link bypass: Citation link pointed directly to storage with an unexpired SAS URL or public link without access control.
- Token group claim overage (>200 groups): App read group IDs from token claims instead of querying Microsoft Graph
transitiveMemberOf. - Source permission sync lag: Permissions were revoked at source but indexer sync had not propagated changes to all chunks.
- Parent inheritance desynchronisation: Permissions changed on a parent folder or SharePoint library, requiring an indexer resync that was not triggered.
- Shared application or semantic cache: A query answer generated for an authorised user was cached and served to an unauthorised user.
- Hostile filter injection: Malformed group ID or user input broke OData filter syntax, causing filter evaluation failure.
Technical Details¶
${TECHNICAL_ROOT_CAUSE_DESCRIPTION}
5. Blast Radius and Impact Assessment¶
Audit log query window: ${START_TIME_UTC} to ${CONTAINMENT_TIME_UTC}.
- Total queries matching affected document:
${TOTAL_MATCHED_QUERIES} - Unique user accounts that received content:
${EXPOSED_USER_COUNT} - Export / download actions recorded:
${DOWNLOAD_COUNT} - List of exposed accounts:
${USER_ID_1}(Time:YYYY-MM-DDTHH:MM:SSZ, Path:${PATH})${USER_ID_2}(Time:YYYY-MM-DDTHH:MM:SSZ, Path:${PATH})
6. Corrective and Preventative Actions (CAPA)¶
| Action item | Owner | Target date | Ticket / PR |
|---|---|---|---|
| Merge code fix with enforced security filter on affected path | GenAI engineer | YYYY-MM-DD |
PR ${PR_NUMBER} |
Add regression test to snippets/test_leakage.py |
GenAI engineer | YYYY-MM-DD |
PR ${PR_NUMBER} |
| Clear application and semantic cache entries for affected users | DevOps engineer | YYYY-MM-DD |
Ticket ${TICKET_ID} |
| Adjust permission sync frequency or implement webhook refresh | DevOps engineer | YYYY-MM-DD |
Ticket ${TICKET_ID} |
| Conduct retrospective with client security team | Security engineer | YYYY-MM-DD |
Meeting ${MEETING_ID} |
7. Sign-Off and Re-Enable Approval¶
Re-enabling the affected query path requires explicit sign-off from both the Security Lead and the RAG Technical Lead.
| Role | Name | Decision | Date (UTC) |
|---|---|---|---|
| Security Lead | ${SECURITY_LEAD_NAME} | Approved / Rejected | YYYY-MM-DD |
| RAG Technical Lead | ${RAG_LEAD_NAME} | Approved / Rejected | YYYY-MM-DD |
| Client Security Representative | ${CLIENT_REP_NAME} | Notified / Acknowledged | YYYY-MM-DD |