The OSINT investigator's workbench — local-first media, geolocation proofs and case management.
Project description
Azimut
The OSINT investigator's workbench. One case, one folder, every tool. Local-first: your media and your investigations never leave your machine.
Built for the open-source-investigation community — GeoConfirmed contributors, journalists, researchers.
Close Azimut. Reopen the case six months later. Everything is there: the downloaded media, the annotated proofs, the entities and their links, the notes, the exports — in one plain folder you can zip, git, or share.
The name is the French word azimut — the compass bearing you sight along to fix a point on the map (English azimuth). A fitting namesake for a geolocation workbench: fix a direction, fix a location.
v0.1.1 — Proof Studio
| Tool | What it does |
|---|---|
| Media Library | Import local files or download by URL (X, Telegram, TikTok, YouTube, Instagram… via yt-dlp, with a gallery-dl fallback for image-only posts) → clean local file + metadata + SHA-256. Multi-photo posts open a picker. |
| Inspect | Scratch workspace over any photo/video: frame adjustments, editable crop, sharpest-frame capture, hand-made collage with per-piece warp/scale/rotate — nothing enters the case until you save. |
| Satellite | Coordinates or place name → imagery crop, with select-area capture, map rotation, measurement tools, and reference-image overlays. Esri/OSM by default; add your own Mapbox/Google key for more basemaps (stored locally, never shared). |
| Proof Composer | Compose panels in a grid or free layout, annotate with colored shapes and text (same color = same feature), reorderable legend → export proof.png + a re-editable spec. |
| Post Composer | Turn a proof into a publishable thread: coordinates in all formats, plus code, attribution, character count, RTL-safe text. Copy-paste ready — Azimut never posts for you. |
Every tool works one-shot (no setup, scratch session) or inside a case — a plain directory holding the whole investigation.
New in v0.1.1 — a polish pass over the v1 tools:
- Satellite — OSM labels overlay, true browser fullscreen, Esri overzoom (upscales past World Imagery's last level instead of a "not available" tile), and imagery acquisition dates surfaced on the map and in captures.
- Keyed providers — a Settings tab for Mapbox/Google keys with per-provider toggles, monthly usage counters, a soft block at 90% of the free tier, an eco mode that falls back to free imagery when zoomed out, and a disk tile cache. Free by default: keys stay optional and local.
- Proof Composer — free layout mode (drag panels anywhere, overlap with z-order), corner-drag panel resize, and satellite panels that auto-caption with provider · coordinates · imagery date.
- Inspect — shift-click a block of collage pieces to move, scale and rotate them as one.
Install & run
pip install azimut
azimut # starts on http://127.0.0.1:8477 and opens your browser
From source:
git clone https://github.com/OsintMeThat/azimut && cd azimut
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
cd frontend && npm install && npm run build && cd ..
.venv/bin/azimut
Frontend development (hot reload, proxied API):
.venv/bin/azimut --no-browser & # backend on :8477
cd frontend && npm run dev # UI on :5173
Building & releasing
The Svelte frontend builds into src/azimut/static/ (git-ignored) and is
bundled into the Python wheel via hatchling artifacts. So npm run build
must run before building the package, or the shipped UI is stale/missing.
cd frontend && npm run build && cd .. # refresh the bundled UI
python -m build # wheel + sdist (UI included)
pyinstaller packaging/azimut.spec # optional: standalone binary
Releases are automated: push a semver tag and GitHub Actions
(.github/workflows/release.yml) builds the
wheel + Windows/Linux/macOS binaries, attaches them to a GitHub release, and
publishes to PyPI. Don't publish by hand.
git tag v0.1.0 && git push origin v0.1.0
One-time setup: register the repo as a
PyPI Trusted Publisher for the
azimut project (no API token to store).
Principles
- Local-first, privacy-first — no account, no telemetry, no upload; the
server binds to
127.0.0.1only. - The case is the product — plain JSON + media files, versionable, portable.
- One tab = one tool, useful in 30 seconds.
- Orchestrator, not replacer — integrate specialized services, don't clone them.
- Tools emit facts, the analyst decides — no automated "magic button".
- Honest output — every artifact records how it was produced.
- Free and open source — no paid keys required, ever. Optional bring-your-own-key providers.
Full spec: docs/SPEC.md.
License
AGPL-3.0-only — free and open source; hosted or modified versions must share their source.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file azimut-0.1.1.tar.gz.
File metadata
- Download URL: azimut-0.1.1.tar.gz
- Upload date:
- Size: 605.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
503cf9033be4437a1e973e69ebc919143d9a79ce4a1e5c56dc1c05c0042a2939
|
|
| MD5 |
67d224caa71515af181d69569110e978
|
|
| BLAKE2b-256 |
61f1d1bd49de7ec299f9e4170c34d98fc94d802740c184963fdecc2e1b36119d
|
Provenance
The following attestation bundles were made for azimut-0.1.1.tar.gz:
Publisher:
release.yml on OsintMeThat/azimut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
azimut-0.1.1.tar.gz -
Subject digest:
503cf9033be4437a1e973e69ebc919143d9a79ce4a1e5c56dc1c05c0042a2939 - Sigstore transparency entry: 2172967416
- Sigstore integration time:
-
Permalink:
OsintMeThat/azimut@79f4336067b5409da5d8a70dd7642467534bb551 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/OsintMeThat
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@79f4336067b5409da5d8a70dd7642467534bb551 -
Trigger Event:
push
-
Statement type:
File details
Details for the file azimut-0.1.1-py3-none-any.whl.
File metadata
- Download URL: azimut-0.1.1-py3-none-any.whl
- Upload date:
- Size: 396.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d46230a1288e5ec5452462eeed8e1e00061a1a919a24dab615c98b4467a92b64
|
|
| MD5 |
acf1457d6c086a1d77146cacf1883233
|
|
| BLAKE2b-256 |
dee81338687e78edb6a8e6e06bc64932784f7e1826a9408062e7d35669ea90a0
|
Provenance
The following attestation bundles were made for azimut-0.1.1-py3-none-any.whl:
Publisher:
release.yml on OsintMeThat/azimut
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
azimut-0.1.1-py3-none-any.whl -
Subject digest:
d46230a1288e5ec5452462eeed8e1e00061a1a919a24dab615c98b4467a92b64 - Sigstore transparency entry: 2172967429
- Sigstore integration time:
-
Permalink:
OsintMeThat/azimut@79f4336067b5409da5d8a70dd7642467534bb551 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/OsintMeThat
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@79f4336067b5409da5d8a70dd7642467534bb551 -
Trigger Event:
push
-
Statement type: