A Chrome extension that automatically injects authentication headers into HTTP requests based on URL patterns. Built for developers who need to test APIs with different auth tokens across multiple environments.
- 🎯 Pattern-based matching - Target specific domains or subdomains
- 🔐 Bearer token injection - Auto-inject
Authorizationheaders - 📊 Real-time tracking - See which requests are being intercepted
- 🎨 Side panel UI - Context-aware, stays open while browsing
- ⚡ Event-driven - Minimal performance impact with smart caching
- 🌓 Dark mode - Chrome DevTools-inspired aesthetic
🚀 Coming Soon - Extension is currently in review for Chrome Web Store
Once published, you'll be able to install directly from the Chrome Web Store.
-
Clone the repository
git clone https://github.com/prosdevlab/auth-header-injector.git cd auth-header-injector -
Install dependencies
pnpm install
-
Build the extension
pnpm build
-
Load in Chrome
- Open
chrome://extensions/ - Enable "Developer mode"
- Click "Load unpacked"
- Select the
distfolder
- Open
pnpm devThis starts a watch server that auto-rebuilds on file changes. Reload the extension in Chrome to see updates.
-
Open the side panel
- Click the extension icon in Chrome toolbar
- Side panel opens on the right
-
Enable the extension
- Toggle "Enable extension" at the top
-
Add your first rule
- Click "Add Rule"
- Enter a URL pattern (e.g.,
*.api.example.com) - Paste your auth token
- Add an optional label
-
Browse and verify
- Navigate to a page that makes API calls
- See real-time request counts in the context bar
- Verify rules are "active" (intercepting requests)
The extension uses Chrome's urlFilter syntax with wildcard support. Here are common patterns and what they match:
| Pattern | Matches | Example URLs |
|---|---|---|
*example.com |
Base domain + all subdomains | example.comapi.example.comwww.example.com |
*.example.com |
Only subdomains | api.example.comwww.example.com❌ example.com |
api.example.com |
Exact subdomain only | api.example.com❌ example.com❌ www.example.com |
*://api.example.com/* |
Explicit URL match | https://api.example.com/usershttp://api.example.com/auth |
# ❌ Won't match base domain
Pattern: *.github.com
Requests to: github.com/api/... # Not matched!
# ✅ Matches base domain + subdomains
Pattern: *github.com
Requests to: github.com/api/... # Matched!
Requests to: api.github.com/... # Matched!GitHub
Pattern: *github.com
Matches:
✅ https://github.com/api/...
✅ https://api.github.com/...
✅ https://raw.githubusercontent.com/...
Multi-environment API
Pattern: *.lytics.io
Label: Lytics (All Environments)
Matches:
✅ https://api.lytics.io/...
✅ https://c.lytics.io/...
❌ https://lytics.io (base domain)
Staging Only
Pattern: api.staging.example.com
Label: Staging API
Matches:
✅ https://api.staging.example.com/users
❌ https://api.example.com (production)
- Add the rule with your pattern
- Open the Service Worker console:
- Go to
chrome://extensions - Click "Service Worker" under the extension
- Go to
- Navigate to the target site
- Check for logs:
[Request Tracker] ✓ Matched pattern: ...
If you don't see matches, your pattern might be too narrow (e.g., using *.domain.com when you need *domain.com).
- Manifest V3 - Latest Chrome extension API
- React 19 - UI framework
- Shadcn UI - Component library (Radix UI + Tailwind)
- SDK Kit - Plugin architecture for service worker
- Vite - Build tool with watch mode
- TypeScript - Type safety
- Vitest - Unit testing
src/
├── background/ # Service worker
│ ├── plugins/ # SDK Kit plugins
│ │ ├── chromeStorage.ts # Persistent storage
│ │ ├── patternMatcher.ts # URL pattern matching
│ │ └── requestInterceptor.ts # Header injection
│ └── utils/
│ └── requestTracking.ts # Pure functions for tracking
├── panel/ # Side panel UI
│ ├── components/ # React components
│ ├── hooks/ # Custom React hooks
│ └── App.tsx # Main app
└── shared/ # Shared types & utilities
- User adds rule → Saved to
chrome.storage.sync - Storage change event → Updates rule cache in service worker
- Request interceptor → Injects
Authorization: Bearer {token}viadeclarativeNetRequest - Request tracker → Monitors
webRequestevents, updates stats - Side panel UI → Reads stats via
chrome.storage.local, displays real-time
- ✅ Rule caching - Rules stored in memory, ~0ms lookup
- ✅ Batched writes - Stats written every 3s, reduces I/O by ~90%
- ✅ Request debouncing - Duplicate requests ignored for 1s
- ✅ Event-driven UI - Updates via
chrome.storage.onChanged, no polling
- All data is stored locally on your device using Chrome's sync storage
- No external servers - No data is transmitted to any third-party services
- No analytics or tracking - We don't collect any usage data
- Open source - Full code transparency for security auditing
- Tokens are stored in Chrome's encrypted sync storage
- Never logged or transmitted except to your configured domains
- Visible only when you explicitly choose to show them
- Synced securely across your Chrome instances (if Chrome sync is enabled)
We require these permissions for core functionality:
declarativeNetRequest- Inject authentication headers into matching requestsstorage- Store your rules and tokens locallytabs- Detect current page URL for context-aware UIsidePanel- Display the extension interfacewebRequest- Track request statistics (counts only, no content)host_permissions (<all_urls>)- Allow header injection on domains you configure
{
"permissions": [
"declarativeNetRequest", // Inject headers
"storage", // Persist rules & stats
"tabs", // Get current tab URL
"sidePanel", // Side panel UI
"webRequest" // Track requests
],
"host_permissions": [
"<all_urls>" // Match any domain
]
}Sync Storage (rules, synced across devices)
{
auth_rules: AuthRule[]
}
interface AuthRule {
id: string;
pattern: string; // URL pattern
token: string; // Bearer token
label?: string; // Optional label
enabled: boolean;
createdAt: number;
updatedAt: number;
}Local Storage (stats, device-specific)
{
request_stats: {
[domain: string]: {
count: number;
lastSeen: number; // timestamp
ruleIds: string[];
}
}
}# Install dependencies
pnpm install
# Start dev server (watch mode)
pnpm dev
# Build for production
pnpm build
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Lint & format
pnpm lint
pnpm format
# Type check
pnpm type-checkdev- Vite watch mode with auto-rebuildbuild- Production build todist/test- Run Vitest testslint-staged- Pre-commit hooks (Biome + TypeScript)
- Update types in
src/shared/types.ts - Add business logic in
src/background/or hooks - Update UI in
src/panel/components/ - Write tests in
tests/or colocated.test.ts - Update README with usage docs
# Run all tests
pnpm test
# Watch mode
pnpm test:watch
# With coverage
pnpm test -- --coveragetests/
├── setup.ts # Global test setup (Chrome API mocks)
└── src/
└── background/
└── plugins/
├── chromeStorage.test.ts
├── patternMatcher.test.ts
└── requestInterceptor.test.ts
Tests use Vitest with mocked Chrome APIs. See tests/setup.ts for mock implementations.
Problem: You added a rule but don't see request counts increasing.
Solutions:
- Check your pattern - use
*domain.cominstead of*.domain.comif targeting the base domain - Ensure the rule is enabled (toggle in the rules list)
- Ensure the extension is enabled (toggle at top)
- Check the Service Worker console for
[Request Tracker]logs - Verify the site makes API calls (some sites use GraphQL or WebSockets)
Problem: Rules show active but headers aren't being sent.
Solutions:
- Check
chrome://extensionsfor errors - Ensure pattern uses correct syntax (test with
*://domain.com/*) - Verify token format (should be just the token, NOT
Bearer {token}) - Check Network tab in DevTools → Request headers
- Some sites block extension-injected headers (rare, but possible)
Problem: Extension stops working after a while.
Solutions:
- Chrome kills idle service workers after ~30s (normal behavior)
- Extension auto-restarts on next event (opening side panel, new request)
- Check for errors in Service Worker console
- Reload extension if persistent issues
Contributions welcome! Please:
- Fork the repo
- Create a feature branch (
git checkout -b feat/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feat/amazing-feature) - Open a Pull Request
We use Conventional Commits:
feat:- New featurefix:- Bug fixdocs:- Documentation changesstyle:- Code style changes (formatting, no logic change)refactor:- Code refactoringtest:- Adding/updating testschore:- Maintenance tasks
- Export/import rules as JSON
- Multiple auth header types (API-Key, Basic Auth, Custom)
- Rule templates for popular APIs (GitHub, AWS, etc.)
- Request/response logging
- Statistics dashboard
- Cloud sync with encryption
MIT License - see LICENSE for details
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Repository: github.com/prosdevlab/auth-header-injector
- SDK Kit - Plugin architecture for Chrome extensions
- Shadcn UI - Component library
- Lucide Icons - Icon set
- Chrome Extensions Docs - API reference
Built with ❤️ for developers who live in the browser
Free & Open Source • MIT License • ProsDevLab