Self-hosted service
Exodus-Privacy/exodus avatar
Exodus-Privacy/exodus

exodus: auditing the privacy behaviour inside Android applications

Platform to audit trackers used by Android application

810 stars74 forksPythonAGPL-3.0

At a glance

What is it?
Exodus is a privacy auditing platform for Android applications that reports behaviours dangerous for user privacy, such as ads, tracking and analytics, and it is backed by a community-maintained tracker database. There is a public instance, an API, a self-hosted Docker setup and a separate tool for CI pipelines.
Who is it for?
Adopt exodus if you need an auditable, citable account of what an Android application does with personal data, whether for an app store submission, a corporate review or a research project. Do not adopt it as a runtime privacy control, since it is an auditing platform and not a blocker on the device, and do not plan a self-hosted instance without accounting for Postgres, RabbitMQ, MinIO and the two application services.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 40 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the platform reports

Exodus is a privacy auditing platform for Android applications. Its stated purpose is to detect behaviors which can be dangerous for user privacy, and the README names the categories as ads, tracking and analytics among others.

That framing is the difference between this and an antivirus. The question being answered is not whether the application is malicious but what it collects and what it sends, which is the question a reviewer, a journalist or a user with a personal data policy actually has to answer. The output is therefore a report rather than a verdict, and the vocabulary of the reports is the vocabulary of data flows rather than of malware families.

There is an official instance of the platform, published at reports.exodus-privacy.eu.org, and it is the instance most people meet first. The repository also documents an API, with its documentation in the doc/api.md file, which means the findings can be pulled programmatically rather than read by hand, and that matters for anything that wants to compare applications over time or across a catalogue of apps.

The project is written in Python, licensed under the GNU AGPL v3, and its default branch is v1. The most recent release is v1.33.0 from 2026-09-13, following v1.32.4 in April 2026 and v1.32.3 in February 2026.

The tracker database lives on ETIP

The knowledge behind the reports is separated from the platform that serves them, and that separation is the most important architectural fact in the project.

All data about trackers is stored on ETIP, the tracker investigation platform, at etip.exodus-privacy.eu.org. The README asks people who want to help identify new trackers to request an ETIP account by sending a username and an email address to the address given there. That is an invitation to a working group rather than an open pull request path, and it reflects how the data is produced: someone examines an application's behaviour, recognises a network endpoint or a library as belonging to a known tracker, and records it.

The split has two consequences. The platform is only as good as the tracker database behind it, so coverage depends on how many people are working on ETIP and which applications they have looked at. And a report is only reproducible if the data version is fixed, which is why the separate licensing of the database and the API results, discussed later, matters to anyone citing a finding.

The project is explicit that translation is also a contribution, and it is translated into 21 languages with more than 40 available in Crowdin, which is an unusual thing for a technical auditing tool to have done.

The services behind a self-hosted instance

The docker-compose.yml in the repository shows the whole topology, and it is a conventional Python web stack with a few pieces worth naming.

PostgreSQL holds the data. The service uses the postgres:15 image with an exodus user, password and database, and a PGDATA path inside the volume:

yaml
  db:
    environment:
      POSTGRES_USER: exodus
      POSTGRES_PASSWORD: exodus
      POSTGRES_DB: exodus
      PGDATA: /var/lib/postgresql/data/pgdata
    image: postgres:15

RabbitMQ carries the work queue, and the application image names it amqp:

yaml
  amqp:
    image: rabbitmq:3.10.8-alpine
    networks:
      backend:
        aliases:
            - amqp
    ports:
      - "5672:5672"

MinIO provides the object storage, which is where the application binaries being analysed are kept, and it is the one dependency whose image is not pinned to a fixed version:

yaml
  minio:
    command: ["minio", "server", "/data", "--console-address", ":9001"]
    environment:
      MINIO_ROOT_USER: exodusexodus
      MINIO_ROOT_PASSWORD: exodusexodus
    image: elestio/minio:latest

On top of those sit the two application services. The front service serves the web interface and the API, published on port 80 of the host and mapped to port 8000 in the container, and the worker service runs the same image with a start-worker command. Both mount the exodus source directory so a developer can edit code and see it take effect, and both take their configuration from an .env file.

Running an instance and using it from a pipeline

The README does not spell out the commands, and it points at a document instead. Installing a local instance has different routes, via Docker or manually, and everything is explained in doc/install.md in the repository.

The compose file is the Docker route, and it is meant to be used rather than read: the services are wired to a shared backend network with aliases, so exodus-front, exodus-worker, db, amqp and minio resolve each other by name, and the volumes keep the database and the object storage across restarts.

For continuous integration, the project points at a separate repository, exodus-standalone. The distinction matters if you are automating an audit: the full platform is a web application with a database, a queue, object storage and a user-facing interface, which is the right shape for a service that many people query. A pipeline needs something that runs, produces a report about one application and exits. That is what exodus-standalone is for, and the README recommends it explicitly to anyone adding the platform to a CI pipeline.

So there are three ways to use the project, with different costs. The public instance is free of operational effort. A self-hosted instance gives you the platform and the API under your control, at the price of running five services. And exodus-standalone gives you the audit in a pipeline without the platform around it.

The licence split between code and data

There are three licences in play, and the project is unusually precise about which applies to what.

The code is under the GNU AGPL v3, with the LICENSE file in the repository holding the terms. AGPL is the copyleft licence that extends the source-offer obligation to network use, which is why it was chosen for a service whose users interact with it over a network rather than only receiving a binary. If you run a modified copy and serve it, that is the part of the licence that matters, and it is a question for your own review rather than for this article.

The data is separate. The Exodus database and the API results are made available under the Open Database License, and any rights in the individual contents of the database are licensed under the Database Contents License, both published by Open Data Commons. In practice that is a share-alike arrangement for the database as a whole, with a separate rights layer for the individual facts inside it.

The separation is the point. The code is copyleft because the project wants modifications shared; the data is openly licensed because the project wants the findings to travel, and the individual-contents licence exists so that a fact recorded about one tracker does not make the whole dataset the property of whoever recorded it.

None of this is legal advice, and an organisation redistributing reports or hosting a modified instance should read the three documents rather than a summary of them.

Where exodus is the wrong tool

The first limitation is the obvious one: this is an auditing platform, not a privacy control on a device. Nothing in the README describes anything that runs on an Android phone, blocks a request or changes an application's behaviour. If the requirement is to stop an application from collecting data, that is a different category of product and no amount of Exodus reports will satisfy it.

The second limitation is coverage, and it is structural rather than fixable. Findings depend on the tracker database maintained on ETIP, which depends on people examining applications. An application that nobody has looked at, or a tracker that nobody has recognised, produces an unremarkable report. A clean report is therefore evidence that nothing was detected, not evidence that nothing is collected.

The third is the operational cost of self-hosting. A self-hosted instance needs Postgres, RabbitMQ, MinIO and the application services, with the object storage image pinned to latest rather than to a fixed version, which means a rebuild can pick up a different storage backend than the one your instance was tested against. The compose file also carries development conveniences such as the source directory mounted read-write into both application services and a user taken from the environment, which is right for a development machine and worth reviewing before it faces anything else.

The fourth is the scope of the data itself. The platform reports on applications it has been given, and the README says nothing about whether a report reflects the behaviour of a specific build, a specific version or the application as distributed. For an audit you intend to publish, that granularity is the difference between a finding and an anecdote.

Project structure, contributions and maintenance

The repository holds the exodus package itself, a docker directory with the images, a contrib directory, a doc directory with the installation, API and FAQ documents, and a Pipfile with its lock file, which points at pipenv for the Python environment. A .python-version file pins the interpreter, .flake8 configures the linter, and uwsgi_params suggests the web layer is served through uWSGI in production.

Contributions come in several forms and the README lists them: translating the platform through Crowdin, reporting bugs and proposing features through issues, joining the IRC channel on Libera.chat, improving the code following the documentation in CONTRIBUTING.md, and helping with the identification of trackers through ETIP.

The project has published a code of conduct and asks contributors to follow it. The tracker identification route deliberately goes through a private account request rather than the issue tracker, which is a reasonable way to keep the database curated, and it also means that improving coverage depends on people with time rather than on code contributions.

On maintenance, the release history shows steady work through 2026, with v1.33.0 published on 2026-09-13 and the last push on the same day. The repository is not archived, and the version numbering on the v1 branch suggests the platform is still evolving within a single major line rather than preparing a rewrite.

Editorial conclusion

Adopt exodus if you need an auditable, citable account of what an Android application does with personal data, whether for an app store submission, a corporate review or a research project. Do not adopt it as a runtime privacy control, since it is an auditing platform and not a blocker on the device, and do not plan a self-hosted instance without accounting for Postgres, RabbitMQ, MinIO and the two application services. Verify first that the trackers you care about are covered by the database, that the report you cite comes from an instance whose data version you can name, and that the licence split between the AGPL code and the Open Database licensed results fits the way you intend to redistribute your findings.

Frequently asked questions

What does the exodus platform detect in Android applications?

Behaviors which can be dangerous for user privacy, such as ads, tracking and analytics. The platform produces a report on an application rather than a verdict, and the official instance is published at reports.exodus-privacy.eu.org.

How do I run a local instance of exodus?

Through Docker or manually, with the instructions in doc/install.md. The docker-compose.yml brings up PostgreSQL, RabbitMQ, MinIO, the front service and the worker service on a shared backend network, and the front service is published on port 80 of the host.

Where is the tracker data for exodus maintained?

On ETIP, the tracker investigation platform, at etip.exodus-privacy.eu.org. To help identify new trackers you request an account by sending a username and an email address to the address listed in the README.

Can exodus be used in a CI pipeline?

Yes. The README directs anyone adding the platform to a CI pipeline to the separate exodus-standalone project, which runs the audit without the full platform around it.

Which licences apply to exodus and to its data?

The code is under the GNU AGPL v3. The database and the API results are made available under the Open Database License, and rights in the individual contents of the database under the Database Contents License.

Official sources

  1. Exodus-Privacy/exodus on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/exodus-privacy-exodus.svg)](https://hysenlabs.com/projects/exodus-privacy-exodus)

Was this useful?