Architecture overview

The cryptography, end to end.

This page is a public summary of Makro's security architecture: the algorithms we use, the trust boundaries our code crosses, and the OWASP items we treat as non-optional. It is deliberately high-level. For a deeper review - including exact code paths, test fixtures, and internal threat-model documents - contact security@makroexpander.com and we will arrange it under a standard NDA.

A / Key lifecycle

Two separate keys, one direction.

Macro encryption uses one key for local storage and a different key for cloud sync. Both are generated on your device and neither is transmitted to our servers.

Device key (local storage)
GeneratedFirst installFrom crypto.getRandomValues · derives a 256-bit AES key via PBKDF2-SHA256 at 600,000 iterations
Storage realismBrowser-managedThe derived AES-GCM CryptoKey is non-extractable. Its underlying seed lives in the extension's isolated storage partition. Protection covers disk-level access and other extensions; it does not protect against same-user malware with runtime access to this extension's storage. That limitation is documented in the source.
LifetimeInstall to uninstallWiped on uninstall · no remote escrow · no recovery path
Sync key (cloud sync, zero-knowledge)
Input modesPassphrase (preferred) or licensePassphrase-derived sync decouples encryption from billing: we can revoke a license and still be unable to decrypt your blobs
DerivationPBKDF2-SHA256600,000 iterations · domain-separated by a versioned salt scheme so keys can be rotated without breaking existing data
TransitNeverNeither the passphrase nor the raw license key is sent. License-key auth uses a SHA-256 hash.
PurposeEncrypt sync blobs on this device, before uploadThe server only ever stores ciphertext. Compelled-disclosure requests return ciphertext that we cannot decrypt.
B / Trust boundaries

The places where bytes cross boundaries.

Every trust boundary is a potential attack surface. These are the ones Makro has; we summarise our posture at each rather than list specific mitigations (detail is available to evaluators under NDA).

BOUNDARY 01

Web page DOM -> content script

Hotword detection reads from page fields. A hostile page could try to inject data into extension messages via DOM.
All DOM reads are treated as untrusted input; values are never passed unsanitised to HTML sinks or to background-script message payloads.
BOUNDARY 02

Content script -> background service worker

Messages cross from the untrusted page context into the full-privilege extension context.
Message handlers validate sender identity. Destructive operations require an additional context check. External-extension messages are rejected from unknown senders.
BOUNDARY 03

Extension -> sync API

Encrypted blobs cross the network to Cloudflare Workers for storage.
Payloads are AES-256-GCM ciphertext before they leave the device; TLS 1.3 on top. Background-script cross-origin fetches are whitelisted to our own API host.
BOUNDARY 04

Worker -> D1 database

Stored blobs and billing metadata live in Cloudflare D1.
All queries use parameter-bound prepared statements; string interpolation into SQL is prohibited and audited. The database sees only ciphertext for macro content.
C / OWASP controls

Which specific OWASP items we implement.

OWASP Top 10 is a starting point, not a finish line. Every item below has concrete enforcement - either an audit script that runs per commit or an architectural constraint.

01
Broken access control
Server-side authorization on sync and AI endpoints. Privileged message handlers in the extension validate sender context before mutating state.
02
Cryptographic failures
AES-256-GCM for data at rest. PBKDF2-SHA256 with 600,000 iterations for key derivation. Constant-time comparison for any secret-bearing equality check. No roll-your-own crypto.
03
Injection
Every database query uses parameter-bound prepared statements; string-interpolated SQL is not permitted and is audited out at review time. All HTML rendering paths run dynamic input through an escape helper. No eval, no Function() constructor.
04
Insecure design
Zero-knowledge sync is an architectural choice, not a toggle. Local-only settings block cloud AI calls at the request-forming layer, not after a permission check.
05
Security misconfiguration
Hash-based CSP on every HTML response. HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy set globally. Lint gates regress these if they drift.
08
Software integrity
Extension releases ship only through the official Chrome Web Store and Firefox AMO channels, both with package signing.
D / Audit process

Every commit earns its merge.

The gate is a chain of automated scans and disciplined reviews, with extra attention on anything that touches encryption or data flow.

2,492
Automated tests
Unit + integration suite covering extension, worker, and encryption code
Pre-commit
Lint + scan gates
Security-focused static analysis applied before a change lands
Release
Regression suite
Behavioural checks across XSS, crypto, privacy, input validation, rate limiting, GDPR, data integrity, and i18n
Multi-layer
Review discipline
Automated scans plus review-time scanners plus an extra audit pass on substantial changes

The chain, at a glance.

Security scanning layers up across three categories. We're labelling each with how it's applied so the story is clear without turning the page into an attack-surface map.

1. Local lint on commit. A static-analysis ruleset focused on common security pitfalls runs as a pre-commit hook on the author's machine. The same ruleset runs again in CI, so nothing hides if a local hook is disabled.

2. Automated checks on every pull request. Static analysis, the full unit-test suite, an extension-store linter, a clean release build, and a manifest version-sync check. Failures are visible on the PR and are resolved before merge.

3. Review-time scanners. Secrets scanning, dependency vulnerability checks, SQL-safety audits across database queries, and locale-parity checks across all seven supported languages run as part of our review workflow.

4. Substantial-change policy. Larger diffs receive a second independent audit pass covering the same code through a fresh lens.

5. Release regression suite. Before tagging a release, a behavioural suite revisits previously-fixed classes of bug so that once a vulnerability is addressed it cannot quietly regress.

We are continuing to automate more of this chain over time and will update this page as gates move from process into pipeline.