Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd0507292e |
@@ -0,0 +1,193 @@
|
||||
# User Data Isolation Redline
|
||||
|
||||
Status: mandatory
|
||||
|
||||
Decision date: 2026-07-10
|
||||
|
||||
Baseline at decision: V1R4C3
|
||||
|
||||
## Redline
|
||||
|
||||
User data isolation is a hard system-design requirement.
|
||||
|
||||
No component may read, write, search, rank, summarize, cache, or report data from another user, tenant, project, session, workspace, branch, agent, or task context unless explicit authorization and context binding exist.
|
||||
|
||||
This applies to memory search, filesystem logs, vector indexes, search gateways, autonomous controller state, task records, audit logs, artifacts, and any fallback provider.
|
||||
|
||||
## Incident Class
|
||||
|
||||
Any cross-context data contamination is a security and reliability incident, not a normal feature bug.
|
||||
|
||||
Examples:
|
||||
|
||||
- memory search returns records from another project;
|
||||
- shared workspace logs are used as current-session evidence;
|
||||
- global `memory/` state mixes unrelated users or tasks;
|
||||
- fallback provider uses unscoped records;
|
||||
- agent reports status based on stale or unrelated context;
|
||||
- shared cache leaks content across users, groups, or sessions.
|
||||
|
||||
## Core Rule
|
||||
|
||||
A query may only access records satisfying all required scope dimensions:
|
||||
|
||||
```text
|
||||
user_id
|
||||
AND tenant_id / group_id
|
||||
AND session_id or conversation_id
|
||||
AND project_id
|
||||
AND workspace_id
|
||||
AND branch or baseline scope
|
||||
AND agent_id / tool_context when applicable
|
||||
```
|
||||
|
||||
If a dimension is unavailable, the safe behavior is deny-by-default or text-only fallback.
|
||||
|
||||
## Forbidden Design
|
||||
|
||||
The following are forbidden in production paths:
|
||||
|
||||
1. Global shared memory directories without per-scope namespace.
|
||||
2. Search over untagged records.
|
||||
3. Search over records whose owner/scope cannot be proven.
|
||||
4. Trusting filesystem location alone as authorization.
|
||||
5. Treating memory search results as authoritative without provenance.
|
||||
6. Cross-session fallback without explicit allowlist.
|
||||
7. Auto-reporting from memory results that are not bound to the current runtime/baseline/task.
|
||||
8. Using stale context from unrelated branches or projects as current-state evidence.
|
||||
|
||||
## Required Design
|
||||
|
||||
Every persisted memory/state record must include immutable metadata:
|
||||
|
||||
```text
|
||||
record_id
|
||||
user_id
|
||||
tenant_id or group_id
|
||||
session_id / conversation_id
|
||||
project_id
|
||||
workspace_id
|
||||
branch
|
||||
baseline
|
||||
agent_id
|
||||
source_tool
|
||||
created_at
|
||||
schema_version
|
||||
sensitivity
|
||||
retention_class
|
||||
```
|
||||
|
||||
Every read/search request must include a scope envelope:
|
||||
|
||||
```text
|
||||
request_user_id
|
||||
request_tenant_id / group_id
|
||||
request_session_id / conversation_id
|
||||
request_project_id
|
||||
request_workspace_id
|
||||
allowed_branches / current_branch
|
||||
allowed_baselines / current_baseline
|
||||
purpose
|
||||
```
|
||||
|
||||
A record is readable only if its metadata matches the request scope policy.
|
||||
|
||||
## Enforcement Layers
|
||||
|
||||
### 1. Storage namespace isolation
|
||||
|
||||
Memory/state paths must be namespaced:
|
||||
|
||||
```text
|
||||
memory/{tenant_id}/{user_id}/{project_id}/{session_id}/...
|
||||
state/{tenant_id}/{project_id}/{workspace_id}/...
|
||||
```
|
||||
|
||||
No production component may write unrelated contexts into a single global `memory/` directory.
|
||||
|
||||
### 2. Metadata enforcement
|
||||
|
||||
Untagged records are unreadable by default.
|
||||
|
||||
Records without owner/scope metadata may be archived for forensic review but must not be searched or used for live reasoning.
|
||||
|
||||
### 3. Query-time ACL
|
||||
|
||||
Search must apply a mandatory scope filter before ranking or summarization.
|
||||
|
||||
The ranking stage must never receive out-of-scope records.
|
||||
|
||||
### 4. Provenance requirement
|
||||
|
||||
Every memory/search result used for operational reporting must carry provenance:
|
||||
|
||||
```text
|
||||
record_id
|
||||
scope metadata
|
||||
source path or source index
|
||||
match reason
|
||||
created_at
|
||||
```
|
||||
|
||||
Responses must prefer current runtime truth sources over memory:
|
||||
|
||||
```text
|
||||
getRuntimeStatus
|
||||
getBaseline
|
||||
listPatches
|
||||
explicit user-provided current context
|
||||
current branch files
|
||||
```
|
||||
|
||||
Memory search is advisory only after scope validation.
|
||||
|
||||
### 5. Fallback safety
|
||||
|
||||
If provider search cannot prove scope isolation, the system must use text-only fallback or no-memory fallback.
|
||||
|
||||
Fallback must not silently broaden the scope.
|
||||
|
||||
### 6. Write-path isolation
|
||||
|
||||
Writers must not append current-session records into shared directories.
|
||||
|
||||
Writers must derive the target path from the scope envelope, not from a global default.
|
||||
|
||||
### 7. Audit and detection
|
||||
|
||||
The system must produce audit events when:
|
||||
|
||||
- a record is denied due to scope mismatch;
|
||||
- untagged memory is encountered;
|
||||
- fallback disables memory search;
|
||||
- a provider tries to return out-of-scope records;
|
||||
- cross-context contamination is detected.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
A memory/search provider is allowed only if all tests pass:
|
||||
|
||||
1. Same user, same project, same session -> records are visible.
|
||||
2. Same user, same project, different session -> visible only if policy permits.
|
||||
3. Same user, different project -> denied by default.
|
||||
4. Different user, same project -> denied unless explicitly shared by group policy.
|
||||
5. Different tenant/group -> denied.
|
||||
6. Untagged record -> denied.
|
||||
7. Stale branch/baseline record -> not used as current evidence.
|
||||
8. Provider fallback without scope support -> memory disabled.
|
||||
9. Search result provenance is returned and logged.
|
||||
10. Out-of-scope records are filtered before ranking/summarization.
|
||||
|
||||
## Runtime Rule
|
||||
|
||||
If memory search is enabled without these controls, recurrence is possible.
|
||||
|
||||
Therefore, memory search must remain disabled or in scoped allowlist mode until the isolation acceptance suite is green.
|
||||
|
||||
## Owner Gate
|
||||
|
||||
Any change that enables shared memory search, cross-session recall, global vector indexes, or cross-agent memory reuse requires owner/admin approval.
|
||||
|
||||
## Final Rule
|
||||
|
||||
User data isolation is a redline. Reliability, convenience, or recall quality may not override it.
|
||||
Reference in New Issue
Block a user