DEV Community

Sathish Kumar S
Sathish Kumar S

Posted on

I Built a Security Attack Analysis Engine Without Installing a Single Runtime Package

What happens when you build a security analysis tool in Python and deliberately remove every third-party runtime dependency?

Usually, I would reach for a few packages.

A parser here. A CLI framework there. A data-processing library. Maybe a logging package. Something for JSON. Something for configuration.

For the Zero Dependency 72-Hour Hackathon, I couldn't.

The rule was simple: standard library only.

So I built TraceLock — a lightweight security event correlation and attack analysis engine in Python, with zero third-party runtime dependencies.

The idea

TraceLock takes security event logs and tries to answer a question that raw logs often don't:

"What actually happened during this sequence of events?"

A single failed login isn't necessarily interesting.

A successful login isn't necessarily malicious.

A command being executed isn't necessarily suspicious.

But when the events occur in a sequence like:

Multiple authentication failures
        ↓
Successful authentication
        ↓
Command execution
        ↓
Privileged activity
Enter fullscreen mode Exit fullscreen mode

the story becomes much more interesting.

TraceLock correlates those events and reconstructs them into an attack chain.

For example, one of my synthetic attack scenarios produces:

Credential Attack
        →
Successful Access
        →
Command Execution
        →
Privileged Activity
Enter fullscreen mode Exit fullscreen mode

The resulting assessment is:

Risk: CRITICAL
Score: 100/100
Enter fullscreen mode Exit fullscreen mode

It also extracts evidence, produces behavioral analysis, identifies relevant MITRE ATT&CK-style behavioral mappings, generates recommendations, and can export the analysis as JSON.

Why build this with zero dependencies?

The Zero Dependency hackathon challenged participants to build useful software using only their language's standard library — no third-party runtime packages, frameworks, or external libraries.

For a security project, this constraint actually made sense.

Security tools are exactly the kind of software where the dependency chain deserves attention.

Every additional runtime package adds something that has to be trusted, maintained, updated, and potentially audited.

That doesn't mean third-party packages are bad.

It means that sometimes the right engineering question is:

"Do I actually need this dependency?"

TraceLock was my attempt to answer that question for a small security-analysis engine.

What TraceLock does

The project follows a pipeline:

Raw Security Logs
       ↓
Log Parser
       ↓
Event Correlation
       ↓
Attack Chain Reconstruction
       ↓
Evidence Extraction
       ↓
Behavior Analysis
       ↓
Anomaly Detection
       ↓
Risk Scoring
       ↓
MITRE Mapping
       ↓
Security Recommendations
       ↓
Terminal / JSON Report
Enter fullscreen mode Exit fullscreen mode

The important part is that each stage is implemented directly in Python.

No external runtime framework is sitting underneath it.

The first challenge: parsing logs without a package

Parsing logs sounds easy until you actually start defining what a parser should do.

TraceLock's parser needs to extract things like:

  • timestamps
  • source IP addresses
  • usernames
  • event types
  • commands
  • privilege-related activity

Python's standard library already gives enough building blocks for this.

I used:

  • re for pattern matching
  • datetime for timestamp parsing
  • dataclasses for structured event objects
  • typing for type annotations

The parser converts raw log lines into structured LogEvent objects.

Conceptually:

Raw line
   ↓
Pattern matching
   ↓
Extract fields
   ↓
Classify event
   ↓
Create LogEvent
Enter fullscreen mode Exit fullscreen mode

The interesting realization was that I didn't need a dedicated parsing framework.

The standard library already had the primitives.

The package I would normally reach for: a CLI framework

A command-line tool usually makes people reach for something like Click or Typer.

TraceLock doesn't use either.

Instead, the CLI is built with Python's built-in:

argparse
Enter fullscreen mode Exit fullscreen mode

That gives TraceLock commands such as:

python -m tracelock.cli examples\sample_attack.log
Enter fullscreen mode Exit fullscreen mode

and JSON output:

python -m tracelock.cli examples\sample_attack.log --json reports\sample_attack.json
Enter fullscreen mode Exit fullscreen mode

The CLI handles the input file and optional JSON output without requiring another dependency.

This was probably one of the easiest substitutions.

argparse is surprisingly capable once you stop assuming that every CLI needs a framework.

The harder part: correlation

Parsing individual events is one thing.

Understanding the relationship between events is another.

TraceLock uses a correlation window and groups related events based on context such as source IP and user.

The correlation engine looks for meaningful sequences rather than treating every event independently.

For example:

10.10.10.50
    ↓
5 authentication failures
    ↓
successful authentication
    ↓
command execution
    ↓
privileged activity
Enter fullscreen mode Exit fullscreen mode

The system reconstructs this as one attack chain instead of five unrelated observations.

This required thinking about:

  • time windows
  • event ordering
  • source identity
  • duplicate-chain prevention
  • scoring
  • explanations

This was one of the places where I felt the zero-dependency constraint most strongly.

There wasn't a library I could simply call to "understand this sequence."

I had to define the behavior myself.

Turning events into an attack story

A security analyst doesn't just want:

event_1
event_2
event_3
event_4
Enter fullscreen mode Exit fullscreen mode

They want a story.

So TraceLock has a story-building stage that converts correlated events into a chronological narrative.

For a full attack chain, the title becomes:

Credential Attack → Successful Access → Command Execution → Privileged Activity
Enter fullscreen mode Exit fullscreen mode

The report also contains a timeline, stages, evidence, and a conclusion.

This was an important design decision:

Detection is more useful when the result explains itself.

A score without context isn't very helpful.

Risk scoring without a machine-learning framework

Another thing I could have outsourced to a package is scoring.

I didn't.

TraceLock uses a custom risk-scoring system based on the observed event sequence and security factors.

For the full synthetic attack chain, the resulting score is:

100 / 100
CRITICAL
Enter fullscreen mode Exit fullscreen mode

The point isn't that 100 is some universal measurement of real-world risk.

It is a deterministic assessment produced from the evidence TraceLock observed.

That distinction matters.

A security tool should not pretend that a simple heuristic is magically equivalent to a complete security investigation.

MITRE ATT&CK mapping

TraceLock also maps observed behaviors to relevant MITRE ATT&CK techniques.

The current mappings include:

T1110  → Brute Force
T1078  → Valid Accounts
T1059  → Command and Scripting Interpreter
T1068  → Exploitation for Privilege Escalation
Enter fullscreen mode Exit fullscreen mode

These mappings are treated as behavioral mappings, not proof that a particular technique definitely occurred.

That distinction is important because log evidence alone often cannot establish an attacker's exact intent.

The goal is to provide useful security context rather than manufacture certainty.

Evidence extraction

One of the things I wanted TraceLock to do was show why it reached a conclusion.

For the sample attack, the report extracts evidence such as:

  • authentication failures
  • successful authentication
  • command execution
  • privileged activity
  • multi-stage correlation

The result is closer to:

Finding
+
Evidence
+
Timeline
+
Risk
+
Explanation
Enter fullscreen mode Exit fullscreen mode

instead of simply:

CRITICAL!!!
Enter fullscreen mode Exit fullscreen mode

That makes the output much more useful to someone actually investigating an event.

Behavior and anomaly analysis

TraceLock also creates a behavior profile from the observed chain.

For the full attack scenario, it identifies a behavioral progression such as:

Credential Compromise
        →
Privilege Escalation
Enter fullscreen mode Exit fullscreen mode

with a confidence value of:

95%
Enter fullscreen mode Exit fullscreen mode

The anomaly stage produces multiple findings from the same evidence and combines them into an overall anomaly assessment.

For the sample attack:

Anomaly Score: 100/100
Severity: CRITICAL
Enter fullscreen mode Exit fullscreen mode

Again, these values are part of TraceLock's deterministic analysis model, not claims that the tool can replace a production SOC or SIEM.

Recommendations

Detection without action is only half the job.

TraceLock therefore generates security recommendations based on the detected behavior.

For the full attack chain, the report produces five recommendations.

The goal is to move from:

"This looks suspicious."
Enter fullscreen mode Exit fullscreen mode

to:

"Here are the next security actions you should consider."
Enter fullscreen mode Exit fullscreen mode

The standard-library replacements

This was the heart of the Zero Dependency challenge.

Instead of importing packages, I built the required functionality from Python's standard library.

My STDLIB.md documents the approach.

Some of the important substitutions were:

Normally reached for TraceLock approach
Pydantic dataclasses
Click argparse
python-dateutil datetime
orjson / ujson json
Rich standard print() and formatting
pandas lists and dictionaries
NumPy built-in arithmetic and collections
scikit-learn custom scoring logic
Loguru standard output/file I/O
PyYAML text parsing and standard data structures
requests urllib where needed

Not every project needs all of these packages.

The point of the table is to document the kinds of third-party functionality that could normally be used for similar tasks and what standard-library primitives are available instead.

The part that surprised me

The biggest lesson wasn't:

"Python has a lot in its standard library."

I already knew that.

The bigger lesson was:

Packages hide engineering decisions.

When you install a library, you inherit decisions about:

  • data structures
  • error handling
  • parsing behavior
  • edge cases
  • formatting
  • APIs
  • performance trade-offs

When you remove the package, those decisions become yours.

That's both the difficult part and the educational part.

What was harder than the documentation made it look

The standard library makes many things possible.

It doesn't necessarily make them effortless.

The hardest part wasn't importing the modules.

It was designing the behavior.

For example:

1. Correlation isn't just parsing

Finding events is easy.

Deciding which events belong to the same attack chain requires rules.

2. A report needs an explanation

Generating a score is easy.

Generating a score that a human can understand requires more thought.

3. Dependency removal changes the architecture

Without a framework doing work for you, every layer has to have a clear responsibility.

That pushed TraceLock toward a modular design:

parser
correlator
risk
story
evidence
behavior
anomaly
mitre
recommendation
report
cli
Enter fullscreen mode Exit fullscreen mode

4. Zero dependency also means zero hiding

If something goes wrong, there's no package to blame.

The behavior is yours.

And that's actually a good thing for learning.

Testing it

I didn't want the zero-dependency claim to be just something written in the README.

TraceLock includes automated tests.

Running:

python -m pytest -v
Enter fullscreen mode Exit fullscreen mode

produces four passing tests covering:

test_normal_login
test_brute_force
test_command_activity
test_full_attack_chain
Enter fullscreen mode Exit fullscreen mode

The important distinction is that pytest is a development/testing dependency only.

It is not required to run TraceLock.

The runtime itself uses only Python's standard library.

Proving the dependency claim

I also included a deps-proof.txt file in the repository.

The proof records:

Python: 3.13.14
Runtime dependencies: STANDARD LIBRARY ONLY
Third-party runtime packages: 0
Enter fullscreen mode Exit fullscreen mode

The repository also includes:

STDLIB.md
Enter fullscreen mode Exit fullscreen mode

which documents the standard-library approach and the development-only testing dependency.

The goal was to make the claim verifiable rather than simply saying:

"Trust me, bro. No dependencies."

A real run

Using the included synthetic attack log:

python -m tracelock.cli examples\sample_attack.log --json reports\sample_attack.json
Enter fullscreen mode Exit fullscreen mode

TraceLock detects:

Attack chains detected: 1

Title:
Credential Attack → Successful Access → Command Execution → Privileged Activity

Risk:
CRITICAL

Score:
100/100

Evidence:
5 items

Behavior:
Credential Compromise → Privilege Escalation

Behavior confidence:
95%

Anomaly:
100/100

Severity:
CRITICAL
Enter fullscreen mode Exit fullscreen mode

It also generates the JSON report successfully.

The sample scenario contains five authentication failures followed by successful authentication, command execution, and privileged activity.

What I learned

This hackathon changed the way I look at dependencies.

Before this project, the mental model was often:

Need feature
    ↓
Search package
    ↓
Install package
    ↓
Use package
Enter fullscreen mode Exit fullscreen mode

Zero Dependency forced me to think:

Need feature
    ↓
What does the feature actually require?
    ↓
What does the language already provide?
    ↓
Can I compose those primitives?
    ↓
What trade-offs am I accepting?
Enter fullscreen mode Exit fullscreen mode

That second process takes more effort.

But it teaches you what's actually happening underneath the abstraction.

Does this mean third-party packages are bad?

No.

That isn't the lesson I took from the hackathon.

Libraries exist for good reasons.

A mature package can provide:

  • better edge-case handling
  • stronger performance
  • broader compatibility
  • years of maintenance
  • extensive testing
  • features that aren't worth rebuilding yourself

I wouldn't recommend replacing every dependency with handwritten code in a production system.

The lesson is different:

Know what you're depending on.

And know enough about the underlying problem that you can recognize when a dependency is genuinely valuable versus when you're importing an entire abstraction for a small piece of functionality.

Why TraceLock matters

TraceLock is not intended to replace a production SIEM, EDR, SOC, or professional incident-response platform.

It's a lightweight security-analysis engine and an exploration of how far you can go with Python's standard library.

The interesting part isn't just that it has zero runtime dependencies.

It's that a reasonably complete pipeline can still exist:

Logs
 ↓
Parsing
 ↓
Correlation
 ↓
Attack reconstruction
 ↓
Evidence
 ↓
Behavior
 ↓
Anomaly detection
 ↓
Risk scoring
 ↓
MITRE context
 ↓
Recommendations
 ↓
Reports
Enter fullscreen mode Exit fullscreen mode

All without installing a runtime package.

Final thoughts

The most useful thing I got from Zero Dependency wasn't a dependency-free project.

It was a better question.

Instead of immediately asking:

"Which package should I install?"

I now ask:

"What is the package actually doing for me?"

Sometimes the answer is:

"A lot. Use the package."

Sometimes it's:

"I can build this from the standard library."

Knowing the difference is the real skill.

TraceLock was my attempt to put that idea into practice — by building a security event correlation and attack analysis engine from Python's standard library, documenting the substitutions, testing the implementation, and proving that the runtime dependency count is zero.

And honestly, writing the code was only half the challenge.

The other half was discovering what I had been letting packages hide from me.

Try TraceLock

The source code, example logs, tests, dependency proof, standard-library documentation, and usage instructions are available in the TraceLock GitHub repository.

If you're interested in security tooling, dependency reduction, or simply understanding what your language can do before reaching for another package, feel free to explore it.

Top comments (0)