Building a Windows security application is easy if the goal is simply to make something that looks secure.
Building one while constantly asking:
“What exactly is the trust boundary here?”
is considerably harder.
That question ended up shaping almost every part of ATLOCK v4.
ATLOCK is a portable Windows security suite I built around several local security capabilities:
NTFS/ACL-based file protection
Local encrypted password vault
Intruder detection
Webcam evidence capture
Local security notifications
System lockdown functionality
Portable executable deployment
This article is not a feature tour.
It's a breakdown of the engineering decisions, boundaries, failure modes, and compromises behind the application.
- The First Architectural Decision: Local-First
The initial architecture was intentionally simple:
┌─────────────────────┐
│ ATLOCK UI │
│ Application │
└──────────┬──────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
File Protection Password Vault Intruder Ops
│ │ │
▼ ▼ ▼
NTFS / ACL Local Storage Camera
│ │ │
└────────────────┼────────────────┘
▼
Local Windows Machine
There is deliberately no requirement for a cloud backend for the core security workflow.
That has an important architectural consequence.
The machine running ATLOCK is both:
the security boundary and the storage boundary.
That sounds simpler.
It isn't.
A local-first architecture removes some remote attack surfaces, but it places much more responsibility on:
Windows access control
local filesystem security
process isolation
secret handling
evidence storage
application lifecycle
crash behavior
local privilege boundaries
So “local” does not automatically mean “secure.”
It simply changes the threat model.
- Threat Modeling Before Feature Engineering
One mistake I wanted to avoid was starting with:
“What cool security features can I add?”
Instead, the more useful question became:
“What assets am I actually protecting?”
For ATLOCK, the relevant assets include:
┌───────────────────────────────┐
│ ASSETS │
├───────────────────────────────┤
│ Password credentials │
│ Protected files │
│ Authentication state │
│ Intrusion evidence │
│ Webcam captures │
│ Application configuration │
│ Security event information │
└───────────────────────────────┘
Each asset has a different security requirement.
For example:
Password vault
Primary concern:
confidentiality + key management
Protected files
Primary concern:
authorization + filesystem enforcement
Intruder evidence
Primary concerns:
confidentiality + integrity + access control + privacy
That distinction matters because applying the same security mechanism everywhere is usually the wrong abstraction.
- Why I Used NTFS ACLs Instead of Reinventing File Permissions
This was one of the most important Windows-specific decisions.
Windows already has a mature filesystem security model.
NTFS permissions can be represented through Access Control Entries (ACEs) inside an Access Control List (ACL) associated with a security descriptor.
Conceptually:
File
│
▼
Security Descriptor
│
└── DACL
│
├── ACE → User A → Allow
├── ACE → User B → Deny
└── ACE → Group X → Allow
Rather than implementing an independent permission abstraction and then trying to enforce it ourselves, ATLOCK works with the operating system's existing authorization model.
This gives the architecture a useful property:
ATLOCK policy
↓
Windows security model
↓
NTFS enforcement
↓
Filesystem operation
The OS remains responsible for the final enforcement layer.
That's important.
A user interface saying:
“This file is protected.”
means almost nothing if the underlying OS doesn't enforce the restriction.
- The Password Vault: Encryption Is Only One Layer
The password vault was another area where I deliberately avoided reducing the discussion to:
“It's encrypted.”
The current implementation uses:
PBKDF2-HMAC-SHA256
for password-based key derivation and:
Fernet
for authenticated encryption.
The conceptual pipeline is:
Master Passphrase
│
▼
PBKDF2-HMAC-SHA256
│
▼
Derived Encryption Key
│
▼
Fernet
│
▼
Encrypted Vault Data
│
▼
Local Storage
The important separation is:
KDF ≠ Encryption
PBKDF2 is not encrypting the vault.
It is deriving key material from a human-supplied secret.
Fernet then uses the resulting key for authenticated encryption.
- Why PBKDF2 Exists
Human passwords generally have far less entropy than randomly generated cryptographic keys.
A naive implementation might attempt:
key = SHA256(password)
and consider the problem solved.
It isn't.
Fast hashes are desirable for many applications.
They're not desirable when an attacker can repeatedly guess passwords.
A password KDF intentionally makes derivation more expensive.
Conceptually:
password
│
├── salt
│
├── iteration count
│
▼
PBKDF2-HMAC-SHA256
│
▼
derived key
ATLOCK v4 uses 200,000 PBKDF2 iterations in the current implementation.
That parameter isn't a magical security number.
It is a cost parameter.
And cost parameters should be treated as tunable engineering decisions rather than permanent constants.
- The Key-Management Problem Is Bigger Than the Cipher
This is probably the most important lesson from implementing the vault.
Suppose someone tells you:
“The vault uses AES.”
That doesn't answer the most interesting question.
Where does the key come from?
And more importantly:
Where is the key when the application isn't running?
A secure encryption primitive cannot compensate for terrible key handling.
The security boundary therefore looks more like:
Master Secret
│
▼
Key Derivation
│
▼
Encryption Key
│
┌───────────┴───────────┐
▼ ▼
Encryption Decryption
│ │
└───────────┬───────────┘
▼
Vault Data
This is also why I don't consider “Fernet + PBKDF2” to be the complete security story.
The surrounding lifecycle matters.
- Fernet and Authenticated Encryption
Fernet is useful here because the vault doesn't merely need confidentiality.
It also needs integrity/authentication.
In simplified terms:
Plaintext
│
▼
Authenticated encryption
│
├── Confidentiality
└── Integrity/authentication
That's fundamentally different from treating encryption as:
plaintext → ciphertext
and then forgetting about tampering.
For a password vault, undetected modification is itself a security problem.
- Intruder Ops Was a Completely Different Engineering Problem
The webcam component introduced an entirely different class of problems.
The conceptual flow is:
Authentication failure
│
▼
Failed-attempt tracking
│
▼
Threshold reached
│
├──────────────┐
▼ ▼
Alert Evidence
│
┌─────┴─────┐
▼ ▼
Photo Video
The capture implementation uses OpenCV, specifically the camera capture interface.
And this introduced several problems I didn't have with normal UI operations.
- Hardware Is Not a Normal Function Call
A camera isn't a deterministic data structure.
It is an external device with state.
It may be:
unavailable
initializing
already occupied
slow to respond
disconnected
exposed through a problematic driver
returning invalid frames
That means this is dangerous conceptually:
button_click()
↓
initialize_camera()
↓
capture()
↓
save()
↓
return_to_UI()
If camera initialization blocks, the UI blocks.
A security application that freezes during a security event is not exactly ideal.
So the capture path needs to be treated as an independent operation rather than something the main UI should blindly wait for.
- The UI Must Not Become the Capture Pipeline
The architecture is closer to:
Main UI
│
Security Event
│
▼
Capture Worker
│
┌─────────┴─────────┐
▼ ▼
Camera File I/O
│ │
└─────────┬─────────┘
▼
Result / Status
│
▼
Main UI
This separation matters because UI responsiveness and hardware I/O have fundamentally different timing characteristics.
The interface should not need to know how long a camera driver takes to initialize.
- Intruder Ops Creates Its Own Threat Model
This was another interesting realization.
You can build a feature intended to improve security...
...and simultaneously create a new sensitive-data repository.
A captured webcam image can be significantly more sensitive than a normal application log.
So the threat model becomes:
Unauthorized login attempt
│
▼
Capture
│
▼
Sensitive evidence
│
▼
Local storage
│
▼
Potential secondary exposure
Now you have to ask:
Who can read the evidence?
What happens if the application directory is copied?
What happens if the local machine is compromised?
How long should evidence remain?
What happens after a false positive?
Can another local user access it?
This is why “the evidence stays local” isn't sufficient as a security argument.
- Security Notifications
ATLOCK also maintains local security-event feedback.
The goal is to keep the event path local:
Security Event
│
├── State Update
├── Evidence
└── Notification
No remote dashboard is required merely to communicate a local event.
This reduces architectural dependency but increases the importance of correct local state management.
- Portable Deployment Is Also a Security Decision
ATLOCK is packaged as a Windows executable.
The application is built using PyInstaller.
The resulting architecture is roughly:
Python application
│
▼
PyInstaller analysis
│
├── Python runtime
├── application modules
├── dependencies
└── resources
│
▼
Windows executable
The advantage is straightforward:
download → execute
But packaging Python into a portable executable introduces its own considerations.
The binary now contains a bundled runtime and application dependencies.
That means the release artifact itself becomes part of the security boundary.
- The “It Works on My Machine” Problem
A desktop security application cannot be evaluated only on the development machine.
Different systems have different:
camera hardware
Windows configurations
permission states
antivirus behavior
user privileges
filesystem layouts
Python/runtime assumptions
driver behavior
A feature that works perfectly on one machine can fail on another for reasons completely outside the Python application logic.
That's why defensive failure handling matters more than the happy path.
For example:
Camera available?
│
┌────┴────┐
│ │
YES NO
│ │
Capture Fail safely
│ │
Save Log/report
│
Release device
The failure path is part of the feature.
Not an afterthought.
- The Architecture I Ended Up With
At a high level:
ATLOCK v4
│
┌───────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Authentication Security State Configuration
│ │ │
├───────────────┼────────────────┤
│ │ │
▼ ▼ ▼
Password Vault File Protection Intruder Ops
│ │ │
▼ ▼ ▼
PBKDF2 + NTFS / ACL OpenCV
Fernet │ │
│ │ │
└───────────────┼────────────────┘
▼
Local Windows OS
The important characteristic isn't that the diagram looks complicated.
It's actually the opposite.
I tried to keep the responsibilities separated.
- What I Deliberately Didn't Build
This is arguably more important than the feature list.
I didn't want ATLOCK to become:
Desktop App
+
Cloud Backend
+
User Accounts
+
Analytics
+
Remote Dashboard
+
Telemetry
+
Synchronization
+
Subscription System
just because those things are technically possible.
Every additional subsystem increases:
complexity
+
dependencies
+
attack surface
+
maintenance burden
+
failure modes
So the architectural question became:
Does this feature materially improve the security objective enough to justify its new trust boundary?
Sometimes the answer is no.
- What ATLOCK Is Not
I'm deliberately not going to claim that ATLOCK replaces:
Microsoft Defender
BitLocker
enterprise EDR
enterprise IAM
professional password managers
dedicated forensic tooling
It doesn't.
Different security products solve different problems.
ATLOCK is an independent Windows security project exploring how multiple local security capabilities can coexist inside a portable desktop application.
That's a much more honest engineering claim.
- What Building It Actually Taught Me
The biggest lesson wasn't:
“I learned encryption.”
It was:
Security is a system property, not a feature.
A secure cipher doesn't make insecure key management secure.
An intrusion detector doesn't automatically make captured evidence secure.
A file-protection UI doesn't matter if the OS isn't enforcing the underlying permission model.
A local-first architecture doesn't automatically protect a compromised machine.
And a security application with 50 features isn't necessarily safer than one with 10.
The security boundary exists across all of them.
- Where ATLOCK Goes From Here
There are still areas I want to improve substantially:
stronger threat-model documentation
deeper testing across Windows configurations
more rigorous vault lifecycle analysis
tighter evidence-storage controls
better failure-path testing
improved permission handling
more defensive hardware handling
security-focused logging
reproducible release builds
Because the uncomfortable part of security engineering is this:
The more you understand the system, the more things you realize you need to verify.
And that's exactly what makes the project interesting.
Final Thought
I started ATLOCK because I wanted to build a Windows security application.
I ended up learning that the difficult part isn't adding security features.
It's deciding where the trust boundaries actually are.
If you're a Windows developer or security engineer, I'd genuinely like to know:
What part of this architecture would you attack first?
Not the UI.
Not the marketing.
The architecture.
🚀 ATLOCK v4:https://github.com/Akhouri-Anmol-Kumar/ATLOCK
🚀One click download link: https://github.com/Akhouri-Anmol-Kumar/ATLOCK/releases/download/v4.0/ATLOCK.zip



Top comments (2)
The key-management question is where I'd attack first: where does the
derived Fernet key live between vault unlock and app close? If it's a
plain Python object in process memory for the session duration, that's
extractable via a memory dump or a debugger attached to the running
process, no need to break PBKDF2 or Fernet at all, just read the RAM
while the vault is unlocked.
Second target: the evidence storage. You've already named the right
questions ("who can read it, what if the directory is copied") but
didn't say what currently answers them. If webcam captures sit as
plain image files with default NTFS permissions rather than something
the vault's own key protects, a second local user account (or anyone
with physical access before lockdown re-engages) reads them directly.
The honesty about what ATLOCK isn't trying to replace is what makes
the rest of this credible though, most solo security projects oversell
scope and undersell threat model, this does the opposite.
Talha, seriously, thank you again for taking the time to go this deep into ATLOCK. 👊
Your first comment already gave me a lot to think about, and this one goes straight into the areas where the implementation actually needs to be challenged rather than just looking at the feature list.
The derived-key lifecycle point is especially important. You're absolutely right that once the vault is unlocked, attacking PBKDF2 or Fernet isn't necessarily the interesting path anymore—the runtime state and what exists in memory become part of the threat model. That's something I need to document and evaluate much more explicitly rather than treating the cryptographic primitives as the end of the story.
And I agree with your second point about Intruder Ops evidence storage. I deliberately called out the questions around access control and copied evidence in the article, but I didn't clearly state what the current implementation actually guarantees. That's a gap in the documentation, and honestly, your comment makes that gap much more obvious.
I really appreciate that you're not just saying “use stronger encryption” and moving on. You're looking at where the actual attack surface moves after the obvious security layer is working.
Also, thanks for pointing out the scope/honesty aspect. I'm intentionally trying not to present ATLOCK as something it isn't. I'd much rather have someone challenge the threat model and find weaknesses than make a huge security claim that doesn't survive technical scrutiny.
These are exactly the kinds of comments I hoped I'd get by publishing the technical side of ATLOCK. Seriously appreciate it. 🙏
I'm going to keep these two areas—key lifecycle/memory exposure and evidence protection—high on my list for the next security review.