VectorPin v0.1.1 · alpha
◉ open integrity standard since 2026 · Apache 2.0

Pin every
embedding you store.
Catch every
vector that's been tampered.

Vector databases are the soft underbelly of the AI stack — models trust them, agents query them, audits don't ask about them. VectorPin binds every embedding to its source text and producing model with an Ed25519 signature. Steganographic exfiltration, silent rotation, ingestion poisoning — all break the pin the moment a single float is touched.

byte-compatible across Python Rust TypeScript
pin № 0042 ✓ verified
source
"The quick brown fox."
sha256:9e2a…dd42 · NFC bytes

modeltext-embedding-3-large vector3072 × f32 · LE signeded25519 · prod-2026-05 at2026-05-07T14:31:08Z
~/audit
$ vectorpin audit-lancedb
✓ 18,442 pinned
✓ 18,440 ok
✕ 2 VECTOR_TAMPERED
  └ exit 1
overhead
42 µs/verify
3072-dim, x86_64

failure modes
7 · each routable
"A vector that nobody attests to is a vector that anybody could have written." — sign at the source.
§ what we're stopping

The vector store doesn't inspect what's written. That's the attack surface.

The companion VectorSmuggle research project demonstrates each of these in the wild. Every technique requires modifying the vector after the model produces it. Cryptographic pinning is the kill shot.

T-01 demonstrated

Steganographic exfiltration

An attacker with write access encodes secrets into vectors via rotation, scaling, or noise injection. The data leaves disguised as ordinary embeddings.

T-02 common

Ingestion poisoning

A compromised pipeline injects tampered vectors into the store. Downstream RAG retrieves them and the agent quotes the attacker's words.

T-03 emerging

Silent model rotation

The embedding model gets swapped in production. Old vectors and new vectors share a database. Nothing logs the cutover. Search quality silently collapses.

§ the kill shot

Touch a single float. Watch the pin break.

Below is a 32-cell view of an embedding pinned at ingest time. Drag any cell up or down to perturb a dimension — the cryptographic stamp flips the moment the vector hash changes.

embedding · 32 of 3072 dims shown
dim[0] ↕ drag any cell up or down to perturb a dimension · double-click to reset dim[31]
verifier output
✓ pin valid
ed25519 ✓ · sha256(vector) matches
verifier
> verifier.verify(pin, vec)
  outcome:  OK
  signed_at:2026-05-07
  by:       prod-2026-05

"Every steganographic technique requires modifying the vector after the model produces it." — from the spec.

§ quickstart

Three languages. One wire format.

Python, Rust, and TypeScript are byte-for-byte compatible. A pin produced by any of them verifies on the other two — locked together by shared test vectors in CI.

python/pin.py
from vectorpin import Signer, Verifier

signer = Signer.generate(key_id="prod-2026-05")
embedding = my_model.embed("The quick brown fox.")

pin = signer.pin(
    source="The quick brown fox.",
    model="text-embedding-3-large",
    vector=embedding,
)

verifier = Verifier({signer.key_id: signer.public_key_bytes()})
result = verifier.verify(pin, source="The quick brown fox.", vector=embedding)
assert result.ok
✓ pin signed · 35 µs · ed25519 prod-2026-05 0.04s
§ adapters

Audit the store you already run.

The adapter protocol is intentionally thin. vectorpin audit-* commands print a JSON summary on stdout and exit non-zero on any verification failure, so they compose cleanly into CI or a cron job.

backend status notes install
LanceDB default alpha default · embedded · file-based · native metadata column pip install 'vectorpin[default]'
Chroma alpha source text from metadata key pip install 'vectorpin[chroma]'
Pinecone alpha managed · cloud-native pip install 'vectorpin[pinecone]'
Qdrant alpha server-side payload filtering pip install 'vectorpin[qdrant]'
pgvector planned Postgres extension
FAISS planned use LanceDBAdapter (embedded, native metadata)