One of the most common questions we get is: "If AI is changing my passwords, doesn't that mean the AI can see them?"
The short answer is no. Here's exactly how we built the system to make that impossible.
The core problem with AI and passwords
When you ask an AI to help with a task, it typically needs to see everything in the prompt. If we simply told the AI "change the password from OldPass123 to NewPass456", those passwords would be:
- Visible in the AI's context window
- Potentially logged by the AI provider
- Sent over the network to cloud servers
This is exactly what we don't do.
How secure credential injection works
We use a technique called secure credential injection. The AI navigates websites and identifies password fields, but the actual password values are filled in by a completely separate local system.
What the AI sees
Here's a real example of what our AI agent receives during a password change:
Screenshot: Netflix account settings page
DOM elements detected:
- [Input field] "Current Password" (empty)
- [Input field] "New Password" (empty)
- [Input field] "Confirm New Password" (empty)
- [Button] "Save"
Available actions:
- click(element)
- enter_current_password()
- enter_new_password()
Notice what's missing: the actual passwords. The AI sees form fields, buttons, and page structure—everything needed to navigate—but never the credential values.
What happens when the AI acts
When the AI decides to fill a password field, it calls a function like enter_current_password(). Here's the flow:
1. AI: "I see the current password field. Calling enter_current_password()"
2. Local engine receives the function call
3. Local engine retrieves password from secure memory
(Password was loaded from your CSV, stored only in RAM)
4. Local engine injects password directly into browser
(Using Playwright's secure input methods)
5. AI receives confirmation: "Password field filled successfully"
The AI requested an action, but the sensitive data traveled through a completely separate channel that the AI cannot access.
Three layers of protection
Layer 1: Context isolation
The AI model (Gemini 2.5 Flash via OpenRouter) receives screenshots and DOM data to understand the page. When it identifies a password field, it calls a function—but the function's parameters are filled in locally on your Mac, not by the AI.
This is like giving someone directions to a locked room but not the key. They can tell you "turn left, then right, then open the door"—but they can't actually open it themselves.
Layer 2: Memory safety
Passwords exist in memory only as long as absolutely necessary:
password = get_password_from_secure_storage()
try:
browser.fill_field(password)
finally:
# Immediately clear from memory
password = None
gc.collect() # Force garbage collection
After each password operation, we explicitly clear the value and trigger garbage collection. The password isn't sitting around in memory waiting to be discovered.
Layer 3: Comprehensive log redaction
Every log message passes through a redaction filter before being written:
[14:32:01] Navigating to account settings
[14:32:03] Found password change form
[14:32:04] Entering current password: [REDACTED]
[14:32:05] Entering new password: [REDACTED]
[14:32:06] Clicking save button
[14:32:08] Password changed successfully
Even if you shared your log files publicly, no sensitive data would be exposed. We redact passwords, API keys, email addresses, 2FA codes, and any field containing words like "password", "secret", "key", or "token".
Real example: Changing a Netflix password
Here's what actually happens during a password change, step by step:
Step 1: AI receives the task
Task: Change password for netflix.com
Navigate to password settings and use the secure credential functions.
DO NOT type passwords directly - use enter_current_password() and enter_new_password()
Step 2: AI navigates to settings The AI sees a screenshot of Netflix, clicks on the profile menu, navigates to Account, then to Change Password. All navigation is visible to the AI.
Step 3: AI identifies the form
AI thought: "I see three password fields - current, new, and confirm.
I'll call enter_current_password() for the first field."
Step 4: Local injection happens Your Mac's local engine:
- Retrieves the current password from secure memory
- Uses Playwright to fill the field directly in the browser
- Confirms success to the AI (without revealing what was entered)
Step 5: Repeat for new password
The AI calls enter_new_password(), and the local engine fills both the "new" and "confirm" fields with the generated password.
Step 6: AI completes the task The AI clicks Save and verifies the success message appeared.
Throughout this entire process, your actual passwords never appeared in any AI prompt, response, or log.
What gets sent to the cloud
We believe in transparency. Here's exactly what leaves your machine:
Sent to OpenRouter (AI service):
- Screenshots of the websites you're changing passwords on
- DOM structure (HTML elements, button labels, form fields)
- The AI's navigation decisions and function calls
Never sent anywhere:
- Your actual password values
- Your password manager CSV file
- The content filled into password fields
The AI service can see that you're on Netflix's password change page. It can see the form fields exist. It cannot see what gets typed into those fields.
How to verify this yourself
We encourage you to verify our security claims:
Check the activity log
Open Dosel and watch the activity log during a password change. You'll see navigation steps and [REDACTED] placeholders—never actual passwords.
Review the log files
# Check logs for any password exposure
grep -i "your-actual-password" ~/Library/Application\ Support/password-manager-pro/logs/
# Should return: no matches
Monitor network traffic
Use a tool like Charles Proxy or Wireshark. You'll see API calls to OpenRouter containing screenshots and DOM data, but no password strings.
Frequently asked questions
What if OpenRouter logs everything?
Even if OpenRouter logged every single request (they don't, according to their privacy policy), they would see:
- Screenshots of password change pages
- Function calls like
enter_current_password() - Confirmation messages like "field filled successfully"
They would NOT see the actual password values, because those never enter the AI's context.
What about the screenshots—could someone see my password being typed?
Password fields display dots or asterisks by default. The screenshots show ••••••••, not the actual characters. Even visually, your passwords are protected.
Why not make this open source so we can verify?
Fair question. We're considering open-sourcing the core security architecture in the future. For now, you can verify our claims through the methods described above—checking logs, monitoring network traffic, and observing the activity feed.
The bottom line
Dosel uses AI to navigate websites and identify where to click—tasks that require visual understanding. But the sensitive part (your actual credentials) travels through a completely separate, local-only system that the AI cannot access.
It's like having a navigator who can read maps and give directions, but you're the one holding the car keys.
Download Dosel → — 5 free automated password changes per month, no credit card required.
Questions about our security architecture? Email us at security@dosel.app.