Markdown Here Browser Permissions: How Host Access is Configured
Markdown Here requires activeTab, contextMenus, storage, and scripting permissions by default, using optional host permissions to request access to specific websites only when users initiate markdown conversion.
The adam-p/markdown-here repository implements a WebExtension that runs across Chrome, Edge, Firefox, and other Chromium-based browsers. Instead of requesting blanket access to all websites at installation, the extension follows the principle of least privilege by declaring broad host patterns as optional permissions in src/manifest.json and dynamically requesting them at runtime through the Chrome permissions API.
Core Permissions Declared in the Manifest
The foundation of Markdown Here's security model lies in its src/manifest.json, where four primary permissions enable basic functionality without granting unrestricted website access.
activeTab allows the extension to inject scripts into whichever tab the user has explicitly activated via the toolbar button or context menu. This provides temporary access to the current page without requiring permanent host permissions for every site.
contextMenus enables the "Convert Markdown to HTML" entry that appears when users right-click editable fields, creating the primary user interface for triggering conversions.
storage persists user preferences including the "forgot-to-render" check and theme settings across browser sessions.
scripting (required by Manifest V3) authorizes programmatic script injection through chrome.scripting.executeScript, which the extension uses to load chrome/contentscript.js into active tabs.
How Host Permissions Are Configured
Unlike many extensions that request broad host access during installation, Markdown Here configures optional host permissions covering http://*/* and https://*/* patterns. This declaration in src/manifest.json makes these permissions available but not granted until explicitly requested.
The runtime permission management logic resides in src/common/content-permissions.js, which wraps the Chrome permissions API. When the extension needs to read a page's HTML or inject CSS for markdown rendering, it first checks whether the specific origin has been granted access:
// origin must end with a trailing slash, e.g. "https://mail.google.com/"
const origin = `${window.location.protocol}//${window.location.host}/`;
ContentPermissions.hasPermission(origin).then(granted => {
if (!granted) {
// Ask the user for permission
ContentPermissions.requestPermission([origin]).then(result => {
if (result) {
console.log('Permission granted – can render markdown now.');
} else {
console.warn('User denied permission.');
}
});
} else {
console.log('Already have permission for', origin);
}
});
If ContentPermissions.hasPermission() returns false, the extension calls ContentPermissions.requestPermission([origin]), which internally invokes chrome.permissions.request({origins: [...]}). The browser then displays a native permission prompt asking the user to allow access to that specific site.
The Host Permission Workflow in Action
The escalation from minimal privileges to full host access follows a strict user-initiated workflow designed to respect user privacy:
-
Initial State: Upon installation, the extension only possesses
activeTabprivileges, giving it temporary access only when the user clicks the extension button on the current tab. -
Conversion Trigger: When a user selects "Convert Markdown" from the context menu or toolbar,
src/chrome/backgroundscript.jsqueries the active tab and attempts to injectsrc/chrome/contentscript.js:
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
const tabId = tabs[0].id;
chrome.scripting.executeScript({
target: {tabId},
files: ['chrome/contentscript.js']
});
});
-
Permission Check: The content script needs to read the page's DOM and inject CSS for rendered markdown. Before proceeding, it checks whether the required origin is granted via the
ContentPermissionshelper. -
Dynamic Request: If the permission is missing, the extension triggers the browser's permission prompt. The user must explicitly approve access to that specific origin before any DOM manipulation occurs.
-
Operational State: Once granted, the extension can read/write the page's DOM and inject stylesheets, completing the markdown conversion for that domain until the permission is revoked.
Summary
-
Default Permissions: Markdown Here operates initially with only
activeTab,contextMenus,storage, andscriptingrights, minimizing its attack surface. -
Optional Host Access: Broad URL patterns (
http://*/*,https://*/*) are declared as optional insrc/manifest.jsonrather than required permissions. -
Runtime Requests: The
ContentPermissionsclass insrc/common/content-permissions.jsmanages dynamic permission checks and requests using the Chrome permissions API. -
User Consent: Host access is only requested when users explicitly initiate a markdown conversion on a new domain, following the principle of least privilege.
-
Revocable Access: Users can revoke granted host permissions at any time through the browser's extension settings without breaking the extension's core functionality on other sites.
Frequently Asked Questions
What happens if I deny host permissions when prompted?
If you decline the permission request, the extension cannot read the page content or inject the necessary CSS for rendering markdown. The conversion will fail silently or display a notification indicating that permission is required to proceed. You can trigger the permission prompt again by attempting to convert markdown on the same site.
Why does Markdown Here use optional permissions instead of requesting all sites upfront?
According to the source code implementation in src/manifest.json, using optional host permissions respects the principle of least privilege. This design prevents the extension from accessing website data until you explicitly choose to use the tool on a specific domain, reducing security risks and privacy concerns compared to extensions that request <all_urls> at installation.
How can I revoke permissions granted to Markdown Here?
You can revoke specific host permissions through your browser's extension management interface. Navigate to the extension details page for Markdown Here, locate the "Site access" or "Permissions" section, and remove individual domains or reset permissions entirely. The extension will continue to function on other sites where permissions remain granted, or you can grant access again later when needed.
Does Markdown Here work without any host permissions?
The extension can partially function using only the activeTab permission, which provides temporary access when you click the extension button. However, for persistent functionality across page reloads or for sites where you want seamless markdown conversion without clicking the toolbar each time, granting the specific host permission provides a smoother experience.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →