twofas/sdk
PHP SDK for integrating 2FAS two-factor authentication into your applications. A lightweight client with straightforward configuration and clean, framework-friendly APIs for adding an extra layer of account security to Laravel and other PHP projects.
Architecture fit. twofas/sdk is a plain PHP HTTP client for the 2fas.com API, not a Laravel package — no service provider, no facade, no publishable config, no auto-discovery. From a TPM's seat, that is the first scoping fact: the integration work is ours, not the vendor's, and it lands on our side of the boundary. Correct placement is an infrastructure adapter behind a domain-owned interface (TwoFactorVendorClient or similar) bound in AppServiceProvider, with SDK types confined to one namespace. Nothing about its DTOs or HTTP semantics should reach controllers, jobs, or auth guards. The architectural question to answer before any ticket is written is whether this touches the authentication path at all — a vendor SDK inside auth is high blast radius, and the decision to accept that belongs in design review, not in a sprint.
Integration feasibility. Mechanically trivial: composer require, construct the client, call methods. A happy-path spike is days, not weeks. The uncertainty is strategic, not technical. 2FAS is a consumer authenticator vendor; the API backs their own mobile and extension clients, and there is no evidence of a versioned, documented, third-party-facing contract. We would be building against a de facto private API. Zero stars and zero dependents means there is no field validation to inherit — no production war story, no failure taxonomy, no compatibility matrix, and no one to call.
Technical risk. Four risks matter to a delivery plan, and they are not equally weighted:
Key questions. These gate the spike, and each has an owner:
What this SDK is not. It is not a TOTP/HOTP verification library. If the requirement is "2FA on our own login," the answer is Fortify, pragmarx/google2fa, or the IdP — full stop. Letting the package name create ambiguity in a planning doc is a real and cheap-to-avoid failure mode.
Stack fit. It runs on PHP 8.x + Guzzle and therefore works under Laravel 10/11, but it duplicates Laravel's Http client, retry, and middleware facilities rather than using them. Two viable options: wrap the SDK thinly and accept the duplicate transport, or fork the transport layer onto Illuminate\Support\Facades\Http so we inherit timeout, retry, and observability conventions we already operate. Either way, configuration belongs in config/services.php under a twofas key sourced from env or a secrets manager — never hardcoded in the SDK constructor.
Migration path. Start with the baseline check: standard TOTP is a solved, self-hostable problem. If the requirement is generic TOTP, there is no migration to do and no reason to be here. The SDK earns a place only against a named interop goal — importing a user's existing 2FAS codes during onboarding, pairing with the 2FAS app, or consuming their push-approval flow. Scope adoption to that goal and nothing wider. If adopted, the change is additive: introduce the interface, ship a NullTwoFactorClient and a local-TOTP implementation alongside it, and make the vendor path opt-in per tenant.
Compatibility. No stable version means pinning to a commit (dev-main#<sha>) with a committed lockfile, and vendoring or forking the repo into our VCS. Do not float on a branch. Verify the PHP constraint, Guzzle major, and psr/http-client against the existing dependency graph before committing sprint capacity to the spike — a resolver conflict is a cheap way to lose a week.
Sequencing. This is the delivery plan I would defend, with explicit kill gates:
Step 1 is the decision point. Steps 2–6 are only funded if step 1 produces a documented API and a reachable counterparty.
Maintenance. Effectively self-maintained. Zero stars and zero dependents means we are the first serious user and likely the only operator of this code in the wild; assume we own the fork within two quarters. Budget roughly 10–15% of one engineer for drift, dependency bumps, and fixture updates. Every vendor-side schema change surfaces as our incident. This is a standing line item, not a one-time integration ticket — treat it that way in planning or it becomes invisible overhead.
Support. No support contract, no SLA, no issue triage guarantee, and escalation to 2FAS is unlikely for a third-party wrapper. Name an owner and write a runbook before launch, not after the first page.
Scaling. Rate limits and quotas are unknown; assume per-key throttling and design a client-side limiter. Model worst-case login QPS against an assumed ceiling and validate empirically during the spike. Keep the SDK off the synchronous login hot path wherever possible — queue sync and backup operations — with a timeout budget around 800ms and a circuit breaker at the adapter boundary.
Failure modes. Vendor outage becomes authentication outage if called inline (mitigate: fallback-to-local-TOTP plus breaker). Silent auth failures and schema drift after an unannounced API change. Shared API key leakage as a single point of compromise across all tenants. Retry storms against a rate-limited endpoint with no backoff. Key rotation with no documented procedure. Each of these should have a named owner and a tested response before the feature is customer-facing.
Ramp-up. Code comprehension is a few days — it is a small HTTP wrapper. The real cost is the undocumented API and the vendor relationship, which nobody on the team currently has context on. Plan for one engineer to own vendor liaison, the fork, and the runbook; onboarding a second is cheap once fixtures and contract tests exist. Plan for one engineer to own vendor liaison, the fork, and the runbook; onboarding a second is cheap once fixtures and contract tests exist. Budget two weeks of that engineer's time before any roadmap commitment is made.
Recommendation: conditional, spike-first. Do not place this SDK in the critical authentication path. Fund a 3–5 day spike to determine whether 2FAS import is worth a feature, then decide build/buy/drop with real data. If it proceeds, it proceeds pinned, forked, wrapped behind a domain interface, feature-flagged, with a local-TOTP fallback proven to work. If the API is undocumented or the terms do not permit our use, use a self-hosted TOTP library and revisit when 2FAS publishes a supported, versioned API.
The caveat to carry into the funding conversation: with zero stars and zero dependents, we are the first serious user. That is sometimes an opportunity and usually a warning. Fund accordingly.
How can I help you explore Laravel packages today?