Azimut keeps a whole open-source investigation in one plain folder on your own machine: the media you collected, the examination you ran on it, the geolocation you established, the entities and links you confirmed, the notes you wrote, and the exports you published.

It runs as a small server on 127.0.0.1 plus a normal browser tab. No account, no telemetry, no automatic upload. It is free and open source under AGPL-3.0.
This guide covers the whole install: every path (ready-to-run binary, pipx, from source), what happens on first launch, the settings worth a minute, the optional capture extension, and what to do when something goes wrong. It is written to stay valid across releases, so it names no version numbers.
If you only want it running, you do not need the whole page. These are the parts most people come for:
- Path A: the ready-to-run binary – the fastest way in, nothing to install first
- Path B: install with pipx – one line if you already have Python
- Your workspace folder – where your cases live, and why upgrades never touch them
- Worth setting up on day one – the four settings that pay off immediately
- Optional: the capture extension – map screenshots filed straight into a case
- Troubleshooting – the fix when something misbehaves
- What you can count on – the guarantees, and what Azimut will never do
What the tool is
A local OSINT workspace for reviewing media, building geolocation proofs and keeping case notes together. It is built for open-source investigators, journalists and researchers. Each case is a plain folder that can be reopened, archived or shared. Every tool works one-shot (a scratch session, no setup) or inside a case, a plain directory holding the whole investigation.
The name is the French word for azimuth, the compass bearing you sight along to fix a point on the map.
Where it stands
Not all of the picture above is built. Azimut ships one complete daily workflow per version, and the honest summary is this: the geolocation chain runs end to end today: collect, examine, locate, prove, publish, document and the broader investigation layer is the objective, not yet the state.
Two places tell you exactly where a given copy stands: docs/SPEC.md in the repository lists what is done and what is on the roadmap, in order, and the Releases page describes each version as it lands. A tab is either in your copy or it isn’t, and nothing in this install guide changes either way.
What it records
Underneath every tool is one graph, per case, in SQLite. Entities are typed (person, organization, alias or username, account, email, phone, domain, IP, vehicle, place, event, media, proof…) and so are the links between them (owns, appears-in, located-at, same-as, posted, mentions, and free labels you add). Everything carries provenance: which tool produced it, from which source, when, and whether it is confirmed by you or merely suggested by a tool.
That distinction is the design’s backbone. Tools suggest; only an analyst action confirms. Azimut never issues an automated geolocation verdict, and every artifact records how it was produced.
What it will never do
Stated plainly, because it shapes what you should expect:
- No cloud, no account, no hosted service, no telemetry.
- No automated verdict. Azimut files facts for you to judge.
- No rebuilding of specialized OSINT services. It orchestrates them and brings selected results into the case with provenance.
- No block-evasion scraping. Your own session cookies are in scope; third-party downloader proxies are not.
- No auto-posting. Threads are prepared, never sent on your behalf.
- No paid key required for core work. Bring your own for optional providers.
Before you install
Program and data are separate. The program is a binary you downloaded or a Python package in its own environment. Your data lives in a workspace folder, ~/Azimut by default, with one directory per investigation. Upgrading or uninstalling Azimut never touches it.
There is no desktop application. No window, no system tray, no installer wizard. Azimut prints a URL and opens your browser at it. Closing the terminal or console window stops the app.
Pick your path:
| Path | Best for | Needs |
|---|---|---|
| Ready-to-run binary | Most people. Nothing to set up, ffmpeg included. | Nothing |
pipx install azimut | You already use Python, or want pipx upgrade. | Python 3.11+ |
| From source | Contributing, or running unreleased code. | Python 3.11+, Node.js 20+ |
Path A: the ready-to-run binary (recommended)
Every release attaches a self-contained binary per operating system. Download the one for your platform from the Releases page; the asset names stay the same from release to release.
| OS | Asset |
|---|---|
| Windows | azimut-windows-x86_64.exe |
| macOS (Apple Silicon) | azimut-macos-arm64 |
| macOS (Intel, 14+) | No standalone binary. Use pipx or pip instead. |
| Linux | azimut-linux-x86_64 |
The Linux binary is built on the current Ubuntu LTS runner, so it needs glibc 2.39 or newer (Ubuntu 24.04 and up). On Debian 12 or Ubuntu 22.04 it will not start; use pipx install azimut there instead.
Put the file somewhere permanent: your home folder, ~/Applications, a tools directory. It does not care where it lives and it writes nothing next to itself, so a read-only location is fine.
The first-run security warning
The binaries are unsigned, so every OS stops you the first time you open one. This is expected, and each platform has its own way through.
Windows. Double-click the .exe. SmartScreen shows “Windows protected your PC”. Click More info, then Run anyway. Once per downloaded file.
MacOS. Double-clicking is refused outright. Either:
- right-click the file, choose Open, then Open again in the dialog — Gatekeeper only offers that button from the context menu for unidentified developers; or
- clear the quarantine flag once from Terminal:
xattr -d com.apple.quarantine ./azimut-macos-arm64
Linux. Mark it executable, then run it:
chmod +x azimut-linux-x86_64./azimut-linux-x86_64
What the binary includes
The downloadable binaries bundle a static ffmpeg and ffprobe, refreshed on every release build. Video thumbnails, frame scans, video enhancement and downloads that merge separate audio and video streams all work with nothing else installed. The bundled ffmpeg is redistributed under its own license; see ffmpeg.org/legal.html.
Path B: install with pipx (or pip)
With Python 3.11 or newer, Azimut installs from PyPI.
pipx install azimut # isolated app installazimut # starts on http://127.0.0.1:8477 and opens a browser tab
pip install azimut works too, but pipx is the better fit: the app gets its own environment, so Azimut’s dependencies never collide with your other Python projects.
Housekeeping:
pipx upgrade azimut # update to the latest releasepipx uninstall azimut # remove the app; your ~/Azimut data stays
One extra step: ffmpeg
A pip or pipx install does not bundle ffmpeg. Put ffmpeg and ffprobe on your PATH if you want video thumbnails, frame scanning, video enhancement, or downloads from sites that serve audio and video as separate streams. Everything else works without it.
# macOSbrew install ffmpeg# Debian / Ubuntusudo apt install ffmpeg# Fedorasudo dnf install ffmpeg# Windowswinget install ffmpeg
On Windows you can also unzip a static build from ffmpeg.org/download.html and add its bin folder to PATH.
Verify with ffmpeg -version in a new terminal. If your shell finds it, Azimut will too.
Path C: install from source
You need Python 3.11+ and Node.js 20+. The Svelte frontend is compiled into the Python package, so the frontend build is not optional: skip it and you get a server with no interface.
macOS and Linux:
git clone https://github.com/OsintMeThat/azimut && cd azimutpython3 -m venv .venv && .venv/bin/pip install -e ".[dev]"cd frontend && npm ci && npm run build && cd ...venv/bin/azimut
Windows PowerShell:
git clone https://github.com/OsintMeThat/azimutSet-Location azimutpy -3 -m venv .venv.venv\Scripts\python -m pip install -e ".[dev]"Set-Location frontendnpm cinpm run buildSet-Location ...venv\Scripts\azimut.exe
Rebuilding as you work
A cross-platform helper rebuilds the frontend, stops the previous Azimut instance it started, and launches the fresh build:
python3 scripts/relaunch.py # macOS / Linuxpy scripts\relaunch.py # Windows
It never kills unrelated processes by name. Add --no-browser to keep it from opening a new tab.
Frontend development with hot reload
.venv/bin/azimut --no-browser & # backend on :8477cd frontend && npm run dev # UI on :5173, API proxied
The checks CI runs
Before opening a pull request, run what the pipeline runs:
uv run ruff check src tests # lintuv run mypy # type-check the backendcd frontend && npm run check # svelte-check, blocks on errors
Every feature is expected to land with tests, so run the suite too.
– First launch –
However you installed it, starting Azimut prints two lines and opens a tab:
Azimut <version> · http://127.0.0.1:8477 (local only)Runs in your browser tab. Close this window to stop Azimut.
The tab opens once the server is actually accepting connections, so you never land on a “can’t connect” page.
If your default browser stays shut, paste http://127.0.0.1:8477 into Firefox or Chrome yourself.
Command-line options
| Option | Effect |
|---|---|
--port N | Serve on a different port. Default is 8477. |
--no-browser | Start the server without opening a tab. |
--version | Print the version and exit. |
There is no --host. Azimut binds to 127.0.0.1 and refuses to listen anywhere else, by design rather than by omission.
Your workspace folder
On first launch Azimut creates ~/Azimut:
- Cases sit directly under it. Open the folder in your file manager and you see your investigations, not the app’s machinery.
- The machinery lives in the hidden
~/Azimut/.azimut/directory: scratch sessions, exported bundles, app settings, runtime tools and tile caches.
Inside a case, Azimut owns only the azimut/ subdirectory, where the manifest, notes, media, proofs, exports and the case database live. A README.txt states that boundary. Anything else you put at the case root is yours, is left untouched, and travels with the case when you export a bundle.
The path to your workspace is remembered in a one-line pointer file, kept in the platform’s own configuration location so a read-only install directory is never a problem:
| OS | Pointer file |
|---|---|
| Windows | %APPDATA%\Azimut\location |
| macOS | ~/Library/Application Support/Azimut/location |
| Linux | $XDG_CONFIG_HOME/azimut/location, or ~/.config/azimut/location |
Losing that file costs an address, never data: Azimut falls back to ~/Azimut, and pointing it back at your real workspace takes one field in Settings.
One-shot or in a case
Every tool works two ways. Open one with no case and you get a scratch session, useful in about thirty seconds and stored under .azimut/, promotable to a real case later. Open a case first and the same tool files its output as evidence in that investigation. Nothing forces you to create a case just to try something.
Worth setting up on day one
General: coordinate format and units.
Publishing: thread defaults and the attribution signature.
Templates: reusable composer templates and post targets.
Imagery: the basemap, with optional provider keys. A NASA FIRMS MAP_KEY also lives here: it is what turns on fire detections on the map and in the extension. Ask for one on the FIRMS page linked in Settings; it arrives by email.
Storage: where the workspace lives and where exports land.
About the update check
Azimut asks GitHub for the latest release when the page loads and links the download when a newer one exists. This is the single exception to “nothing reaches the network unless your action needs it”, and it exists so people running a downloaded binary hear about fixes. It is read-only, it fails silently offline, and System turns it off. Check for updates on the same tab runs it on demand.
Optional: the capture extension (recommended)
A browser extension files map captures straight into a case from sites Azimut does not host: Google Maps and Earth, Bing, Yandex, OSM, Apple Maps, Zoom Earth, Copernicus Browser and Satellites.pro. One screenshot per click, with the coordinates parsed from the URL and the site’s attribution kept.
Since 0.3.0 it also draws Azimut’s own tools over a 2D map on those sites: measure, the case’s saved points, sun and moon, a search grid that opens in the app afterwards, reference windows holding the case’s own images and videos, and NASA FIRMS fire detections. The scale is measured off the map rather than assumed, so a tool switches itself off, and says why, on a view it cannot compute on.
The two browser families install it differently, because they disagree about what a permanent extension is.
1. Chrome, Edge, Brave
In Azimut, open Settings → Capture extension and press Install. The app writes the extension into a folder it owns and shows you the path — copy it.
Open chrome://extensions, turn on Developer mode (top right), click Load unpacked, and paste the path into the picker (Ctrl+L on Linux, Cmd+Shift+G on macOS, the filename box on Windows). Leave the folder where it is: the browser loads it from there on every start.
Then paste the pairing token from Settings into the extension’s options, and capture something to check the round trip.
Because the app owns that folder, later updates are one button: Settings → Capture extension → Update rewrites the files and the extension restarts itself. Your pairing survives. Settings still offers a plain .zip if you would rather place the files yourself, it works the same, minus the update button.
2. Firefox
Firefox refuses an unsigned extension and drops an unpacked one when it closes, so about:debugging is a dead end for daily use. It gets a signed package instead.
Download the .xpi linked from Settings → Capture extension — the app links the exact file, which rides on the release that last changed the extension rather than on the newest one. Then open about:addons, use the gear menu → Install Add-on From File, and pick it. Paste the pairing token as above.
It survives restarts and it updates itself: a signed package is sealed, so the Update button does not apply and Firefox reads Azimut’s own update manifest about once a day. You can force it from about:addons → Check for Updates.
The file is signed by Mozilla but listed nowhere, signing and distribution are separate, so the add-on is validated and installable without being published on addons.mozilla.org.
Staying up to date
Binary. Download the new asset and replace the old file. ~/Azimut is untouched, so every case reopens as it was. You clear the OS warning once more for the new file.
pipx / pip. pipx upgrade azimut, or pip install --upgrade azimut.
Source. git pull, reinstall dependencies if pyproject.toml changed, then rebuild the frontend with npm run build. The relaunch helper does the build and restart in one step.
Scrapers, independently of the app. Settings → System → Downloaders updates yt-dlp and gallery-dl. If a download suddenly fails on a site that used to work, try this before anything else.
A note on schema: a case folder records the schema it was written with, and a case from a newer Azimut asks you to update rather than opening half-read. Older cases migrate forward automatically on open, with a backup retained.
Moving the workspace
Two mechanisms, for two different situations.
From the app, when you are relocating your data for good: Settings → Storage, described above. Use it for a move to an external drive or a bigger disk, and let Azimut verify the copy file by file.
With an environment variable, when you want a portable or temporary workspace:
AZIMUT_HOME=/media/usb/azimut-work azimut
AZIMUT_HOME wins over everything, on every launch, and creates the folder if it is missing. Because you give it fresh each time, it is the right tool for a workspace on removable media, and Settings hides the folder picker while it is set: the variable decides, not the UI.
One deliberate asymmetry: a workspace configured through the pointer and then missing stops startup with a full-screen panel instead of quietly creating an empty one. An unplugged drive must not look like a first run.
Troubleshooting
The tab never opened. The server is probably fine. Read the terminal for the URL and open it by hand. --no-browser suppresses the tab on purpose, so check it isn’t left over in a script.
Something else is on port 8477. Start elsewhere: azimut --port 8600. The port is only how your browser reaches the local server, so any free high port works.
“Held by another Azimut.” One Azimut per workspace, enforced by a lock the kernel releases on exit, with a heartbeat so a folder shared between machines can tell a live holder from a crashed one. The panel names the machine and port holding it and offers Reload; switch to that tab instead of starting over. Take it anyway exists for a lock that outlived its process, and warns you once before you use it.
“The workspace is gone.” The folder the pointer names isn’t there: renamed, deleted, or on a drive that isn’t plugged in. Nothing has been deleted or recreated. Plug the drive back in and reload, or point Azimut at the real folder from the panel’s own picker.
No video thumbnails, no frame scan, no video enhancement. ffmpeg is missing. This only happens on a pip or pipx install: install ffmpeg, restart Azimut. The downloadable binaries bundle it.
A download asks me to log in. Public media is fetched without cookies. A login-walled post prompts once for a browser session or an exported cookies.txt. That file is a live credential, which is why it is deliberately excluded from the settings backup.
A download that used to work now fails. Update the scrapers: Settings → System → Downloaders.
A case looks broken. Run the Case Doctor. It checks that the case’s database and media records still match its files without writing anything, then offers each repair explicitly, and states up front what a database rebuild cannot recover. It also handles files you dropped into media/ by hand.
I made a folder in the workspace from my file manager. One click adopts it as a case, where it is, without reading or moving what it holds. A folder whose case manifest was lost is recovered instead, then handed to the Doctor.
I deleted something I needed. Deleted artifacts wait in the case’s Trash until you restore them or delete them permanently.
macOS still refuses the binary after right-click → Open. Clear the quarantine attribute: xattr -d com.apple.quarantine ./azimut-macos-arm64.
Linux says “permission denied”. chmod +x azimut-linux-x86_64.
Uninstalling
The program:
- Binary: delete the file.
- pipx:
pipx uninstall azimut. - pip:
pip uninstall azimut. - Source: delete the clone.
Your data: ~/Azimut survives all of the above by design. Delete it by hand if you want the cases gone too. Beyond that there is only the small pointer file listed earlier.
What you can count on
The guarantees are short enough to state in full, and they hold in every version:
- Local-first. No account, telemetry or upload. Network access follows an action that needs the network, with the opt-out startup release check as the single exception.
- Portable cases. Files hold media, notes and proofs; a per-case SQLite database holds the graph. A closed case folder is complete and can be copied as-is, and a bundle export carries the analyst’s half of the folder along with Azimut’s, under a SHA-256 manifest, optionally password-protected.
- Focused tools. One tab does one task, and works in a scratch case you can promote.
- Orchestration. Specialized services stay external; selected results enter the case with provenance.
- Analyst control. Tools may suggest entities or links; only your action confirms them.
- Auditable output. Artifacts record how they were produced and label what is only a hint.
- Free core. Local computation and keyless services cover the core workflows. Your own keys add optional providers.
- Localhost only, single user. The server binds to
127.0.0.1behind a Host and Origin guard, secrets are written with restrictive permissions, and imports validate what they extract.
Source, releases, roadmap and issue tracker: github.com/OsintMeThat/azimut. The full product spec lives in docs/SPEC.md, and it is the authority on what is shipped and what is next.






Leave a Reply