Enterprise-grade Chrome extension for high-volume ads.txt / app-ads.txt authorization auditing with resilient fetch logic, deterministic line matching, and export-ready operational reporting.
Important
This project performs semantic, line-level inventory authorization validation, not simple file-presence checks.
- Title and Description
- Table of Contents
- Features
- Tech Stack & Architecture
- Getting Started
- Testing
- Deployment
- Usage
- Configuration
- License
- Contacts & Community Support
- High-throughput validation engine for
ads.txt,app-ads.txt, and direct URL mode. - Batch-based parallel execution with configurable concurrency control (
1β5targets per batch). - Deterministic tuple validation against reference rows (
domain,publisher-id,account-type). - Partial-match diagnostics for account type mismatch detection.
- Dual protocol retrieval strategy (
https://fallback tohttp://) for resilience across heterogeneous publisher infrastructure. - Retry-enabled fetch with timeout control and transient-failure backoff.
- Soft-404 detection to reject HTML/JSON/XML responses masquerading as text inventory files.
- Input normalization pipeline:
- strips comments,
- removes zero-width characters,
- normalizes case,
- supports optional
TAG-IDparsing.
- Duplicate logical-line detection in target files.
- Metadata enrichment for
OWNERDOMAINandMANAGERDOMAIN. - Two reporting layouts:
Standard(row-level reference checks),Grouped by Target(target-centric matrix output).
- Triage-first filtering mode (
Errors / Warnings Only). - In-session and persistent UX state via
chrome.storage.local. - Export and handoff tooling:
- CSV generation,
- clipboard copy (tab-delimited).
- Progress instrumentation with elapsed-time and per-status counters (
Valid,Partial,Missing,Error).
Tip
Start with smaller batch sizes when auditing unstable domains to reduce temporary network-noise false negatives.
- Platform: Chrome Extension, Manifest V3.
- Language: Vanilla JavaScript (ES2017+), HTML5, CSS3.
- Runtime primitives:
- Extension service worker (
background.js), - popup UI runtime (
popup.html+popup.js), - browser storage API (
chrome.storage.local).
- Extension service worker (
- Security and access model:
- permission:
storage, - host permissions:
http://*/*,https://*/*.
- permission:
.
βββ background.js
βββ popup.html
βββ popup.js
βββ style.css
βββ manifest.json
βββ LICENSE
βββ CONTRIBUTING.md
βββ README.md
βββ icons/
β βββ icon128.png
βββ trigger action/
βββ trigger_action.py
- Extension-first architecture for zero-dependency operator usage and immediate browser-side execution.
- Stateful operator UX to preserve audit context between sessions without backend infrastructure.
- Reference-driven semantic validation rather than regex-only presence matching.
- Soft-404 guarding to prevent false positives from CDN/WAF error pages.
- Output symmetry between on-screen tables and export formats for incident workflows.
flowchart TD
A[Operator inputs targets and references] --> B[Normalize and parse reference tuples]
B --> C{File mode}
C -->|ads.txt or app-ads.txt| D[Build domain endpoint URL]
C -->|direct URL| E[Normalize input URL]
D --> F[Fetch with retry and timeout]
E --> F
F --> G{HTTPS success?}
G -->|No| H[HTTP fallback attempt]
G -->|Yes| I[Read text payload]
H --> I
I --> J{Soft-404 or non-text?}
J -->|Yes| K[Mark Error result rows]
J -->|No| L[Parse target lines and metadata]
L --> M[Match references and classify status]
M --> N[Render table and update counters]
N --> O[Export CSV or copy report]
K --> N
Note
The extension is intentionally dependency-free; no Node.js build chain is required for standard operation.
- Google Chrome (current stable channel recommended).
- Local filesystem access to load an unpacked extension.
- Git CLI (optional but recommended for updates and contribution workflows).
# 1) Clone repository
git clone https://github.com/<your-org>/Inventory-Auth-Auditor.git
cd Inventory-Auth-Auditor
# 2) Open Chrome extension manager
# URL: chrome://extensions/
# 3) Enable "Developer mode"
# 4) Click "Load unpacked" and select the project rootAfter loading, click the extension action icon to launch the auditor window.
The repository currently does not ship an automated test harness; use the operational verification flow below.
1) Load extension in Developer mode.
2) Choose File Type: ads.txt or app-ads.txt.
3) Paste 2-5 known domains and valid reference tuples.
4) Run validation and confirm progress + counters.
5) Confirm at least one Valid and one Missing/Partial path.
6) Export CSV and verify column integrity.
7) Toggle Grouped layout and Errors-only filter.
8) Test Stop control during an active run.
# Validate extension manifest structure
python -m json.tool manifest.json > /dev/null
# Quick JavaScript syntax check (if Node.js is available)
node --check popup.js
node --check background.jsWarning
Cross-domain inventory endpoints may produce transient Connection Error states; rerun suspect targets before escalation.
- Commit and push validated changes.
- Team members pull latest branch.
- Open
chrome://extensions/and clickReloadfor the extension.
zip -r release.zip manifest.json background.js popup.html popup.js style.css icons LICENSE README.md CONTRIBUTING.md- Add a lightweight pipeline that:
- validates JSON manifest syntax,
- performs JavaScript parse checks,
- packages distributable zip artifact.
- Gate release tags on successful validation steps.
- Keep host permissions review in release checklist.
Caution
The declared host permissions are intentionally broad for cross-domain auditing; validate policy expectations before public store publication.
# Target Websites
example.com
news-site.tld
appvendor.tld
# Reference Lines
google.com, pub-1234567890, DIRECT
appnexus.com, 98765, RESELLER
# Target URLs (direct links)
https://publisher-a.com/app-ads.txt
https://publisher-b.net/ads.txt
publisher-c.org/app-ads.txt
# Reference Lines
google.com, pub-1234567890, DIRECT
rubiconproject.com, 998877, RESELLER
// Input references are normalized into deterministic tuples.
const references = rawRefs
.map((line) => line.split(',').map((v) => v.trim()))
.filter((parts) => parts.length >= 2)
.map(([domain, id, type]) => ({
domain: domain.toLowerCase(),
id: id.toLowerCase(),
type: type ? type.toUpperCase().replace(/[^A-Z]/g, '') : null,
}));
// Target file lines are normalized similarly before comparison.
const normalizedTargetLines = content
.split('\n')
.map((line) => line.split('#')[0].trim())
.filter(Boolean)
.map((line) => line.split(',').map((v) => v.trim()));
// Matching is tuple-based: domain + id, then optional type validation.The extension is configured at runtime through the UI and persisted in chrome.storage.local.
targets: multiline target domain or URL list.refs: multiline reference entries.fileType:ads.txt,app-ads.txt, orurl.viewMode:allorerrors.tableLayout:standardorgrouped.batchSize: stringified integer (1β5).
.env: not used.- CLI startup flags: not required for default usage.
- Runtime host access is controlled by
manifest.jsonpermissions.
Primary static config is defined in manifest.json:
{
"manifest_version": 3,
"name": "Inventory Auth Auditor",
"version": "1.5.0",
"permissions": ["storage"],
"host_permissions": ["http://*/*", "https://*/*"],
"background": { "service_worker": "background.js" }
}Note
Persisted configuration is scoped to the local Chrome profile where the extension is installed.
This project is distributed under the GPL-3.0 License. See LICENSE for full terms.
If you find this tool useful, consider leaving a star on GitHub or supporting the author directly.