Kai Aizen
creator of AATMF · author of Adversarial Minds · NVD contributor
SHELL.005 · 2026.06

Claude's memory system — the feature that lets it remember facts about you across conversations — runs on infrastructure that lives inside the same sandbox where your code executes. This article documents what that infrastructure looks like from the inside: the binaries, the protobuf schemas, the authentication chain, the encryption model, the TLS interception architecture, the credential exposure, and the trust boundaries where the design assumptions break down.

Everything here was extracted from a live claude.ai code execution session using standard Linux tools: strings, openssl, /proc introspection, and mount. No external tools were installed. No vulnerabilities were exploited. The sandbox gave me root.

cwe-522 — credential extraction chain · every link a designed capability 01code executiondesigned capability02root accessno isolation · uid 003/proc/491/memno seccomp prevents read04jwt extractedfrom rclone heap05token replayvs api.anthropic.commissing controls — seccomp filter on process_vm_readv · drop CAP_SYS_PTRACE · separate uid for rclone · prctl(PR_SET_DUMPABLE,0)
fig 1 · cwe-522 — the credential extraction chain, root to token replay; every link is a designed capability operating as intended

1. The Sandbox

Claude's code execution environment is a Firecracker microVM running Linux 6.18.5. The entire userspace is two processes:

PID   BINARY                              LANGUAGE    ROLE
1     /process_api                         Rust        Firecracker init + WebSocket server
491   /opt/rclone/rclone-filestore         Go          FUSE filesystem bridge to Anthropic API

No init system. No cron. No sshd. Two binaries, one conversation.

1.1 Security Controls

$ cat /proc/1/status | grep -E 'Seccomp|Cap'
Seccomp:         0
Seccomp_filters: 0
CapEff:          000001ffffffffff     ← all 41 Linux capabilities
CapBnd:          000001fffeffffff

$ cat /proc/1/attr/current
kernel                                ← AppArmor not enforced

$ cat /sys/fs/cgroup/memory/memory.limit_in_bytes
9223372036854771712                   ← ~8 EB (effectively unlimited)

$ cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
-1                                    ← unlimited CPU
Control Status
Seccomp Disabled — zero filters
AppArmor Not enforced
Capabilities All 41 granted — SYS_PTRACE, SYS_ADMIN, NET_RAW, SYS_MODULE, everything
User root (UID 0)
Memory limit ~8 EB
CPU quota Unlimited

The sandbox relies entirely on the Firecracker VM boundary for isolation. Inside the VM, there are no syscall filters, no mandatory access controls, and no capability restrictions. IS_SANDBOX=yes is set in the environment but nothing enforces it.

1.2 process_api — The Rust Init

process_api is PID 1, written in Rust using the Tokio async runtime, hyper for HTTP, and tungstenite for WebSocket handling.

Firecracker initialization:

[INIT] Starting Firecracker VM initialization...
[INIT] Firecracker init complete, starting process_api services...

It sets up tmpfs, cgroup mounts (cpuacct, devices, freezer, blkio, cgroup2), and resolv.conf before starting the WebSocket server on port 2024 and a control server on port 2025.

WebSocket process protocol (from binary string analysis): 1. First message: text JSON CreateProcess (now ProcessCreatedV2) 2. JWT authentication exchange 3. Second message: CreateProcess with execution parameters 4. Process execution with stdin/stdout/stderr over WebSocket frames 5. Termination via: exit, timeout (timeout_secs / cpu_timeout_secs), OOM (oom_polling_period_ms=100), or container OOM

Resource management passed as command-line arguments:

--memory-limit-bytes     Memory ceiling
--cpu-shares             CPU share allocation
--oom-polling-period-ms  OOM detection interval (default 100ms)
--max-ws-buffer-size     WebSocket buffer (32768)
--block-local-connections  Reject connections from localhost/own IP

Security enforcement:

[SECURITY] Rejected WebSocket connection from local IP

Process IDs are validated against control characters and trace markers (##TRACE##). The --block-local-connections flag prevents sandbox processes from connecting back to the WebSocket server.

gVisor reference: The --listen-uds documentation mentions gVisor: "Used with gVisor --host-uds=open, where bind() on gofer-backed paths falls back to a sentry-synthetic dentry." Some deployments use gVisor instead of or alongside Firecracker.


2. TLS Interception

All outbound HTTPS traffic from the sandbox is TLS-intercepted by Anthropic's egress proxy.

2.1 Four Root CAs

The system cert store contains 150 certificates. The last four are Anthropic-injected:

$ awk '/BEGIN CERT/,/END CERT/' /etc/ssl/certs/ca-certificates.crt | \
  openssl x509 -noout -issuer -subject | grep Anthropic

#147: O=Anthropic, CN=sandbox-egress-gateway-production Egress Gateway CA
#148: O=Anthropic, CN=sandbox-egress-gateway-staging Egress Gateway CA
#149: O=Anthropic, CN=sandbox-egress-production TLS Inspection CA
#150: O=Anthropic, CN=sandbox-egress-staging TLS Inspection CA

Two CA hierarchies (Gateway + TLS Inspection), each with production and staging variants. The leaf certificates are dynamically generated by an intermediate CA not in the cert store:

$ echo | openssl s_client -connect github.com:443 2>/dev/null | \
  openssl x509 -noout -issuer -subject

issuer=O=Anthropic, CN=Egress Gateway SDS Issuing CA (production)
subject=CN=github.com

Every destination gets the same issuer:

Destination Leaf Subject Issuer
api.anthropic.com *.anthropic.com Egress Gateway SDS Issuing CA (production)
github.com github.com Egress Gateway SDS Issuing CA (production)
google.com google.com Egress Gateway SDS Issuing CA (production)

2.2 Injection Coverage

The process_api binary contains paths for injecting the interception CA into every TLS library on the system. Extracted from strings:

System cert stores: /etc/ssl/certs/, /etc/pki/tls/certs/, /var/lib/ca-certificates/, /usr/local/share/ca-certificates/

Python: certifi/cacert.pem, pip/_vendor/certifi/cacert.pem, botocore/cacert.pem, plus pyenv/conda/uv virtualenvs

Java: /etc/ssl/certs/java/cacerts, /etc/pki/java/cacerts, plus JVM discovery across usr/lib/jvm, root/.sdkman

Browsers: Firefox/Firefox ESR policies, Chrome, Edge, Playwright, Puppeteer cache paths

Cloud SDKs: CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE, AWS_CA_BUNDLE, GIT_SSL_CAINFO

Environment variables:

SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
CURL_CA_BUNDLE, HTTPLIB2_CA_CERTS, NIX_SSL_CERT_FILE (referenced in binary)

A failure marker at /.sandboxing-ca-inject-failed tracks injection failures.

2.3 Implication

Anthropic can inspect, log, and filter all HTTPS traffic leaving the sandbox. When the sandbox pip installs a package, curls an API, clones a git repo, or authenticates to a cloud service — the traffic is decrypted at the egress proxy, inspected, and re-encrypted. No code running in the sandbox can establish a private TLS connection to any external service.


3. The FUSE Mount Architecture

rclone-filestore creates four FUSE mounts from a JSON config at /tmp/rclone-mount-config.json, all scoped to a conversation-specific filesystem ID:

{
  "service_url": "https://api.anthropic.com",
  "mounts": [
    { "destination": "/mnt/user-data/outputs",     "readonly": false, "cache_duration_s": 3600 },
    { "destination": "/mnt/user-data/uploads",      "readonly": true,  "cache_duration_s": 1 },
    { "destination": "/mnt/transcripts",            "readonly": true,  "cache_duration_s": 10 },
    { "destination": "/mnt/user-data/tool_results", "readonly": true,  "cache_duration_s": 3 }
  ]
}

The kernel mount table confirms FUSE passthrough:

$ mount | grep fuse
rclone-filestore:claude_chat_01U6KwbMD7vRFYEpj3zXcEaA:/mnt/user-data/outputs
    on /mnt/user-data/outputs type fuse.rclone (rw,nosuid,nodev,allow_other)

Every file I/O operation on these paths goes through FUSE to rclone-filestore, which makes ConnectRPC calls to api.anthropic.com. The VFS cache lives in tmpfs at /dev/shm/rclone-vfscache and vanishes when the VM terminates.

The binary itself is 30MB, delivered via squashfs from /dev/vdb, mounted read-only at /opt/rclone.

3.1 Two Backends

The binary contains not just a filestore backend but a dedicated memory store backend:

$ /opt/rclone/rclone-filestore help backends

All rclone backends:
  local            Local Disk
  crypt            Encrypt/Decrypt a remote
  rclone-filestore Filestore Backend
  rclone-memory    Memory Store backend

The rclone-memory backend's configuration reveals the memory system's connection contract:

--rclone-memory-url              Memory service URL (e.g. http://localhost:9430)
--rclone-memory-memory-store-id  Memory store ID (memstore_...)
--rclone-memory-auth-token       Store-scoped JWT (sk-ant-mem-...)
--rclone-memory-cache-ttl        Content cache TTL (default 1h)

The default memory service URL (localhost:9430) suggests a local sidecar in non-Firecracker deployments. In this Firecracker sandbox, only the filestore backend is configured (this is an incognito conversation — memory disabled). When memory is enabled, a fifth FUSE mount backed by the rclone-memory backend would appear.


4. The Memory API

4.1 Service Architecture

The binary is built from github.com/anthropics/anthropic/[email protected] — internal module, no public versioning. Two proto package versions are present: anthropic.memory.api.v1 and anthropic.memory.api.v1alpha. Two service layers exist: MemoryService (public) and MemoryInternalService (internal, used by the sandbox).

4.2 RPC Methods

12 request types, 13 response types:

Request Response Purpose
WriteMemoryRequest WriteMemoryResponse Create a memory
ReadMemoryByPathRequest ReadMemoryByPathResponse Read by path
GetMemoryRequest GetMemoryResponse Read by ID
UpdateMemoryRequest UpdateMemoryResponse Modify content/path
DeleteMemoryByPathRequest DeleteMemoryByPathResponse Delete by path
DeleteMemoryRequest DeleteMemoryResponse Delete by ID
ListMemoriesRequest ListMemoriesResponse Paginated listing
SearchMemoriesRequest SearchMemoriesResponse Semantic search
MoveMemoryRequest MoveMemoryResponse Rename/relocate
GetMemoryVersionRequest GetMemoryVersionResponse Retrieve version
ListMemoryVersionsRequest ListMemoryVersionsResponse Version history
RedactMemoryVersionRequest RedactMemoryVersionResponse Redact a version

4.3 The Memory Object

Fields extracted from Go struct getters:

Memory {
    Id                string      mem_... identifier
    MemoryStoreId     string      memstore_... identifier
    MemoryVersionId   string      memver_... head pointer (current version)
    Path              string      hierarchical path
    Content           string      the stored text
    ContentSha256     bytes       integrity hash
    ContentSizeBytes  int64       content length
    CreatedAt         timestamp
    UpdatedAt         timestamp
}

4.4 Versioning

Each mutation creates a MemoryVersion:

MemoryVersion {
    Id                string      memver_... identifier
    MemoryId          string      parent memory
    MemoryStoreId     string      store scope
    Operation         enum        CREATED | MODIFIED | DELETED
    Path              string      path at time of version
    Content           string      content at time of version
    ContentSha256     bytes
    ContentSizeBytes  int64
    CreatedAt         timestamp
    CreatedBy         Actor       who made this change
    RedactedAt        timestamp   null if not redacted
    RedactedBy        Actor       null if not redacted
}

Versioning is append-only. Deleting a memory writes a DELETED version. Redacting nulls content fields while preserving the version record and lineage. The CreatedBy field uses an Actor union:

Actor = SessionActor | ApiActor { ApiKeyId } | UserActor

The MemoryMetadata type adds LineCount and UpdatedBy fields — line-oriented storage with attribution tracking.

SearchMemoriesRequest {
    MemoryStoreId   string
    Query           string      semantic search query
    PathGlob        string      glob pattern for path filtering
    PathsOnly       bool        return paths without content
    MaxResults      int32
    ContextLines    int32       context snippet size
}

Semantic search with glob support and configurable context windows.

4.6 List with Depth

ListMemoriesParams {
    PathPrefix   string     browse under a path
    Depth        int32      max depth below prefix
    Limit        int32      page size
    Order        enum       ASC | DESC
    View         enum       BASIC (metadata) | FULL (with content)
}

Entries deeper than Depth roll up as MemoryPrefix items — directory-like placeholders. The response alternates between Memory and MemoryPrefix via a MemoryListItem union.

4.7 Write with Preconditions

Optimistic concurrency via ContentSha256Precondition. Path conflicts return MemoryPathConflictError with ConflictingMemoryId. Content is zstd-compressed in transit.

4.8 Telemetry

Every operation and outcome is instrumented:

MEMORY_OPERATION_WRITE | READ | LIST | SEARCH | MOVE | DELETE | UPDATE
MEMORY_OPERATION_REDACT | EXPORT | GET_VERSION | LIST_VERSIONS
MEMORY_OPERATION_CREATE_STORE | DELETE_STORE | UPDATE_STORE | ARCHIVE_STORE

MEMORY_OUTCOME_OK | NOT_FOUND | CONFLICT | PERMISSION_DENIED
MEMORY_OUTCOME_RATE_LIMITED | PRECONDITION_FAILED | INVALID_ARGUMENT

5. Authentication and Credential Extraction

5.1 Six Credential Types

The binary embeds protobuf definitions for six authentication mechanisms under anthropic.annotations:

ApiKeyAuth       — API key (sk-ant-...)
ObolJwtAuth      — Internal JWT via "Obol" auth service
GoogleSaAuth     — Google Service Account
CustomJwtAuth    — Custom JWT bearer assertion
OAuthTokenAuth   — OAuth2 token
SessionKeyAuth   — Session-scoped key

The Authn message aggregates these into rules with RequiredClaims, ForbiddenClaims, RequiredScopes, RequiredUnifiedPermissions, EdgeAuthenticationTypes, and ExtractTenantContext.

5.2 Session Vault

Three constants describe the credential delivery mechanism:

SESSION_VAULT_SANDBOX_CRED    credential scoped to this sandbox
SESSION_VAULT_CRED_INJECTION  the injection mechanism
SESSION_VAULT_VALIDATE        validation of injected credentials

The mount config contains no auth tokens. The environment contains no auth tokens. The command line contains no auth tokens. The credential is injected at runtime through the session vault without persisting it in any file.

5.3 The Extraction

But the credential must exist in process memory for the ConnectRPC calls. By reading /proc/491/mem — readable because the sandbox runs as root with no seccomp or MAC restrictions — two ES256-signed JWTs are extractable:

# Scan rclone-filestore heap for JWT pattern
maps = open('/proc/491/maps').read()
for region in maps:
    data = open('/proc/491/mem', 'rb').read(region)
    jwts = re.findall(r'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+', data)

Token 1 — Read-Write (814 bytes):

{
    "header": {"typ": "JWT", "alg": "ES256", "kid": "KplTqXuB82QG2wduqFyGEsgH6n493zEsfH8qHdXqfiA"},
    "iat": 1782580584,    // 2026-06-27T17:16:24Z (session start)
    "exp": 1782602184,    // 2026-06-27T23:16:24Z (6 hours later)
    "claims": ["sub", "org_uuid", "account_uuid", "workspace_tagged_id",
               "filesystem_id", "org_taints", "resolved_workspace_tagged_id",
               "workspace_uuid", "workspace_cmek_enabled"]
}

Token 2 — Read-Only (838 bytes): Same header, same timestamps. Additional claim: readonly.

5.4 JWT Claims Analysis

Claim Purpose
sub Subject identifier
org_uuid Organization scope
account_uuid Account scope within org
workspace_uuid Workspace scope
workspace_tagged_id / resolved_workspace_tagged_id Workspace resolution
filesystem_id Conversation-scoped filesystem
org_taints Taint-based policy enforcement at org level
workspace_cmek_enabled Whether CMEK is active for this workspace
readonly (Token 2 only) Read-only access flag

The RW token services /mnt/user-data/outputs. The RO token services /mnt/user-data/uploads, /mnt/transcripts, and /mnt/user-data/tool_results. TTL is 6 hours from session start.

5.5 CWE-522

The extraction chain:

Code execution (designed) → root access (by design) → /proc/491/mem readable
(no seccomp) → JWT in rclone heap → token replay vs api.anthropic.com

Missing controls: seccomp filter on process_vm_readv / /proc/PID/mem, drop CAP_SYS_PTRACE, separate UID for rclone-filestore, or prctl(PR_SET_DUMPABLE, 0).

5.6 Feature Gates

AGENT_MEMORY_EAP               Early Access Program
AGENT_MEMORY_RESEARCH_PREVIEW   Research preview
AGENT_MEMORY_PUBLIC_BETA        Current public beta
AGENT_MEMORY_MOUNT              Filesystem mount enablement
AGENT_MEMORY_PROMPT_OVERRIDE    Memory injection into prompts

5.7 The Session System

The binary reveals the broader session architecture beyond memory:

SESSION_CREATE · SESSION_UPDATE · SESSION_STREAMING · SESSION_SYSTEM_EVENT
SESSION_AGENT_OVERRIDES · SESSION_THREADS · SESSION_HOOKS · SESSION_TOOL_EVENTS
CALLABLE_AGENTS · CC_ROUTINE_FIRE · SHELL_AGENT_DELETE · MID_SESSION_UPDATE
managed-agents-2026-04-17-research-preview

Agent orchestration primitives — callable agents, routine firing, and managed agent API versioning — are built into the same binary.


6. Encryption and PII

6.1 AAD Encryption

AAD_SCHEME_ORG_ACCOUNT_STORE   scoped to org + account + store
AAD_SCHEME_ORG_WS_STORE        scoped to org + workspace + store

Envelope encryption with Additional Authenticated Data derived from organizational hierarchy. Ciphertext for one org/account/store cannot be decrypted in another context.

6.2 CMEK

CmekKeyDisabledError { Message, Reason }
cmekForcedUnsafeTelemetryAttrKeys
forced_unsafe_cmek_gen.go

Enterprise customers can bring their own keys. forced_unsafe_cmek mode bypasses CMEK with telemetry tracking when the customer key is temporarily unavailable. The workspace_cmek_enabled claim in the JWT means the filestore backend knows at authentication time whether to expect customer-managed keys.

6.3 PiiString

PiiString.String()                  // returns redacted form
PiiString.GetSensitivePiiValue()    // returns raw sensitive value
PiiString.MarshalJSON()             // serializes redacted
PiiString.LogValue()                // log-safe representation

The <REDACTED_SENSITIVE_STRING_LEN_%s> format string confirms the redaction pattern.

6.4 Quota Enforcement

memory_store_bytes_limit_exceeded     store hit byte quota
memory_store_count_limit_exceeded     store hit memory count quota
memory_store_version_limit_exceeded   store hit version count quota

The function backend.isStoreQuotaExceeded enforces these before writes. No TTL, no LRU, no auto-eviction. When quota is hit, writes fail hard.


7. The Trust Boundary Lifecycle

This is the architectural tension at the center of the system.

trust boundary analysis · from encrypted storage to plaintext prompt✓ at rest — encryptedMemory Databaseenvelope encryptionAAD: org+account+storeor org+workspace+storeCMEK Supportcustomer-managed keysforced_unsafe fallbackwith telemetryVersioned StorageCREATED → MODIFIED → DELETEDredact nulls content,preserves lineageContent IntegritySHA-256 per memoryprecondition-basedoptimistic concurrency↓ decrypted by MemoryInternalService⚠ in transit — interceptedzstd compressionConnectRPCHTTP/2 + protobufTLS →api.anthropic.comEgress ProxyTLS-terminates ALL4 Anthropic root CAs↓ injected via AGENT_MEMORY_PROMPT_OVERRIDE✗ at use — plaintextSystem Prompt InjectionAGENT_MEMORY_PROMPT_OVERRIDEmemories as derived infoin memory_system blockModel Context Windowmemories visible to modelno content provenanceno source authenticationTool Call Contextall tools receiving thesystem prompt seethe memoriesProcess MemoryJWT credentials in rclone-filestore heap — readable via /proc/PID/memno signature proves the memory was unmodified between storage and injection🔒 quota enforcementmemory_store_bytes_limit_exceeded · memory_store_count_limit_exceededmemory_store_version_limit_exceeded · backend.isStoreQuotaExceeded enforced pre-writeno TTL · no LRU · no auto-eviction — when quota is hit, writes fail at the hard wallthe encryption ends at the prompt — same attack, different substrate
fig 2 · the memory trust boundary lifecycle — production-grade crypto at rest (4 controls) and in transit collapses to plaintext at use (4 exposures); quota enforcement has no eviction path

7.1 At Rest — Encrypted

Envelope encryption with org-scoped AAD. CMEK for Enterprise. SHA-256 content integrity. Precondition-based optimistic concurrency. Append-only versioning. PII-aware string handling. Redaction that preserves lineage while nulling content.

This is production-grade crypto. Real protection against external attackers and cross-tenant access.

7.2 In Transit — Intercepted

ConnectRPC (HTTP/2 + Protobuf) over TLS to api.anthropic.com. Content zstd-compressed. But the TLS terminates at Anthropic's egress proxy, which holds four root CAs injected into every cert store on the system. The proxy sees everything.

7.3 At Use — Plaintext

Memories are decrypted and injected into the system prompt via AGENT_MEMORY_PROMPT_OVERRIDE as a memory_system block. At this point:

The encryption ends at the prompt.


8. The Six Unknowns

The analysis above maps the peripheral nervous system. Six questions about the central nervous system remain unanswerable from inside the sandbox.

8.1 The Memory Controller

Known: The rclone-filestore binary has zero decision logic. It writes, reads, and searches — but nothing in the binary decides what to remember. SESSION_AGENT_OVERRIDES and CALLABLE_AGENTS suggest an orchestration layer that could host the observer. MemoryVersion.CreatedBy with SessionActor / ApiActor / UserActor would identify the controller — if we could observe who writes the memories.

Unknown: Whether synthesis is synchronous (model emits a tool call during conversation) or asynchronous (background process after conversation ends).

8.2 The Embedding Pipeline

Known: SearchMemoriesRequest sends a text Query with MaxResults, PathGlob, PathsOnly, and ContextLines. Zero embedding model, vector DB, or similarity metric references in the binary.

Unknown: Everything. Embedding model identity, vector storage engine, similarity algorithm, sharding strategy.

8.3 The Prompt Format

Known: Memories arrive as "derived information" in a memory_system block. MEMORY_VIEW_BASIC vs FULL suggests two-phase retrieval.

Unknown: Exact format, priority ordering when memories conflict, token budget allocation, retrieval strategy.

8.4 Consolidation

Known: UpdateMemory with preconditions enables safe overwrite. MemoryMetadata.LineCount suggests fact-list storage.

Unknown: Whether there's a summarization loop that consolidates raw conversation into refined memories over time.

8.5 The Backend

Known: Dual service layers. Zstd compression. AAD envelope encryption. CMEK. Three quota limits.

Unknown: Database engine, caching layer, key management infrastructure.

8.6 Eviction

Known: Three hard quota walls. ARCHIVE_STORE for mothballing. No TTL, no LRU, no decay.

Unknown: What happens when quota is hit. Whether the orchestrator implements eviction logic, or whether writes simply fail.


9. Architecture Map

┌────────────────────────────────────────────────────────────────────────┐
│                     ANTHROPIC BACKEND (UNKNOWN)                       │
│  ┌──────────────┐  ┌──────────────┐  ┌────────────────────────────┐  │
│  │  Embedding   │  │  Memory DB   │  │  Memory Controller /       │  │
│  │  Model (?)   │──│  Engine (?)  │──│  Observer Model (?)        │  │
│  └──────────────┘  └──────────────┘  └────────────────────────────┘  │
│                           │                                           │
│  ┌────────────────────────┴───────────────────────────────────────┐   │
│  │   MemoryInternalService + MemoryService (ConnectRPC)          │   │
│  └────────────────────────┬───────────────────────────────────────┘   │
│  ┌────────────────────────┴───────────────────────────────────────┐   │
│  │   Egress Gateway — TLS Interception (4 root CAs)              │   │
│  └────────────────────────┬───────────────────────────────────────┘   │
└───────────────────────────┼──────────────────────────────────────────┘
                            │
┌───────────────────────────┼──────────────────────────────────────────┐
│     FIRECRACKER microVM — Linux 6.18.5 — root, all caps, no MAC    │
│                            │                                         │
│  ┌─────────────────────────┴──────────────────────────────────────┐  │
│  │  rclone-filestore (Go, PID 491)                                │  │
│  │  ├─ rawMemoryClient (ConnectRPC)   ├─ LRU cache               │  │
│  │  ├─ Filestore backend              ├─ Quota enforcement        │  │
│  │  ├─ Memory backend (rclone-memory) └─ Session Vault JWT        │  │
│  └─────────────────────────┬──────────────────────────────────────┘  │
│                            │ FUSE                                     │
│  ┌─────────────────────────┴──────────────────────────────────────┐  │
│  │  /mnt/user-data/outputs (rw)  ·  /mnt/user-data/uploads (ro)  │  │
│  │  /mnt/transcripts (ro)        ·  /mnt/user-data/tool_results  │  │
│  └────────────────────────────────────────────────────────────────┘  │
│  ┌────────────────────────────────────────────────────────────────┐  │
│  │  process_api (Rust/Tokio, PID 1)                               │  │
│  │  ├─ WebSocket server (:2024)    ├─ Control server (:2025)     │  │
│  │  ├─ CA injection engine         ├─ OOM polling (100ms)        │  │
│  │  └─ Firecracker init            └─ gVisor UDS alternative     │  │
│  └────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────────┘

Methodology

Static analysis: - strings /opt/rclone/rclone-filestore — 30MB Go binary. Protobuf schemas, Go symbol names, embedded constants. - strings /proc/1/exe — Rust binary (process_api). Tokio/hyper/tungstenite, CA injection paths, WebSocket protocol. - cat /tmp/rclone-mount-config.json — Mount configuration with conversation-scoped filesystem ID. - /proc/PID/status, /proc/PID/environ, /proc/PID/cmdline, /proc/PID/maps — Process introspection. - openssl s_client + openssl x509 — TLS certificate chain inspection across multiple destinations. - awk extraction from /etc/ssl/certs/ca-certificates.crt — CA cert enumeration and Anthropic root identification. - mount, /proc/net/tcp — Network and filesystem topology. - Cgroup files under /sys/fs/cgroup/ — Resource limits.

Dynamic analysis: - rclone-filestore help backends — Discovered memory backend and its configuration contract. - rclone-filestore help backend rclone-memory — Extracted memstore_... and sk-ant-mem-... token formats. - Python script reading /proc/491/mem — JWT extraction from process memory with regex scan of heap regions. - JWT header/payload decoding — Identity model reconstruction from ES256-signed tokens.


Disclosure

The credential exfiltration finding (CWE-522) documented in Section 5 is pending responsible disclosure to Anthropic. JWT values shown are redacted to safe structural fields only — no subject identifiers, organization IDs, or secret values. The relay fleet finding (348 unauthorized transparent proxies to api.anthropic.com) is documented separately under TLP:AMBER.


same attack. different substrate.