How we built the Composer auth proxy that serves our Magento modules
Every eTechFlow module installs via Composer from a private repository at repo.etechflow.com. The repository is gated by per-customer credentials that map to a specific license entitlement. This post is the engineering behind that gate: the auth proxy, the credential lifecycle, and the failure modes we designed around.
The problem we needed to solve
When a customer buys a Magento module from us, they need to do two things to install it. First, add our Composer repository to their composer.json. Second, authenticate against that repository with credentials that work for them and only them.
Most Magento module vendors solve this with shared per-vendor credentials (everyone who buys from Amasty uses one set of Amasty credentials) or with email-based credentials (your account email and order number). Both have problems. Shared credentials cannot be revoked when a license is refunded. Email credentials leak through screenshots and bug reports.
We needed credentials that were per-license, revocable, rotatable, and auditable.
The architecture
Three components handle authentication on every install.
Component 1: the auth proxy. A small Node service in front of the actual Composer repository. Every request to repo.etechflow.com hits the proxy first. The proxy reads HTTP basic auth credentials from the request, looks them up against our license database, and decides whether to pass the request through.
Component 2: the license database. Stores credentials keyed to license ID. Each row has the customer ID, the module slug they bought, the credential pair (username plus bcrypt-hashed password), the issue date, optional expiry, revoke status, and last-validated timestamp.
Component 3: the audit log. Every authentication attempt (success or failure) writes a row with IP address, timestamp, requested package, and license ID matched. The audit log is queryable and forms the basis of suspicious-activity alerting.
The full request flow on a composer require etechflow/some-module:
- Composer sends HTTP basic auth to the auth proxy.
- The proxy looks up the credential pair against the license database.
- If valid and not revoked, the proxy forwards the request to the internal Composer registry.
- The internal registry returns the requested package.
- The proxy logs the success and returns the response to Composer.
Total latency overhead: under 50 milliseconds per package fetch. A typical Composer install fetches 1 to 3 packages from us, so the overhead is invisible to the customer.
The credential lifecycle
A credential is generated at module purchase time. The customer email gets the credential pair plus install instructions immediately. The credentials are bound to the license ID, which means they are revoked atomically if the customer refunds (30-day refund window).
After 12 months we expire the credential and email a renewal credential. The old credential keeps working for 90 days during the cutover window so customers can update their auth.json without urgency.
If a customer suspects credential leakage (committed to a public repo, screenshotted in a bug ticket), they can rotate from their account dashboard. Rotation revokes the old credential immediately and issues a new one.
The failure mode we built around
The single biggest risk with this architecture is the auth proxy being unavailable. If repo.etechflow.com goes down, every customer who tries to install or update a module fails. We have three layers of protection:
Geographic redundancy. The auth proxy runs in two regions with active-active routing. A regional outage fails over inside 60 seconds.
Database read replicas. Credential lookups happen against read replicas with a 10-second replication lag. Writes (new credentials, revocations) hit the primary. Read-only paths survive a primary failover.
Graceful degradation. When the database is unreachable entirely, the proxy falls back to a 60-minute credential cache that holds the last successful lookup. Customers installing during that window still succeed. New module purchases pause until the database recovers.
The graceful degradation path has triggered three times since launch. Each time, customers reported no problems.
What we publish to customers
Customers see the architecture indirectly through three surfaces.
The auth.json snippet in their purchase email tells them exactly what to add to their store. The format is standard HTTP basic auth in Composer's expected structure, so any Composer-literate engineer can read it.
The account dashboard shows them all their active credentials, when each was issued, and a one-click rotate button. We do not show the password value after creation; rotation generates a new one.
The audit log is internal-only by default. Customers can request an export of their own credential activity for security reviews.
What we would do differently
Two design choices we would revisit if starting over.
We would use HTTP bearer tokens instead of basic auth. Composer has supported bearer tokens for a few years now and they are cleaner to revoke without breaking installer expectations. We chose basic auth at the start because it works with older Composer versions; the older versions are now rare enough that we could move on.
We would consider OAuth device flow for first-time install. Today the customer has to manually paste credentials into auth.json or run a Composer config command. OAuth device flow would let the install be approved from the customer's browser session. Adds infrastructure but lowers the friction of the first install.
Why this matters for the Magento ecosystem
Most Magento module vendors have not built proper credential infrastructure. The common pattern (shared credentials, email-tied access, no audit log) creates real security gaps. When a Magento store gets compromised through a third-party module, the audit trail back to the vendor's distribution infrastructure is usually empty because no infrastructure existed to log against.
If you are evaluating Magento module vendors, ask them how their Composer authentication works. The answer reveals how seriously they take supply-chain security.
Related
- Composer auth for private Magento repositories covers the customer-side setup.
- Magento extension buyer's guide covers vendor evaluation criteria.