Skip to content
VoidNote
Announcement

2 March 2026

Void Streams: encrypted live chat and a better way to give secrets to AI agents

A Void Stream is a live encrypted channel that self-destructs when it closes. Use it to chat securely between two devices — or to hand a bundle of environment variables to a coding agent that will never actually see the keys.

What is a Void Stream?

A Stream is a one-way or two-way live channel where every message is encrypted before it leaves your device. The server sees only ciphertext. When the stream closes — by your choice, or when it expires — every message is destroyed. There is no history, no replay, no archive.

The decryption key is embedded in the stream URL itself, in the fragment (#...). Fragments are never sent to the server by the browser or any HTTP client — so the server is mathematically incapable of reading your messages.

Optional password protection adds a second layer: even if someone intercepts the stream URL, they still can't join without the password. That password is hashed with PBKDF2 at 100,000 iterations — brute-forcing it is not practical.

Device-to-device secure chat

The simplest use case: you're on your laptop, your phone is in another room (or country), and you need to send something sensitive — a password, an OTP, a code snippet — without it touching iCloud, Google Drive, Slack, or any other service that stores it indefinitely.

Create a stream, share the link, open it on the other device. Type a message, it appears instantly, encrypted end-to-end. Close the stream when you're done. Gone.

The VoidNote iOS and Android apps support streams natively. No account needed on the receiving end — just the link.

The problem with giving AI agents secrets

AI coding agents — Claude Code, Cursor, Copilot Workspace, custom agent loops — are genuinely useful for real work now. That means they need access to real secrets: deployment keys, database credentials, API tokens, third-party service keys.

The current options are all bad. Paste secrets into the context window and they end up in logs, conversation history, and model provider infrastructure. Point the agent at a .env file and it's on disk, often accidentally committed. Use a secrets manager and you're granting the agent a long-lived credential to the manager itself, which is now the single point of compromise.

What you actually want is: give the agent exactly the secrets it needs, for exactly as long as it needs them, and have those secrets self-destruct the moment they're consumed.

A VoidNote link as a bundle of environment variables

Here's the pattern. You create a note containing all the environment variables your agent needs for a given project:

# What you put in the note

DEPLOY_KEY=sk-proj-abc123...

DATABASE_URL=postgresql://user:pass@host/db

STRIPE_SECRET=sk_live_xyz789...

SENTRY_DSN=https://abc@sentry.io/123

You get back a URL like https://voidnote.net/n/abc123#secretkey. You paste that single URL into the agent's context, or your project's CLAUDE.md, or a CI environment variable.

The agent reads the note once using the SDK:

import

{ read } from 'voidnote-sdk';

// Agent does this at the start of the session

const env = await read(process.env.VOIDNOTE_ENV_URL);

// env = "DEPLOY_KEY=sk-proj-abc...\nDATABASE_URL=..."

// Parse and inject into process.env, or use directly

const vars = Object.fromEntries(

  env.split('\n').map(line => line.split('='))

);

The note burns. The agent has the values it needs in memory for the duration of the session. The next time the agent starts, it needs a fresh note — which you create fresh, with whatever keys you want to grant for that session.

The agent never sees a persistent credential. It sees a URL — dead after one read. Rotate credentials by creating a new note. The old URL is useless the moment it's been consumed.

Add a password for a second lock

Notes and streams both support an optional password. When set, even possessing the URL isn't enough — the reader must also know the password before the content is decrypted.

For agent workflows this is powerful: the URL lives in a config file or environment variable (which an attacker might find), but the password lives only in the agent's system prompt or is passed separately via a secure channel. Compromise of either alone yields nothing.

For human-to-human secure chat, you share the stream URL through one channel (say, email) and the password through another (say, SMS). An attacker who intercepts either channel still can't read the messages.

Streams as a live secret channel for agents

Notes are single-shot. Streams are continuous. If your agent workflow involves an ongoing session where you want to push new secrets mid-run — rotate a key, pass a one-time code, send a dynamic credential — a stream gives you a live encrypted channel to do that.

Create a stream, keep it open on your end, and have the agent listen for SSE messages. Every message is encrypted before it leaves your device and decrypted only in the agent process. You can push key=value pairs in real time. Close the stream when the session is done — all messages are gone.

# Push a new secret mid-session

echo "GITHUB_TOKEN=ghp_newtoken123" | voidnote pipe <stream-url>

# Agent picks it up instantly via SSE — encrypted, ephemeral

The zero-knowledge guarantee

This isn't a marketing claim. The cryptographic model is auditable:

note URL: voidnote.net/n/<tokenId>#<secret>

stream URL: voidnote.net/stream/<tokenId><secret>

key = SHA-256(secret) ← derived locally, never transmitted

ciphertext = AES-256-GCM(plaintext, key, random_iv)

server stores: tokenId + ciphertext + iv ← cannot decrypt

The server cannot read your notes or stream messages. A subpoena to us produces only ciphertext. A breach of our database produces only ciphertext. The only way to read a note or stream is to have the URL.

All source code is open — the SDKs, the CLI, and the server are on GitHub. You can verify the crypto implementation yourself. You don't have to take our word for it.

Try it

Streams are live now. Create one from the dashboard — or from the CLI if you want to pipe output directly into a stream. The SDKs have full stream support if you want to integrate into your own agent loop.

Notes, vault, and streams are all available on the free tier (credit-based). Void Pro and Void Unlimited subscriptions remove credit limits entirely.