scheb/2fa-trusted-device
Trusted-device support for scheb/2fa-bundle, letting users skip repeat two-factor prompts on remembered devices
Repository Health
Technical Analysis
scheb/2fa-trusted-device is a companion package for scheb/2fa-bundle, the Symfony two-factor authentication bundle. It adds “remember this device” functionality so users who have already completed 2FA on a browser or device are not prompted again for a configurable trust period. The package issues a signed, encrypted cookie encoding the trusted device, validates it on subsequent logins, and exposes the plumbing (token storage, JWT encoding, security event listeners) needed to wire trusted-device checks into a Symfony authentication flow.
Because it is published as a read-only split of the monorepo at github.com/scheb/2fa, it ships as a small, focused Composer package: a handful of classes covering token encoding, cookie response handling, and the authenticator passport badge/condition that Symfony’s security system checks during login. Applications install it alongside scheb/2fa-bundle rather than using it standalone.
What You Get
- A
TrustedDeviceManagerthat checks and creates trusted-device records tied to a user and generates a signed token - JWT-based token encoding (
JwtTokenEncodervia lcobucci/jwt) so the trusted-device cookie is tamper-evident - A
TrustedCookieResponseListenerthat automatically attaches the trusted-device cookie to the HTTP response after successful 2FA - A
TrustedDeviceConditionandTrustedDeviceBadge/listener that integrate with Symfony’s authenticator passport system to skip the 2FA step when a valid trusted-device cookie is present - A
NullTrustedDeviceManagerfallback implementation for when trusted-device support is disabled
Common Use Cases
- Reducing repeated 2FA prompts for users logging in from their usual browser or device
- Implementing a “remember this device for 30 days” checkbox on a Symfony login/2FA form
- Building custom trust-duration or device-fingerprinting policies on top of the provided interfaces
- Auditing or revoking trusted devices per user via the
TrustedDeviceManagerInterface
Under The Hood
Architecture — The package is a thin extension layer over scheb/2fa-bundle’s authentication pipeline. TrustedDeviceManager (Security/TwoFactor/Trusted/TrustedDeviceManager.php) implements TrustedDeviceManagerInterface and is the central service: it checks whether a request’s cookie token matches a trusted device for the current user (isTrustedDevice) and creates new trust tokens (addTrustedDevice). Token encoding is delegated to TrustedDeviceTokenEncoder, which itself wraps JwtTokenEncoder (Security/TwoFactor/Trusted/JwtTokenEncoder.php) to produce a compact, cryptographically-signed JWT via lcobucci/jwt and lcobucci/clock for time handling. TrustedCookieResponseListener hooks Symfony’s kernel response event to attach the resulting cookie after a successful 2FA response. On the read side, TrustedDeviceCondition (Security/TwoFactor/Condition/TrustedDeviceCondition.php) is consulted by the bundle’s 2FA-required-check chain, and TrustedDeviceListener plus TrustedDeviceBadge (Security/Http/EventListener and Security/Http/Authenticator/Passport/Badge) integrate with Symfony’s newer Authenticator/Passport security system so a valid trusted-device badge can short-circuit the 2FA requirement during authentication. Tech Stack — Pure PHP 8.4/8.5, PSR-4 autoloaded under the Scheb\TwoFactorBundle namespace (it shares the umbrella namespace with the parent bundle rather than having its own). Direct dependencies are scheb/2fa-bundle (version-locked via self.version since it’s split from the same monorepo release), lcobucci/clock for injectable/testable time, and lcobucci/jwt for JWT signing/verification — no framework-heavy dependencies beyond Symfony’s security contracts pulled transitively through the parent bundle. Code Quality — This split repository ships only the Model and Security source directories; tests, CI config, and contribution tooling live in the upstream monorepo (github.com/scheb/2fa) since this repo is explicitly read-only. The code itself is small (roughly a dozen focused classes, ~660 lines) with narrow single-responsibility interfaces (TrustedDeviceManagerInterface, TrustedDeviceTokenEncoder) that make the trust/token logic swappable. API Design — Consumers rarely interact with this package’s classes directly; it’s designed to be auto-wired by scheb/2fa-bundle’s service configuration and controlled entirely through the parent bundle’s YAML config (trusted-device lifetime, cookie name, etc.), keeping the public surface minimal and the integration low-boilerplate.