Preprint v1.2 · 6 May 2026 Zenodo · doi:10.5281/zenodo.20058255 Jascha Wanger · ThirdKey / Tarnover

Hidden in plain
floats. Embeddings are
the new exfil channel.

Production vector stores treat every embedding as an opaque numerical artifact. That assumption opens a quiet class of steganographic exfiltration attacks — and one of them, small-angle orthogonal rotation, defeats every off-the-shelf distribution-based detector we tested.

stage 01
document → M(·)
Embedded by a trusted model. Direction encodes meaning.
stage 02
v ↦ R · v
Attacker rotates by a keyed orthogonal R. Cosine preserved.
stage 03
store(v′)
Backup ships the rotated batch. No detector signal.
stage 04
R⁻¹ · v′ = v
Accomplice with the key inverts — full payload recovered.
§ 01 Abstract

Retrieval-augmented generation converts sensitive content into high-dimensional embeddings and stores them in vector databases that treat the resulting numerical artifacts as opaque. Major vector-store products do not appear to provide native or default controls for embedding integrity, ingestion-time distributional anomaly detection, or cryptographic provenance attestation.

We show this opens a class of steganographic exfiltration attacks: an attacker with write access to the ingestion pipeline can hide payload data inside embeddings using simple post-embedding perturbations — noise, rotation, scaling, offset, fragmentation, and combinations thereof — while preserving the surface-level retrieval behavior the RAG system exposes to legitimate users.

We evaluate these techniques across a synthetic-PII corpus on text-embedding-3-large, four locally hosted open embedding models, a cross-corpus replication on BEIR NFCorpus and a Quora subset (over 26,000 chunks combined), seven vector-store configurations, an adaptive-attacker variant, and a paraphrased-query retrieval benchmark.

Distribution-shifting perturbations are often caught by simple anomaly detectors; small-angle orthogonal rotation defeats distribution-based detection across every (model, corpus) pair tested. The constructive defense, VectorPin, cryptographically pins each embedding to its source content and producing model — any post-embedding modification breaks signature verification.

§ 02 Six techniques, one gap

Each attack hides a payload inside the floats that downstream similarity search treats as the ground truth.

Five perturb a clean embedding in place; one swaps embedding models per fragment. Only the structural-exception family — orthogonal rotation — is invisible to the distribution-based detectors trained on a held-out clean baseline.

4.1 · perturbation

Noise injection

Add v′ = v + 𝒩(0, σ²I). Capacity scales with σ; so does distributional shift.

σ ≥ 0.01AUC 1.000
4.2 · perturbation · structural exception

Orthogonal rotation ★

v′ = R·v for R ∈ O(d). Pairwise inner products and per-dim marginals are invariant.

35-point sweepAUC ≤ 0.53
4.3 · perturbation

Magnitude scaling

v′ᵢ = sᵢ · vᵢ. Direction preserved, norms shift. Detectable via norm statistics.

library defaultnoisy
4.4 · perturbation

Fixed offset

v′ = v + o. The shared offset moves the empirical centroid by o — immediately obvious.

‖o‖ = 0.05AUC 1.000
4.5 · architectural

Cross-model fragmentation

Split source across models {M₁…Mₖ}. No in-place perturbation; no statistical signal.

requires model attestation— stat. blind —
4.6 · combined

Sequential composition

noise → rotation → scaling → offset. Detector AUC tracks the most-detectable component.

dominated by offsetAUC 1.000
§ 03 Interactive · rotation steganography

Move the slider. The cloud rotates; the statistics don't.

Below: a batch of 80 vectors (shown in 2D for clarity — the real attack lives in ℝ³⁰⁷² via composed Givens rotations). Pick a perturbation family and watch how a statistical detector reacts. The pairwise-similarity heatmap stays clean under rotation because R preserves every inner product ⟨u,v⟩. Under noise, offset, or scaling it lights up.

Embedding cloud · before → after ·

mean cos(v, v′)
pairwise Δsim
‖Δμ‖  batch mean shift
Δσ²  variance shift
Detector AUC · IF + OCSVM proxy
0.50 · chance0.751.00 · trivial
UNDETECTED

Controls

|S − S′| · pairwise similarity delta18×18

S = cos(vᵢ, vⱼ) before. S′ = after. Brighter cells = bigger change. Under rotation: visually empty. Under offset / noise / scaling: structure or static.

What you are seeing. Rotation is an orthogonal map: ⟨Ru, Rv⟩ = ⟨u, v⟩ for every pair. Per-dimension marginals are also preserved when R is sampled with full rotational symmetry. That is why the trained Isolation Forest + One-Class SVM stay at chance AUC — and why a statistical defense alone cannot close this gap. The paper's answer: cryptographic provenance, not anomaly detection.

§ 04 Key empirical findings

Distribution-based defense closes most of the gap, except the rotation channel — until capacity grows enough that local manifold geometry betrays it.

Rotation sweep · 35 points
≤ 0.53AUC

Neither Isolation Forest nor One-Class SVM exceeds AUC 0.53 across the entire (θ, |Π|) sweep on small-angle orthogonal rotation.

Noise σ=0.01 · default OCSVM
1.000AUC

The σ-noise channel saturates the detector immediately past a useful capacity threshold. The stealth window is narrow.

Givens rotation capacity
⌊d/2⌋·bbits

Closed-form per-vector capacity ceiling for the disjoint-Givens keyed-pair encoder. At d = 3072, that is 1,536 channel slots per embedding.

Cross-corpus replication
26k+chunks

BEIR NFCorpus (medical) + a Quora subset. Rotation still indistinguishable; the result is not a quirk of one corpus.

int8 quantization round-trip
0.000Δcos

Qdrant-default per-dimension int8 quantization preserved cosine to three decimal places across every technique tested.

Vendor capability survey
0 / 7defenses

No surveyed vector store ships native vector-content integrity, ingestion anomaly detection, or provenance attestation by default.

§ 05 The constructive defense · VectorPin

Pin every embedding to its source content and its producing model with one Ed25519 signature.

VectorPin is a minimal cryptographic provenance protocol: one signature, one hash family, a fixed canonical byte form for floating-point arrays. Reference implementations exist in Python and Rust, locked together by cross-language test vectors that guarantee bit-for-bit compatibility. Verification distinguishes signature forgery, vector tampering, source mismatch, and model substitution as distinct outcomes.

Pin attestation · canonical wire form

// signed by issuer.ed25519_priv { "v": 1, "model": "text-embedding-3-large@2024-01", "source_hash": "sha256:9f4c…", // source bytes "vec_hash": "sha256:1a82…", // canonical f32 LE "issuer": "did:key:z6Mk…", "ts": "2026-05-06T12:14:00Z", "sig": "ed25519:0x8e…b2" }

The vec_hash commits to the model's actual output bytes. Any post-embedding modification — every technique on this page — changes vec_hash and triggers VECTOR_TAMPERED on verification.

Verification · per-attack outcome

Noise injection
VECTOR_TAMPERED
Orthogonal rotation
VECTOR_TAMPERED
Magnitude scaling
VECTOR_TAMPERED
Fixed offset
VECTOR_TAMPERED
Cross-model fragmentation
MODEL_MISMATCH
Sequential composition
VECTOR_TAMPERED
Untouched issuer-signed vector
OK
Forged signature
SIG_INVALID

Limits, made explicit: VectorPin does not defend against an attacker who holds the private signing key, modifies source documents before embedding, or uses a legitimate signing key to attest a malicious vector at ingestion time. Key custody and upstream input validation remain the operator's job.