Irreversible voice de-identification, fully offline.
Website, wiki, and an in-browser hash verifier that never uploads your file. There is a JavaScript-free edition for readers who would rather not run scripts.
The whole site is static files in website/, so you can read it
offline if you cloned the repository, or if GitHub Pages is ever down: run
python3 tools/site/serve.py and open http://localhost:8000. For a real
server there is deploy/nginx.conf. The one number on the
site that must never be stale, the signing-key fingerprint, lives in the HTML,
so a local copy shows exactly what the source says.
Releases also carry a self-signed code certificate as a second, optional identity beside the OpenPGP key. It is trust-on-first-use, not a certificate authority, and it does not replace the OpenPGP check; what it adds is a publisher an organisation can import once to reduce low-reputation false positives, and an independent second signature. See docs/SELF_SIGNING.md.
VeilVoice destroys the biometric voiceprint of a speaker, meaning pitch, formants, timbre, micro-timing and the melody of an accent, so that neither software nor a human listener can re-identify the speaker or reconstruct the original voice, while the words themselves stay clean and transcribable.
There is no telemetry, no account, and no network code in the dependency graph, and CI fails the build if an HTTP client appears in it.
One thing reaches the network, and only when you press it. The desktop app has a check for updates button. It runs then and at no other time: no timer, no check at startup, nothing in the background. It sends nothing about you or your machine, it reads a public page anybody can open, and it downloads and installs nothing: it reports a version number and every decision after that is yours. There is still no HTTP client in the dependency graph: like the release verifier, it borrows the transfer tool your operating system already ships.
Anonymising, scrambling, encrypting and every other thing VeilVoice does still talk to no servers at all.
- Anonymise a recording. Wav, mp3, flac, ogg, m4a and friends in; a clean WAV out, with metadata stripped.
- Scramble your microphone live and route the result to a virtual audio cable, so any application, whether a call, a stream or a recorder, receives the veiled voice instead of yours.
- Encrypt recordings at rest, by default. Every file VeilVoice writes is sealed with post-quantum-hybrid cryptography unless you explicitly turn that off, and turning it off makes you read why first.
- Lock the app behind a separate password, so someone who picks up your unlocked computer cannot open it. See the honest limits below.
- Detect tampering with VeilVoice's own files, and say plainly when it cannot tell you which program did it.
- Strip identifying metadata from audio and images (EXIF, GPS, tags).
- Watch what is listening. See every application currently holding your microphone or camera, with alerts the moment one starts.
- Securely erase a recording, with an honest account of what that is worth on flash storage.
- Work as a Rust library in your own project. See below.
"Fill the whole spectrogram with white noise" and "stay understandable and transcribable" are mutually exclusive, because noise that covers the voice covers the words. VeilVoice therefore targets the achievable goal: irreversible speaker de-identification with intelligibility preserved on purpose. If the message also needs to be secret, encrypt it. That is a separate problem with a separate answer.
The same honesty applies to accent. VeilVoice maps every speaker onto one canonical pitch register, vocal-tract scale and spectral tilt, so an accent's melody and colour do not survive. What no signal-level transform can change is which phonemes you actually produced, and at that level the accent and the words are the same thing.
And to the app lock. It is an Argon2id password verifier with a rate limit, and it protects against casual access, meaning the person who picks up your unlocked laptop. It is not tamper-proof and it is not disk encryption: anyone who can write to your files can delete the lock, and anyone holding the drive can attack the stored hash offline. VeilVoice says this on the unlock screen itself rather than in a footnote. If the disk is the threat, encrypt the volume.
The full argument, and everything an attacker can still learn, is in
docs/WHITEPAPER.md.
Every picture below is of this build. The window captures are taken by
tools/shots/gui.sh on Linux or tools/shots/gui.ps1 on Windows, either of
which drives the release build and photographs each tab; the terminal drawings
are generated from the command output committed beside them, and CI fails if a
drawing and its output disagree. See
assets/screenshots/README.md for why those two
are different kinds of thing.
Both scripts start the application once per tab with --tab <name> and
photograph it. There is no clicking and there are no coordinates, so a picture
cannot quietly end up showing the wrong tab. Neither script keeps a list of the
tabs either. veilvoice-gui --tabs prints them from the window's own, so one
added tomorrow is photographed without anybody remembering to add it.
The pictures committed here were taken on Linux, by tools/shots/gui.sh,
which runs the application under Xvfb with no window manager. Without one the
window is mapped at the origin at exactly the size it asks for, so the X root
window is the application window pixel for pixel and no cropping can include a
strip of desktop.
tools/shots/gui.ps1 is the Windows counterpart and takes the same pictures
with PrintWindow. It is what produced the captures up to v0.1.19.
Confirmed on Windows 11. That is the one this application has been run on by a person, rather than photographed by a script.
Windows 10 is supported and not yet confirmed, which is a different
sentence and is meant to be. Nothing in the desktop application needs anything
newer than Windows 10: the oldest interfaces it uses are DwmGetWindowAttribute
(Windows Vista), SetProcessDpiAwareness and PrintWindow with
PW_RENDERFULLCONTENT (Windows 8.1), and the two are only used by the
screenshot tool in any case. The application itself asks for nothing beyond
whoami, tasklist, taskkill and reg, all of which predate Windows 10 by
years. So it should run, and saying "it does" is not something this page will
claim until somebody has sat in front of one.
macOS and Linux build and their tests pass in CI, which is weaker still: a green test run is not a person using the window.
Everything the window does, and some things it does not.
Pick your system. Each one is a single command to get running, and a second path if you would rather build it and check the result against what was published.
Check the download before you run it. Every route below ends with that, because a privacy tool you have not verified is a privacy tool you are taking on faith.
Linux (any distribution)
# 1. Download the archive, the hash list and the signature.
V=v0.1.22
B=https://github.com/tilas01/veilvoice/releases/download/$V
curl -fsSLO $B/veilvoice-$V-linux-x86_64.tar.gz
curl -fsSLO $B/SHA256SUMS
curl -fsSLO $B/SHA256SUMS.asc
curl -fsSLO $B/veilvoice-signing-key.asc
# 2. Unpack and check it, from inside the folder.
tar xzf veilvoice-$V-linux-x86_64.tar.gz
cd veilvoice-$V-linux-x86_64
./veilvoice verify
# 3. Run it, or install it so `veilvoice` works in any terminal.
./veilvoice-gui
./veilvoice installinstall copies the programs into your own program directory and adds it to
PATH. No administrator rights, no service, nothing outside your account.
Restart your terminal afterwards, or the new PATH will not be in the one
you are using.
If the desktop application exits immediately saying a library could not be loaded, install it and try again. The window toolkit opens it by name at startup, so a minimal or server install often does not have it:
sudo apt install libxkbcommon-x11-0 # Debian, Ubuntu
sudo dnf install libxkbcommon-x11 # Fedora, RHEL
sudo pacman -S libxkbcommon-x11 # ArchThe command line needs none of this. On a distribution nothing else fits, take
the musl-static archive: it needs no system libraries at all.
macOS (Intel and Apple Silicon)
V=v0.1.22
B=https://github.com/tilas01/veilvoice/releases/download/$V
# arm64 for Apple Silicon, x86_64 for Intel.
curl -fsSLO $B/veilvoice-$V-macos-arm64.tar.gz
curl -fsSLO $B/SHA256SUMS
curl -fsSLO $B/SHA256SUMS.asc
curl -fsSLO $B/veilvoice-signing-key.asc
tar xzf veilvoice-$V-macos-arm64.tar.gz
cd veilvoice-$V-macos-arm64
./veilvoice verify
./veilvoice-guimacOS will refuse an unsigned download the first time. Right-click the program and choose Open, rather than turning Gatekeeper off.
Windows (10 and 11)
$V = "v0.1.22"
$B = "https://github.com/tilas01/veilvoice/releases/download/$V"
curl.exe -fsSLO "$B/veilvoice-$V-windows-x86_64.zip"
curl.exe -fsSLO "$B/SHA256SUMS"
curl.exe -fsSLO "$B/SHA256SUMS.asc"
curl.exe -fsSLO "$B/veilvoice-signing-key.asc"
Expand-Archive "veilvoice-$V-windows-x86_64.zip" -DestinationPath .
cd "veilvoice-$V-windows-x86_64"
.\veilvoice.exe verify
.\veilvoice-gui.exe.\veilvoice.exe install puts it on your PATH. Open a new terminal
afterwards: an existing one keeps the PATH it started with.
WSL
WSL is Linux, so the Linux instructions apply unchanged and veilvoice works
exactly as it does there. Two differences worth knowing:
- The window needs WSLg, which recent Windows has by default.
- A microphone belongs to Windows, not to the distribution, so live mode is the Windows build's job. Use the Windows download for that.
FreeBSD, OpenBSD, NetBSD
The command line only. The audio library has no BSD backend, so live capture cannot work and the window is not shipped. Everything that operates on a file runs exactly as it does elsewhere.
V=v0.1.22
fetch https://github.com/tilas01/veilvoice/releases/download/$V/veilvoice-$V-freebsd-x86_64.tar.gz
tar xzf veilvoice-$V-freebsd-x86_64.tar.gz
cd veilvoice-$V-freebsd-x86_64
./veilvoice verifyBuild it yourself, and prove it matches
A fresh clone needs no secrets:
git clone https://github.com/tilas01/veilvoice && cd veilvoice
cargo build --releaseTo prove your build is the published one, byte for byte:
veilvoice verify --build-script > reproduce-veilvoice.sh
sh reproduce-veilvoice.sh v0.1.22That clones the tag, builds it with the committed lockfile and the commit's own date, and compares the result with the release. If it does not match, the script says which file differed. Before reporting it, check the three things that cause a mismatch on an otherwise honest machine:
- A different compiler. The version is pinned in
rust-toolchain.tomlandrustuphonours it automatically. Withoutrustup, you may be building with something else. RUSTFLAGSset in your environment, which changes codegen.- A dirty checkout. The script clones fresh for exactly this reason; if
you built by hand,
git statusshould be clean.
If all three are ruled out, that is worth reporting, and
docs/REPRODUCIBLE_BUILDS.md explains what is
pinned and why.
| If you have | Read |
|---|---|
| an archive you just downloaded | Checking a download |
| a terminal | The command line |
| a window | The desktop application |
| all of it | The full user guide |
Also: installing in detail, packaging it yourself, reproducible builds.
veilvoice-guiTen tabs: anonymise a file, group conversations, the Studio, which scrambles a microphone live and records into the vault, browse what is in that vault, who is using the microphone and camera, the app lock, verify a download, settings, portable or installed, and an about panel that states the scope. Nine palettes, or your own, and every screen is captured under What it looks like.
veilvoice anonymise recording.mp3 -o clean.wav # writes clean.wav.veil, sealed
veilvoice anonymise recording.mp3 --encrypt-to friend.pub
veilvoice anonymise recording.mp3 --encrypt false # warns first
veilvoice live --output "CABLE Input (VB-Audio Virtual Cable)"
veilvoice devices
veilvoice clean photo.jpg
veilvoice encrypt secret.wav
veilvoice decrypt clean.wav.veil -o clean.wav
veilvoice keygen
veilvoice lock set # password-gate the desktop app
veilvoice lock status
veilvoice guard init --sealed # record what the files should be
veilvoice guard check # and see whether they still are
veilvoice watch # who is using the mic and camera
veilvoice shred secret.wav # irreversibleEvery command takes --help.
anonymise seals its result into a .veil container rather than writing a bare
WAV, because de-identification and confidentiality are different problems and
only the first one is solved by the engine: the words survive on purpose, so
an unencrypted result is still a recording of everything that was said.
The WAV is encoded in memory and sealed there, so a recording that is going to be
encrypted never touches the disk in the clear, not even for a moment, because a
plaintext file that is written and then deleted is exactly what
veilvoice shred explains cannot be
reliably taken back on flash storage.
Passing --encrypt false still works. It prints what you are giving up and, on
a terminal, waits for you to type UNENCRYPTED.
De-identifying your voice on a call achieves little if a second program is
recording the raw microphone at the same time. veilvoice watch names what is
holding your microphone and camera, and alerts the moment something starts:
● veilvoice is now using your microphone
Windows reads the same records that drive the OS privacy indicator; Linux reads
open handles under /proc. macOS exposes no public interface for this, so
nothing is reported there rather than something guessed: the tool tells you it
cannot see, because an empty list from a blind monitor is a false reassurance.
Live mode veils your microphone and writes the result to an output device. To put that into a call, the call has to be able to read that output, and an operating system will not normally let one program's output be another's input. A virtual audio cable is a device that exists only in software: VeilVoice writes to one end, and Zoom, Discord, OBS or anything else picks its microphone as the other.
None of these is written by this project, none is bundled, and each is under its own licence. Install whichever your system uses, then in VeilVoice choose your real microphone as the input and the cable as the output, and in the call choose the cable as the microphone.
Where this does not apply. The FreeBSD, OpenBSD and NetBSD archives have no
live microphone mode at all, because cpal, the audio device library, has no
backend for them. The BSD sections below are there so that somebody on one of
those systems knows that rather than hunting for a cable that would not help.
Run veilvoice info on any platform and it says what that build supports.
Windows 10 and 11
VB-CABLE by VB-Audio Software. Proprietary donationware, free to use. One cable, and the usual choice.
- Download from vb-audio.com/Cable and unzip it.
- Right-click
VBCABLE_Setup_x64.exeand choose Run as administrator. It needs that to install a driver. - Reboot. Windows will not show the device until you do.
- In VeilVoice: input your microphone, output CABLE Input (VB-Audio Virtual Cable).
- In the call: microphone CABLE Output (VB-Audio Virtual Cable).
To hear yourself while you talk, turn on Listen to this device for CABLE Output in Windows sound settings and point it at your headphones.
Voicemeeter, by the same author, is the larger version: several cables plus a mixer, for feeding more than one program at once. Same licence.
Virtual Audio Cable by Eugene Muzychenko is the long-standing commercial alternative, with a trial that adds a spoken reminder to the audio.
veilvoice install on Windows takes a -WithVBCable switch, which opens the
VB-CABLE download page in your browser. It downloads nothing itself and
installs nothing: VeilVoice does not install other people's drivers.
macOS (Intel and Apple Silicon)
BlackHole by Existential Audio. MIT licensed, open source, and a universal binary, so the same installer covers both Intel and Apple Silicon.
-
Install it with Homebrew:
brew install blackhole-2ch
or download the signed installer from existential.audio/blackhole. The source is at github.com/ExistentialAudio/BlackHole.
-
In VeilVoice: input your microphone, output BlackHole 2ch.
-
In the call: microphone BlackHole 2ch.
To hear yourself as well, open Audio MIDI Setup, create a Multi-Output Device containing BlackHole and your headphones, and send VeilVoice there instead.
The 16-channel and 64-channel builds (blackhole-16ch, blackhole-64ch) exist
for larger routing setups and are installed the same way. Two channels is what
a call needs.
Loopback by Rogue Amoeba is the commercial option, with a graphical patchbay and a free trial that degrades the audio after twenty minutes. Soundflower, which older guides still recommend, is unmaintained and is not a good choice on a current macOS.
macOS will ask for microphone permission the first time. That is the real microphone, not the cable.
Linux (any distribution)
PipeWire is almost certainly already running: it is the default on Fedora, Ubuntu since 22.10, Debian 12, Arch and most others. Nothing to install, and the cable is one command.
-
Create the cable:
pw-loopback --capture-props='media.class=Audio/Sink node.name=veilvoice_cable' \ --playback-props='media.class=Audio/Source node.name=veilvoice_cable_out'
Leave that running. It disappears when you stop it, which is the tidy way round: nothing is installed and nothing survives a reboot.
-
In VeilVoice: input your microphone, output veilvoice_cable.
-
In the call: microphone veilvoice_cable_out.
A graphical patchbay makes the wiring visible and is worth having: qpwgraph or Helvum, both packaged nearly everywhere.
On PulseAudio, if your distribution still uses it:
pactl load-module module-null-sink sink_name=veilvoice_cable \
sink_properties=device.description=VeilVoice_CableVeilVoice outputs to VeilVoice_Cable; the call takes Monitor of VeilVoice_Cable as its microphone. pactl unload-module with the number that
command printed removes it again.
On JACK, connect VeilVoice's output port to the
call's input port in qjackctl or Carla. PipeWire provides a JACK interface,
so this works without running JACK itself.
FreeBSD, OpenBSD and NetBSD
The BSD builds have no live mode, so no cable will make one appear. cpal
has no BSD backend, which the archive's own notes and veilvoice info both
say. Everything else works: anonymise, clean, encrypt, decrypt, keygen,
conversation rendering and verification.
Recorded on the roadmap as a real gap rather than a decision. If you want to route audio on these systems for other reasons, this is what people use:
- FreeBSD:
virtual_oss, in ports asaudio/virtual_oss, creates virtual devices in front of a real one. PulseAudio and PipeWire are both in ports as well. - OpenBSD: sndio, which is part of the base
system.
sndiodsub-devices route audio between programs with no third-party driver at all. - NetBSD: the
pad(4)pseudo-device, again in the base system, presents an audio device whose output another program can read.
Worked examples, with the licence implications spelled out, are in
docs/USING_THE_CRATES.md. Every example there is
a real file under crates/*/examples/, compiled on every commit, so none of it
can quietly stop being true:
cargo run -p veilvoice-core --example veil_a_buffer
cargo run -p veilvoice-crypto --example seal_and_openEvery crate is a normal Rust library. Point Cargo at the repository:
[dependencies]
veilvoice-core = { git = "https://github.com/tilas01/veilvoice" }
veilvoice-audio = { git = "https://github.com/tilas01/veilvoice" }| Crate | What it gives you |
|---|---|
veilvoice-core |
The de-identification engine. No I/O, no threads, allocation-free process(). |
veilvoice-audio |
Device enumeration, file decode/encode, live capture→process→playback. |
veilvoice-crypto |
Argon2id, X25519+ML-KEM-768 hybrid, XChaCha20-Poly1305, page-locked secrets, the app-lock verifier, and the decoy passphrase. |
veilvoice-meta |
Metadata stripping for audio and images. |
veilvoice-conversation |
Several speakers in one recording: a voice each, names, and subtitles. |
veilvoice-video |
The conversation made watchable: a waveform, a circle per speaker, subtitles, and what the graphics hardware here can encode. |
veilvoice-policy |
The settings VeilVoice keeps: policies that can only be tightened, and the named profiles and projects a recording was made with. |
veilvoice-setup |
Per-user install and its exact reversal, the optional companion software, and whether a newer release exists. |
veilvoice-verify |
A release checked end to end: the signed hash lists, the contents manifest, and the same three checks through your own GnuPG. |
veilvoice-guard |
Has anything touched what was meant to be left alone: the integrity manifest, ransomware canaries, and the failsafe that acts when another program takes a real microphone. |
veilvoice-watch |
What else this machine is doing: the microphone and camera, screen recorders, keyboard and mouse, kernel drivers, the process list and the privilege this is running at. |
veilvoice-gui |
The desktop application. A library so its own tests can reach it, rather than something to build on. |
The engine itself is small enough to drop into an audio callback:
use veilvoice_core::{DeidConfig, Deidentifier};
let mut deid = Deidentifier::new(DeidConfig::default())?;
let mut out = vec![0.0; block.len()];
deid.process(&block, &mut out); // no allocation, callback safeCloud transcription is genuinely useful and genuinely invasive: the provider receives a biometric identifier that is as durable as a fingerprint, and it usually keeps it. But transcription only needs the words, which is exactly the half VeilVoice preserves.
So run the audio through VeilVoice first. The service gets speech it can transcribe and a voiceprint that belongs to nobody:
use veilvoice_audio::{deidentify, io};
use veilvoice_core::DeidConfig;
// Your real voice never leaves this function.
let original = io::load(std::path::Path::new("dictation.wav"))?;
let veiled = deidentify(&original, DeidConfig::default())?;
io::save_wav(std::path::Path::new("safe-to-upload.wav"), &veiled)?;Or from the shell:
veilvoice anonymise dictation.wav -o safe-to-upload.wavTwo caveats, stated plainly. Accuracy drops somewhat, because the output is synthetic-sounding, and recognisers are trained on natural speech. And the words still go to the provider: this protects your identity, not the content of what you said. If the content is sensitive too, do not upload it at all: transcribe locally.
Local transcription is the stronger answer and is a planned integration (see
ROADMAP.md); until then, whisper.cpp reads the WAV VeilVoice
writes with no extra work.
-
Offline by construction. Zero servers, enforced in CI.
-
No
unsafeanywhere. Every crate carries#![forbid(unsafe_code)], including the page-locking path. -
62334 functional lines of Rust, across 28 crates. A functional line is a line holding code: blank lines and lines holding only a comment are not counted, and a line with code and a trailing comment counts once. Each crate's own README states its share of that total under The files.
It is a smaller number than the length of the tree, and deliberately so. This project is written with a high comment-to-code ratio, and the per-file line counts printed on the generated pages, in the artwork and in the reference links are the other measure, the length of the file. Both are stated with their definitions rather than one being quietly redefined to match the other, and both come from
tools/loc/count.py. The 28 includesfuzz/, the harnesses, which is a Cargo project of its own rather than a workspace member. -
Irreversible. Each frame's measured phase is discarded and resynthesised, permanently destroying the speaker's waveform and micro-timing.
-
Normalising, not just scrambling. Pitch register, vocal-tract length and spectral tilt are each collapsed onto one canonical target, so a whole population of speakers maps to the same output. That destroys information rather than moving it.
-
Cryptographically modulated, with a rolling seed. The residual transform is driven every frame by a ChaCha20 CSPRNG whose seed never leaves the process, and that seed is ratcheted forward every couple of seconds, so each stretch of audio is sealed off behind a one-way step rather than sharing one stream with the whole recording. Configurable, and inaudible by construction.
-
Post-quantum ready, and on by default. At-rest encryption is X25519 + ML-KEM-768 hybrid, because a recording stored today may be attacked decades from now, and it is what
anonymisedoes unless you say otherwise. -
Amnesic. Secrets are page-locked out of swap, zeroized on drop, compared in constant time, and opaque to
Debug. -
Reproducible & verifiable. Pinned toolchain, committed lockfile, path-remapped builds, and a double-build check in CI.
-
Libre. GPL-3.0-or-later.
| Crate | Purpose |
|---|---|
veilvoice-core |
De-identification DSP engine and accent neutralisation, the security-critical heart. |
veilvoice-crypto |
Argon2id, X25519+ML-KEM-768 hybrid, XChaCha20-Poly1305, amnesic secrets, and the decoy passphrase. |
veilvoice-audio |
Capture/playback (cpal), virtual-cable routing, file import/export. |
veilvoice-meta |
Metadata strip/spoof for audio and image EXIF/GPS. |
veilvoice-conversation |
Who spoke when, one destination voice each, WebVTT and SubRip subtitles. |
veilvoice-video |
The conversation drawn and played back, and what this machine's graphics hardware can encode. ffmpeg muxes it. |
veilvoice-policy |
Settings fixed so the interface cannot turn them off, and the named profiles a recording can be repeated from. |
veilvoice-setup |
Per-user install, PATH, removal, companion detection and the update check, shared by both front ends. |
veilvoice-verify |
Hash, signed list and detached signature, with no GnuPG on the machine or through the one you have. |
veilvoice-guard |
The integrity manifest, the canaries, and the safety catch. Detects and reacts; prevents nothing, and says so. |
veilvoice-watch |
Everything else running here: microphone and camera, screen recorders, input, drivers, processes, privilege. |
veilvoice-cli |
The veilvoice command-line tool. |
veilvoice-gui |
The desktop app (egui, Tokyo Night). |
Artwork is generated, not committed as opaque blobs:
python assets/generate.py reproduces every icon and the banner from source.
v0.1.22: early but real. The engine, cryptography, audio path, metadata
cleaning, at-rest encryption, app lock, tamper detection, encrypted-volume
destinations, CLI and GUI are implemented and tested (1659 tests across 13
crates plus doctests, and 20 website suites, clippy clean, no unsafe), with
randomised campaigns against every parser that reads untrusted input and
against the website's Markdown renderer. Release binaries are built for eleven
targets, each one built twice from a copy of the source at a different path and
compared byte for byte. At v0.1.19 all eleven reproduced, the three BSDs
included: those were the last three to be built only once, and the release
notes carry the verdict each platform actually reached rather than a claim
about all of them.
Audited by tilas01, who wrote and reviewed it. Be clear about what that is worth: a maintainer audit catches what the author can see, and no external firm or independent researcher has reviewed this code. Read the source before relying on it for anything that matters. It is written to be read.
Thirty-three audit rounds have found and fixed 196 defects.
Among them: a four-kilobyte file that killed the process, a configuration value that made every output sample silent, a secure erase that
destroyed a file other than the one named, a locked encrypted volume that went
on accepting recordings onto the ordinary disk, and two ways to freeze a
reader's browser tab. None in any round was a confidentiality failure in
the strict sense that nothing let an attacker recover a voiceprint, read a
sealed recording, bypass a password or weaken the cryptography. The two
encrypted-volume defects came closest, and docs/AUDIT.md is exact about which
side of that line they fall on rather than leaving the claim to do the work. Every one is written up individually, including
the ones earlier rounds had declared clean, in
docs/AUDIT.md.
Found something? Report it privately through
GitHub's security advisories
rather than as a public issue. docs/SECURITY.md says what
counts as a vulnerability here, what is a documented limitation rather than
one, and why there is no PGP address to send it to.
Using it: docs/USER_GUIDE.md, or
the wiki.
Roadmap and open work: ROADMAP.md.
Written and maintained by tilas01, who holds the copyright and is the sole author for licensing purposes. The architecture, every decision about what this program does and refuses to do, and a great deal of the code are theirs directly.
Some of the code, the documentation and this website were drafted with the help
of Claude, Anthropic's assistant, working to that direction. Nothing reaches
a release unread: every change is reviewed, built and tested before it is
committed, and the audit rounds in docs/AUDIT.md are the
record of that review finding its own mistakes.
The credit is stated here, and once more in the "Who wrote it" answer on the questions page. Those are the two places somebody looking for it will look. It is deliberately not repeated in the footer of every page or scattered through the commit log, where an acknowledgement turns into a badge.
GPL-3.0-or-later. See LICENSE.
None of the virtual audio cables listed under
Route it into a call is bundled here, and none of them
is ours. Each is somebody else's software under its own licence, named there
with what that licence is. The same goes for ffmpeg, which the video render
asks for its last step and which is not shipped, not vendored and not linked
against: veilvoice companions names it, its vendor and its licence beside the
rest, and installs it through the package manager your machine already has.










