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) | No standalone binary. Use pipx or pip instead. |
| Linux | azimut-linux-x86_64 |
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
Settings sits behind the gear in the topbar, grouped into tabs. Most can wait; four are worth a look right away.
General. Your coordinate format (decimal, DMS or MGRS) and units (metric or imperial), plus the home view the map opens on. Set them once and every tool follows. These are display preferences only: artifacts are stored in decimal degrees and metres whatever you pick.
Publishing. Defaults for prepared threads, and your signature: the attribution that ends up on exported proofs. Fill it in before your first export rather than after.
Imagery. Esri, OSM, OpenTopoMap and Sentinel-2 work with no key at all, Sentinel-2 including a date calendar and a cloud-ceiling slider. Paste a Mapbox, Google or Sentinel Hub key for more basemaps if you have one; none is ever required. Eco mode on the same tab swaps billed basemaps for free imagery when you are zoomed out, which keeps a metered key from draining while you pan around. Unofficial keyless endpoints of keyed services are deliberately never shipped, and custom XYZ templates are supported.
Storage. Three things live here:
- The workspace folder. There is no native folder picker, so you type a path and press Check, which reads it and reports back before offering anything. Use this folder switches the pointer and moves nothing, telling you how many cases would stay behind. Move everything here copies the whole workspace, verifies every file by SHA-256 before the pointer switches, and keeps the old copy until you delete it yourself. An external drive is a valid destination.
- Export folders. One destination each for note PDFs, media copies and proof PNGs; the case’s own
exports/is the default. Files already outside a case are never overwritten, and concurrent exports reserve distinct numbered names. - Settings backup. This is what moves an installation to another machine. It carries portable settings, API keys, templates and your signature, and deliberately leaves behind absolute export paths, the workspace pointer and download sessions, since those belong to one machine. Keep the downloaded file private: it holds your keys.
System. The version, the update check, a pre-filled issue reporter, and the Downloaders panel that updates yt-dlp and gallery-dl in place. That last one matters more than it sounds: scrapers race sites that change without notice, and updating them from inside the app is what keeps a months-old binary working.
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 for Chrome, Edge, Brave and Firefox files map captures straight into a case from external sites: Google Maps and Earth, Bing, Yandex, OSM, Apple Maps, Zoom Earth, Copernicus Browser and Satellites.pro. One screenshot per click, with coordinates parsed from the URL, the source URL, a timestamp and visible attribution. It can also save a map point as a place, or any page as a bookmark without downloading it, and it powers the in-app Capture button on the Google (Maps JS) basemap.
1. Get the folder. Settings → Capture extension → download the zip, then unzip it somewhere permanent. Chrome reloads the extension from that folder on every start, so don’t unzip it into a temp directory.
2. Load it.
- Chrome / Edge / Brave: open
chrome://extensions, enable Developer mode (top right), click Load unpacked, pick the unzipped folder. - Firefox: open
about:debugging#/runtime/this-firefox, click Load Temporary Add-on…, pickmanifest.jsoninside the folder. Firefox drops temporary add-ons when it closes, so you reload it each session. For a permanent install, use Firefox Developer Edition or ESR withxpinstall.signatures.requiredset tofalseinabout:config.
3. Pair it. Copy the pairing token from Settings → Capture extension. In the extension’s options (right-click the toolbar icon → Options), paste the token and press Save & test. Rotating the token in Settings revokes existing pairings.
The extension requests activeTab, scripting, storage, notifications and access to 127.0.0.1/localhost. It does not ask for <all_urls>, browsing history, or any remote server. Note that a new tab may need one toolbar click before the browser allows a screenshot: that gesture is a browser requirement, not an Azimut one.
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