# LogonTracer: the example config ships neo4j/password, and every import puts the database password in argv

> LogonTracer imports Windows event logs into Neo4j, scores hosts and accounts with PageRank, a hidden Markov model and ChangeFinder, and adds an LLM agent in version 2. Its documented commands pass the Neo4j password as a flag, its example config ships a default password for both the web login and the database, and its four compose variants are documented nowhere.

**JPCERTCC/LogonTracer** — Investigate malicious Windows logon by visualizing and analyzing Windows event log

- Repository: https://github.com/JPCERTCC/LogonTracer
- Stars: 3,284 · Forks: 489
- Language: Python
- License: NOASSERTION
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/jpcertcc-logontracer

## The example config gives the web login the database credentials

The configuration step shows this:

```yaml
settings:
  logontracer:
    WEB_PORT: "8080"
    default_user: "neo4j"       # Neo4j username for the default LogonTracer account
    default_password: "password" # Change this before first run

  neo4j:
    NEO4J_USER: "neo4j"
    NEO4J_PASSWORD: "password"   # Your Neo4j password
    NEO4J_SERVER: "localhost"
    WS_PORT: "7687"
```

Two things are worth pausing on. The value `password` appears twice, once as the web application's default login and once as the Neo4j password, and the comment on `default_user` says it is the Neo4j username for the default LogonTracer account, so the two pairs are not independent. And only one of the two carries a change-it instruction. The app then serves plain HTTP on 8080 and the README tells you to open `http://localhost:8080`, so the credential you just set travels in the clear on a default install.

## Every documented import passes the password as a flag

All four import invocations take the database credential on the command line, and the concrete example fills it in:

```shell
python3 logontracer.py -e <path/to/Security.evtx> -z 9 -s localhost -u neo4j -p password --sigma
```

The EVTX form, the XML form and the Elasticsearch form all end in `-s <Neo4j server> -u <user> -p <password>`. A command-line password lands in your shell history and is visible in the process table to anything else running on the machine for as long as the import takes, and an import of a large Security.evtx is not quick. Nothing in the README mentions an environment variable, a prompt, or a config-file-only path for the import step, even though the web application itself stores the same settings in `config/config.yml`. The web upload path exists and does not have this problem, since it runs inside the application that already holds the credentials.

## An import replaces the graph unless you ask it not to

The usage section documents four import routes, and the fourth exists because the first three destroy what was there. The base invocations import a log and clear the existing data, while the one titled Add additional logs runs with `--add` and does not delete existing data. The same choice is exposed in the web interface as the Add additional files checkbox, described as appending data without clearing the database, and as Run scan using Sigma rules to run detection automatically after import. So the safe mode is the one you have to notice: re-running an import to fix a timezone or add a second host's log will empty the graph unless you remember a flag whose name is simply add. For a tool whose output is a picture of an intrusion, that is the difference between two rounds of analysis and one.

## Four compose variants ship, and the README explains none of them

The tree holds `docker-compose/`, `docker-compose-localllm/`, `docker-compose-with-elasticstack/` and `docker-compose-with-nginx/`, beside a `docker/` directory, and the README's badge row links a Docker Hub image. The Installation section then documents only the manual path: clone, `pip3 install -r requirements.txt`, start Neo4j yourself, edit the config, run `python3 logontracer.py --run`. Four deployment shapes ship and not one is described. Two of them tell you something about the intended deployment anyway. The nginx variant implies TLS termination in front of the app, which the manual path does not have, and the local-LLM variant exists because the AI features default to OpenAI, since the AI setup steps say to enable analysis and enter your OpenAI API key and pick a GPT model, with no mention of pointing it somewhere else.

## The v2 agent writes Cypher against your investigation graph

Version 2.0 adds four things under the heading of AI-powered security analysis. Security pattern analysis interprets graph query results and generates risk assessments with MITRE ATT&CK tactic mapping. An autonomous LLM agent iteratively generates and executes Cypher queries against the Neo4j graph without manual intervention. Generated Sigma rules convert findings into deployable detection content. Responses can be produced in English, Japanese or French. The mechanics matter for an incident response tool: the model is not summarising a report, it is writing database queries against the store holding your investigation, and the key is entered in the browser under Settings, then stored by the application. The README describes none of the data that leaves the machine, no retention behaviour, and no way to see what a query did beyond the AI History panel. The local-model compose variant is the only hint that a non-OpenAI path is possible.

## Fourteen event IDs and three scoring methods

The graph is built from a fixed table of event IDs: 4624 and 4625 for successful logon and failure, 4662 for an operation on an object, 4672 for assigning special privileges, 4719 for a system audit policy change, 4720 and 4726 for account creation and deletion, the paired 4728, 4732 and 4756 for additions to security-enabled groups with 4729, 4733 and 4757 for removals, 4768 and 4769 for Kerberos ticket requests, 4776 for NTLM authentication, and 5137 and 5141 for directory service object creation and deletion. Hosts or IP addresses and account names found in those events become the nodes, which is how the tool answers which account tried to log on and from where. Scoring is separate: PageRank, a hidden Markov model and ChangeFinder are named as the methods for detecting malicious hosts and accounts, and event logs can also be shown in chronological order.

## Elasticsearch import drops the timezone flag the others require

The EVTX and XML forms both require `-z <UTC offset>`, and the Sigma example uses `-z 9`. The Elasticsearch form has no such flag: it takes `--es` plus `-s`, `-u`, `-p` and `--es-server <ES host:port>`. So a log pulled from an Elasticsearch index is ingested without the timezone adjustment the file-based routes insist on, which is the kind of difference that shifts every timestamp in the resulting timeline. The Elasticsearch client library is also the one dependency with an upper bound, `elasticsearch-dsl>=7.0.0,<8.0.0`, while everything else in `requirements.txt` is open-ended above a floor. The tree holds an `es-index/` directory for the index side, and the requirements include `elasticsearch-dsl`, so the feature is wired rather than aspirational.

## A two and a half year gap, and a sample graph in the repository

The release history has a hole in it: v1.6.0 on 2022-12-21, v1.6.1 on 2023-11-15, then v2.0.0 on 2026-04-22, with the last commit on master dated 2026-08-02. So the version described throughout the README as v2 has been out for about half a year, with commits landing since the tag, and the step before it is two and a half years old. Requirements say Python 3.9 or later with 3.12 recommended, and Neo4j 5.x in either Community or Enterprise, while multiple independent investigation cases, each in its own Neo4j database, are stated as an Enterprise Edition feature. The `sample/` directory ships a `Security.evtx`, a `data.tar.gz` and a `graph.db.tar.gz`, so you can look at a prepared graph before importing anything of your own.

## Conclusion

LogonTracer fits an incident responder who already has a Neo4j instance and a Security.evtx export, and who wants logon activity as a graph instead of a list of rows. Before the first run, change both passwords in `config/config.yml`, not just the one the comment marks, because the same value appears twice with two meanings. Avoid passing the database password on the command line where the process list can see it, and remember that an import replaces the existing graph unless you pass `--add`. Think hard about the AI features before enabling them: an agent writes and executes Cypher against your investigation database, and the README says nothing about what leaves the machine, though a local-model compose variant exists in the tree. Multiple investigation cases need Neo4j Enterprise. And if you only want the graph and the scoring, leave the OpenAI key alone; it is optional and only the v2.0 analysis needs it.

## FAQ

### What does LogonTracer do with a Security.evtx file?

It imports the log into Neo4j, turning the host names, IP addresses and account names found in fourteen logon-related event IDs into a graph you can browse. Hosts and accounts are then scored with PageRank, a hidden Markov model and ChangeFinder, and the same log can be viewed in chronological order.

### Can I run LogonTracer without an OpenAI API key?

Yes. The requirements call the key optional and required only for the AI analysis features, so the graph, the Sigma scanning, the PageRank, Markov model and ChangeFinder analysis and the web interface all run without one. The v2.0 agent, the risk assessments and the Sigma rule generation are the parts that need it.

### Does LogonTracer need Neo4j Enterprise?

Not for a single investigation. The requirements ask for Neo4j 5.x in Community or Enterprise, and the Enterprise Edition is named as what supports multiple independent cases, each stored in a separate Neo4j database.

### Why did my LogonTracer import clear the previous graph?

Because clearing is the default. The base import commands replace the existing data, and the one that preserves it runs with `--add`, described as adding additional logs without deleting existing data. The web upload has the same choice as the Add additional files checkbox.

### Where does LogonTracer keep its web interface password?

In `config/config.yml`, as `default_user` and `default_password` under the logontracer settings, and the shipped example sets them to `neo4j` and `password`. The comment says the user is the Neo4j username for the default LogonTracer account, and the same password appears again under the neo4j section, so change both.

## Sources

- [Issues](https://github.com/JPCERTCC/LogonTracer/issues)
- [JPCERTCC/LogonTracer on GitHub](https://github.com/JPCERTCC/LogonTracer)
- [README](https://github.com/JPCERTCC/LogonTracer/blob/master/README.md)
- [Releases](https://github.com/JPCERTCC/LogonTracer/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jpcertcc-logontracer
