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:

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:

PathBest forNeeds
Ready-to-run binaryMost people. Nothing to set up, ffmpeg included.Nothing
pipx install azimutYou already use Python, or want pipx upgrade.Python 3.11+
From sourceContributing, or running unreleased code.Python 3.11+, Node.js 20+

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.

OSAsset
Windowsazimut-windows-x86_64.exe
macOS (Apple Silicon)azimut-macos-arm64
macOS (Intel)No standalone binary. Use pipx or pip instead.
Linuxazimut-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 install
azimut # 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 release
pipx uninstall azimut # remove the app; your ~/Azimut data stays

One extra step: ffmpeg

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.

# macOS
brew install ffmpeg
# Debian / Ubuntu
sudo apt install ffmpeg
# Fedora
sudo dnf install ffmpeg
# Windows
winget 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 azimut
python3 -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/azimut
Set-Location azimut
py -3 -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"
Set-Location frontend
npm ci
npm run build
Set-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 / Linux
py 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 :8477
cd 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 # lint
uv run mypy # type-check the backend
cd 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

OptionEffect
--port NServe on a different port. Default is 8477.
--no-browserStart the server without opening a tab.
--versionPrint 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:

OSPointer 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…, pick manifest.json inside 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 with xpinstall.signatures.required set to false in about: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 activeTabscriptingstoragenotifications 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:

  1. 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.
  2. 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.
  3. Focused tools. One tab does one task, and works in a scratch case you can promote.
  4. Orchestration. Specialized services stay external; selected results enter the case with provenance.
  5. Analyst control. Tools may suggest entities or links; only your action confirms them.
  6. Auditable output. Artifacts record how they were produced and label what is only a hint.
  7. Free core. Local computation and keyless services cover the core workflows. Your own keys add optional providers.
  8. Localhost only, single user. The server binds to 127.0.0.1 behind 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

Why this platform ?

In a world of fragmented information and digital noise, clarity is the ultimate tool. I created OsintMeThat to bridge the gap between raw data and actionable understanding. Driven by a passion for geography and mapping, I use open-source intelligence to verify facts, track events, and provide an unbiased view of global conflicts. This platform is more than just a blog—it is a commitment to evidence, transparency, and the belief that the truth is always out there, waiting to be mapped.

Discover more from OSINT Me That

Subscribe now to keep reading and get access to the full archive.

Continue reading