Security Architecture Overview
The Cascade Protocol follows a local-first architecture. Core operations run on the user's machine. There are no backend services or cloud databases. No CLI command contacts a network to validate, convert, query, import or write. Three commands do, only when you run them: advisory feed pull fetches the feed URL you give it, pod extract posts narrative text to a cascade-agent server (on your own machine by default), and agent sends your prompts and the output of the commands it runs, which can include health data, to the AI provider you configure.
Design Principles
- Local processing. The CLI and MCP server work on the local filesystem. The MCP server itself makes no outbound calls, but the AI client that connects to it sends what it reads to its model. With a cloud model, that data leaves the device.
- Open source. The spec, CLI, agent, TypeScript and Python SDKs and conformance suite are public (Apache-2.0 for code, CC BY 4.0 for the spec). The Swift SDK is not public.
- No telemetry. There are no analytics, crash reporting, phone-home behaviors, or tracking of any kind in the CLI or SDKs.
- Minimal attack surface. The protocol defines data structure and serialization, not networking. There is no HTTP server, no database daemon, and no listening socket in default operation.
Data Flow Diagram
Verifiable claim
Network behaviour can be checked by auditing the source code or running the CLI under a network monitor (e.g., Little Snitch, tcpdump, Wireshark). cascade capabilities lists the commands that use the network under securityModel.networkCalls.
PHI Handling
Protected Health Information (PHI) under HIPAA includes any individually identifiable health information. The Cascade Protocol stores PHI categories locally in the user's Pod as RDF/Turtle files, organized by data type.
PHI Categories
The protocol defines the following PHI-relevant data categories, each stored in its own directory within the Pod:
| Category | Pod Directory | Vocabulary |
|---|---|---|
| Medications | clinical/ | clinical: |
| Conditions | clinical/ | clinical: |
| Allergies | clinical/ | clinical: |
| Lab Results | clinical/ | clinical: |
| Vital Signs | wellness/ or clinical/ | health: / clinical: |
| Immunizations | clinical/ | clinical: |
| Demographics | profile/ | cascade: |
Consent Model
There is no consent filtering today. Any agent connected to the MCP server can read the whole Pod. No sharing or consent controls are built.
An earlier design proposed a per-Pod consent.json file listing which data categories may be shared. It was never enforced, and the D-CONSENT-1 decision set it aside. The example below is kept only to show what was proposed.
// Proposed consent.json (never implemented)
{
"version": "1.0",
"categories": {
"medications": { "share": true },
"conditions": { "share": true },
"allergies": { "share": true },
"lab_results": { "share": false },
"vital_signs": { "share": true },
"immunizations": { "share": true },
"demographics": { "share": false }
},
"defaultPolicy": "deny"
}
Implementation status
Nothing reads or enforces consent.json. The MCP server does not filter by category. Do not connect an agent to a Pod unless you are willing for it to read everything in it.
Data Minimization
Query operations accept a list of requested data types and return only matching records. This narrows a single query; it is not an access control. The MCP cascade_pod_query tool accepts all, and cascade_pod_read summarizes the whole Pod.
Provenance Model
Records in the Cascade Protocol carry provenance metadata based on the W3C PROV-O ontology. Provenance distinguishes how data was created and by whom. Lineage exists only where an importer or application writes it.
Provenance Types
Core defines these and several more provenance classes (for example PatientReported, EHRVerified and ScannedDocument). See the core vocabulary for the full list.
| Type | URI | Description | Example Source |
|---|---|---|---|
| ClinicalGenerated | cascade:ClinicalGenerated |
Data originating from clinical or EHR systems | Apple Health clinical records imported from a hospital |
| DeviceGenerated | cascade:DeviceGenerated |
Data from wearable or medical devices | Apple Watch heart rate, blood oxygen readings |
| SelfReported | cascade:SelfReported |
Data entered directly by the patient | Symptom diary entry, manually entered medication |
| AIExtracted | cascade:AIExtracted |
AI-extracted from existing documents, and anything an agent writes through the MCP server | Structured data parsed from a scanned lab report; an agent-written summary |
| AIAsserted | cascade:AIAsserted |
Content from a general-purpose AI assistant, not grounded in clinical sources | A claim imported from an AI chat, to be checked before relying on it |
Provenance Attachment
Provenance is attached to every record as RDF triples using the cascade: and prov: namespaces. The following Turtle example demonstrates how provenance metadata is serialized:
@prefix cascade: <https://ns.cascadeprotocol.org/core/v1#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890>
a clinical:Medication ;
cascade:dataProvenance cascade:ClinicalGenerated ;
cascade:schemaVersion "1.5" ;
prov:wasAttributedTo <https://id.cascadeprotocol.org/users/patient-123> ;
prov:generatedAtTime "2026-01-15T10:30:00Z"^^xsd:dateTime ;
clinical:drugName "Metoprolol" ;
clinical:dosage "25 mg" ;
clinical:frequency "twice daily" .
Verifying Provenance
Provenance can be checked by searching the Pod's Turtle files for cascade:dataProvenance triples, or by querying records with the CLI or the cascade_pod_query MCP tool. To look across all records:
# Query all records
cascade pod query ./my-pod --all
# List every provenance value in the Pod's files
grep -rh "cascade:dataProvenance" ./my-pod
# Or use the MCP server programmatically via cascade_pod_query
Audit Logging
The MCP server appends one entry per tool call to provenance/audit-log.ttl in the Pod. Only the MCP server writes this log; CLI commands run directly are not logged. It is a plain Turtle file: anyone who can write to the Pod folder can edit it, and it is not authenticated or tamper-evident. The log predicates below (cascade:AuditEntry, cascade:timestamp and the rest) are not yet declared in the core vocabulary.
Log Format
Each audit entry records the following fields:
| Field | RDF Property | Description |
|---|---|---|
| Timestamp | cascade:timestamp |
ISO 8601 datetime of the operation |
| Operation | cascade:operation |
Type of operation: read, write, query, validate, convert |
| Data Types | cascade:dataTypes |
RDF list of data types accessed (e.g., "medications", "conditions") |
| Agent ID | cascade:agentId |
Identifier of the AI agent or tool that performed the operation |
| Record Count | cascade:recordsAccessed |
Number of records read or written |
Example Audit Entry
The following example shows the format the audit logger writes (from src/lib/mcp/audit.ts in the CLI). The agent ID is whatever the agent reports, or unknown-agent; it is not verified.
@prefix cascade: <https://ns.cascadeprotocol.org/core/v1#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix prov: <http://www.w3.org/ns/prov#> .
# Cascade Protocol Agent Audit Log
# Generated by cascade serve --mcp
<#audit-3f8a91c2-7b4d-4e6f-9a1c-2d3e4f5a6b7c> a cascade:AuditEntry ;
cascade:timestamp "2026-02-15T14:30:22.451Z"^^xsd:dateTime ;
cascade:operation "read" ;
cascade:dataTypes ("medications" "conditions") ;
cascade:agentId "claude-desktop-v1" ;
cascade:recordsAccessed 12 .
<#audit-8c1d2e3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f> a cascade:AuditEntry ;
cascade:timestamp "2026-02-15T14:31:05.789Z"^^xsd:dateTime ;
cascade:operation "write" ;
cascade:dataTypes ("medications") ;
cascade:agentId "claude-desktop-v1" ;
cascade:recordsAccessed 1 .
Reviewing Audit Logs
Audit logs are standard Turtle files and can be read with any RDF tool or text editor.
# View the raw audit log
cat ./my-pod/provenance/audit-log.ttl
# Count total operations
grep -c "a cascade:AuditEntry" ./my-pod/provenance/audit-log.ttl
# Filter by agent
grep -A5 "agentId" ./my-pod/provenance/audit-log.ttl
Implementation detail
Audit entry IDs use crypto.randomUUID(), so IDs do not collide across server restarts and concurrent sessions. The server only appends to the log and never rewrites entries, but nothing stops another program or person from changing the file.
AI Agent Access
The Cascade Protocol exposes health data to AI agents via the Model Context Protocol (MCP). The MCP server (cascade serve --mcp) applies the controls below. It does not check consent or limit which records an agent can read, and the AI client sends what the agent reads to its model.
Path Containment
All file operations are validated against a boundary directory to prevent path traversal attacks. The implementation resolves both the target path and the Pod boundary to absolute paths, then verifies containment:
// From src/lib/mcp/tools.ts in cascade-cli
function validatePathBoundary(
resolvedPath: string,
boundary: string
): boolean {
const normalizedPath = path.resolve(resolvedPath);
const normalizedBoundary = path.resolve(boundary);
return (
normalizedPath.startsWith(normalizedBoundary + path.sep) ||
normalizedPath === normalizedBoundary
);
}
This check runs on every write operation. If the resolved target file path falls outside the Pod directory, the operation is rejected with an error.
Automatic AIExtracted Provenance
All data written through the MCP server is automatically tagged with cascade:AIExtracted provenance. This is set by the server — the agent cannot choose it. The provenance record includes:
- Provenance type: Always
AIExtractedfor MCP-written data - Agent ID: Identifier the agent reports (e.g.,
"claude-desktop-v1"), not verified; defaults to"unknown-agent"if not provided - Timestamp: ISO 8601 datetime of the write operation
- Reason: Optional free-text explanation for why the record was created
- Confidence level: Optional float between 0.0 and 1.0 indicating the agent's confidence in the data
- Source records: Optional URIs of existing records used to derive the new data
// Provenance metadata returned for every MCP write operation
{
"type": "AIExtracted",
"agentId": "claude-desktop-v1",
"timestamp": "2026-02-15T14:31:05.789Z",
"reason": "Summarized medication list for visit prep",
"confidence": 0.92
}
Audit Trail
Each MCP tool invocation — read, write, query, validate, or convert — is appended to the Pod's audit log. See Audit Logging above for format details.
Encryption
Encryption responsibilities are deliberately separated across layers. The vocabularies and the serialization format define data structure and carry no encryption, so the same records can be stored sealed or in the clear. How a Pod is encrypted at rest is specified separately, in the Pod Encryption specification.
Protocol Layer (Vocabulary & Serialization)
Protocol Layer (Pod Encryption)
settings/encryption.json, the limits a reader enforces before deriving any key, and how a Pod's key is changed. Cross-implementation vectors are in the conformance suite; see the implementer's guide.
Application SDK Layer (cascade-sdk-swift, private and archived)
Infrastructure Layer
Regulatory Considerations
Not legal advice
This section describes how the Cascade Protocol's technical architecture aligns with regulatory frameworks. It is not legal advice and does not constitute a compliance certification. Organizations building on the protocol should conduct their own regulatory assessment.
HIPAA (Health Insurance Portability and Accountability Act)
What Cascade helps with
provenance/audit-log.ttl, with a timestamp, the agent ID the agent reports, data types and record count. The file is not tamper-evident, and CLI commands run directly are not logged.
What Cascade does NOT help with
GDPR (General Data Protection Regulation)
What Cascade helps with
21st Century Cures Act
cascade_convert MCP tool) enable data exchange between Cascade Pods and FHIR-compliant systems.
Threat Model
Threats Cascade Mitigates
validatePathBoundary() function resolves all paths to absolute form and verifies they remain within the Pod directory before any filesystem operation.
AIExtracted for all write operations. Agents cannot override this to claim data is ClinicalGenerated.
Threats Cascade Does NOT Mitigate
Limitations
The following threats are outside the protocol's scope. They must be addressed by the user's platform, infrastructure, or organizational security measures.
Open Source Audit
The spec, CLI, agent, TypeScript and Python SDKs and conformance suite are public (Apache-2.0 / CC BY 4.0) and available for independent audit. The Swift SDK is private and archived.
Repositories
| Repository | Description | Language |
|---|---|---|
spec |
Ontologies, SHACL shapes, JSON-LD contexts, normative documents, decision records | Turtle, Markdown |
cascade-cli |
CLI, MCP server, SHACL validator, FHIR / C-CDA / Apple Health import, pod encryption | TypeScript |
cascade-agent |
Plain-English front end and narrative extraction | TypeScript |
sdk-typescript |
TypeScript SDK | TypeScript |
sdk-python |
Python SDK | Python |
conformance |
Test fixtures, encryption vectors, reference patient Pod | JSON, Turtle |
Verifying No Telemetry
The absence of telemetry, analytics, or phone-home behavior can be checked by searching the codebase for network-related code. In the CLI, the network search finds the three commands that use the network on request (advisory feed pull, pod extract, agent) and the code that describes them; cascade capabilities lists them under securityModel.networkCalls. The analytics search should find no tracking code.
# Search for HTTP/network calls in the CLI
grep -r "fetch\|axios\|http\.\|https\.\|XMLHttpRequest\|net\.connect" \
--include="*.ts" --include="*.js" \
src/
# Search for analytics or tracking
grep -ri "analytics\|telemetry\|tracking\|phone.home\|beacon" \
--include="*.ts" --include="*.js" \
src/
Expected results
Apart from the three commands above, the CLI uses node:fs and node:path for local filesystem operations. Matches for words such as "tracking" may be ordinary code, so read each hit.
Dependency Audit
The CLI's main runtime dependencies and their purposes are listed below. All are open source. Run npm ls --omit=dev for the full tree.
CLI (TypeScript / Node.js)
| Dependency | Purpose |
|---|---|
@modelcontextprotocol/sdk | MCP server implementation for AI agent access |
n3 | RDF/Turtle parsing and serialization |
rdf-validate-shacl | SHACL constraint validation |
zod | Runtime schema validation for MCP tool inputs |
commander | CLI argument parsing |
@the-cascade-protocol/agent | The cascade agent command |
How to Audit
- Clone the repositories and review the source code directly. All code paths are auditable.
- Check dependencies with
npm ls --omit=dev(CLI) for the full dependency tree. - Run under network monitoring to confirm that commands other than the three listed make no outbound connections.
- Review the audit log after any agent interaction to see which MCP calls were made. Remember that the file is not tamper-evident.