ueberauth/guardian
64.9
Adequate · 23 September 2026
3.5k
lines of production code
Elixir
primary language
5
measurements over time
What this system is
This system is a JWT-based authentication library for Elixir applications, providing token generation, verification, and management capabilities. It supports multiple token types, including access and refresh tokens, and allows for flexible permission encoding strategies to handle authorization scopes. The library integrates with the Plug ecosystem to offer secure authentication plugs, session handling, and dynamic secret fetching for key rotation.
How it got here
2015 — Guardian v2.0 migration and scaffolding
9 changes.
This period established the project's foundational tooling and configuration while executing a major migration to Guardian v2.0. The work involved overhauling the authentication architecture to use Joken, restructuring the Plug interface for modern standards, and implementing comprehensive test coverage for the new token and security features.
2016–2019 — JWT token and permissions implementation
9 changes.
This period focused on implementing core JWT token handling with strict validation and support for key rotation, alongside a flexible permissions system with multiple encoding strategies. The work included adding utility tasks for secret generation, establishing comprehensive test coverage for both token and permission modules, and setting up necessary directory structures for future assets and configuration.
Features
Added .dialyzer directory placeholder
A new .dialyzer directory has been created with a .gitkeep file to ensure the directory is tracked by version control, likely to support local Dialyzer PLT files or configuration in the future.
.dialyzer · high confidence
Initial release of Guardian JWT token handling and verification
This change introduces the core JWT token implementation for Guardian, adding \lib/guardian/token/jwt.ex\ and \lib/guardian/token/verify.ex\. It provides the default JWT encoding and decoding logic, including support for dynamic secret fetching via the \SecretFetcher\ behavior (which passes the \kid\ header as a hint for key rotation) and customizable claim verification through the \Guardian.Token.Verify\ behavior. Users can now configure token types, TTLs, allowed algorithms, and drift tolerance, with the default token type set to "access" and a default TTL of 4 weeks.
lib/guardian/token · high confidence
New mix task to generate secure secrets
A new \mix guardian.gen.secret\ task has been added, allowing users to generate cryptographically secure random strings directly from the command line. By default, it produces a 64-character secret using base64url encoding, but users can specify a custom length (minimum 32 characters) to suit their specific security requirements.
lib/mix · high confidence
New permission encoding strategies and plug for flexible permission handling
This change introduces a new permissions system within Guardian, adding a \PermissionEncoding\ behavior and three concrete implementations: \AtomEncoding\, \BitwiseEncoding\, and \TextEncoding\. These modules allow users to define how permissions are serialized and deserialized from claims, supporting integer bitmasks, lists of atoms, and lists of strings. Additionally, a new \Guardian.Permissions.Plug\ is provided to enforce permission checks in the request pipeline, supporting both \:ensure\ (all specified permissions must be present) and \:one\_of\ (at least one of the specified sets must be present) strategies.
lib/guardian/permissions · high confidence
Behavioural changes
Guardian v2.0: Major API overhaul with new token types and refresh/exchange capabilities
This release replaces the previous Guardian implementation with a comprehensive v2.0 architecture, shifting from a simple token generation library to a full-featured authentication system. The default token type has changed from "token" to "access", and token types are now explicitly stored in the JWT "typ" field. The API introduces new core functions: \refresh\ to re-issue tokens with updated expiry times, \exchange\ to swap tokens between types (e.g., refresh to access), and \peek\ to inspect unverified token payloads. Configuration is now resolved at runtime via \Guardian.Config\, and the module requires an implementation module using \use Guardian\ with an \otp\_app\ setting. The underlying token library has been updated to use Joken (replacing the previous Joken/JOSE setup), and the serializer requirement is now enforced via the implementation module rather than a global application config check.
lib · high confidence
Guardian v2.0: Major API overhaul, permissions support, and Joken migration
This release introduces a significant behavioral change to the Guardian API, migrating the underlying JWT library from JOSE to Joken and removing the deprecated \Guardian.Serializer\ and \Guardian.Utils\ modules in favor of a new \Guardian.Config\ module for resolving configuration values. A new \Guardian.Permissions\ plugin allows developers to encode and verify permission sets (similar to OAuth2 scopes) directly within tokens, accessible via new \Guardian.Token\ behavior specs and \Guardian.UUID\ for ID generation. The \Guardian.Plug\ interface has been rewritten to support dynamic secret resolution from the connection, introduce an \api\_sign\_in\ method, and standardize function signatures, while the default token type has shifted from "token" to "access".
lib/guardian · high confidence
Guardian.Plug restructured with new authentication plugs and secure key handling
The Guardian.Plug module has been completely rewritten to align with modern Plug standards, introducing new \EnsureAuthenticated\ and \EnsureNotAuthenticated\ plugs for explicit authentication checks, and a new \SlidingCookie\ plug for automatic token refresh. The existing \VerifyCookie\ plug is now deprecated in favor of \VerifySession\ and \VerifyHeader\, which now support a \refresh\_from\_cookie\ option for seamless token exchange. A new \ErrorHandler\ behavior standardizes error handling across all plugs. Additionally, the \Keys\ module has been updated to prevent atom exhaustion vulnerabilities by using \String.to\_existing\_atom/1\ for lookups, and the \Pipeline\ module now uses private connection storage for configuration.
lib/guardian/plug · high confidence
Migrate configuration syntax and enable Plug header validation
The application configuration has been updated to use the modern \import Config\ syntax instead of the deprecated \use Mix.Config\, aligning with Elixir 1.10+ standards. Additionally, a new configuration option \validate\_header\_keys\_during\_test: true\ has been added for the Plug library, which enforces stricter validation of HTTP header keys during test runs to catch potential issues early.
config · high confidence
Strict validation of JWT time claims and support for auth\_time/max\_age
The JWT verification logic now strictly rejects non-numeric values for the \nbf\ (not before), \exp\ (expiration), and \auth\_time\ claims, returning an \:invalid\_token\ error instead of potentially treating them as valid. Additionally, the system now supports the \auth\_time\ and \max\_age\ claims, allowing applications to enforce a maximum age for tokens by verifying that the current time has not exceeded the authentication time plus the configured \max\_age\ duration.
lib/guardian/token/jwt · high confidence
Test coverage
Added comprehensive test coverage for Guardian.Plug authentication and verification components; Added test coverage for Guardian permissions encoding and validation; Added test coverage for Guardian.Token.Jwt and Guardian.Token.Verify; Added test support modules for token verification and call tracking; Added tests for Guardian configuration and plug helpers; Expanded test suite for Guardian token encoding and signing.
Dependencies
Guardian 2.5.0 release with Elixir 1.13 requirement and dependency overhaul
This entry covers the Guardian library's update to version 2.5.0, which raises the minimum Elixir requirement to 1.13 and significantly restructures the project's build configuration. The \mix.exs\ file now includes comprehensive metadata (maintainers, description, homepage), configures documentation generation via \ex\_doc\ with specific guide groupings, and enables \dialyxir\ for static analysis and \ExCoveralls\ for test coverage. The dependency list has been completely refreshed: \joken\ and \poison\ have been removed, replaced by \jose\ for JWT handling and \jason\ for JSON encoding (used by dev/test tools like \credo\, \ex\_doc\, and \excoveralls\). New development dependencies include \credo\ (1.7.18), \dialyxir\ (1.4.7), and \inch\_ex\ (2.1.0), while runtime dependencies now explicitly include \jose\ and \plug\ (1.19.2).
(dependencies) · high confidence
Housekeeping
Initial project scaffolding and tooling configuration; Placeholder created for guides assets directory.
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 57 → 65 (+7.8)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 98 → 100 (+2.3)
- Architecture 100 → 100 (-0.3)
- Maturity 52 → 53 (+0.8)
- Readiness 50 → 62 (+12.7)
- Security 55 → 79 (+24.0)
Resolved (15)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — no supported dependency manifest was read
- FileTooLong: lib/guardian.ex (lib/guardian.ex)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Medium CVE: EEF-[CVE redacted] (mix.lock)
- No exposed public API
- Off-boarding risk: anonymized user #1
- Test reliability not included
New (18)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- High CVE: [GHSA redacted] (mix.lock)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- No dependency advisory monitoring
- Off-boarding risk: anonymized user #1
- Outdated: credo
- Outdated: dialyxir
- Outdated: ex_doc
- Outdated: plug
- Workflow holding a long-lived secret is unscoped
Changes since last survey
- 6 commits — 4 feature/other, 2 fixes
By area
- (root) — 2 commits
- lib/guardian — 2 commits
- .github/workflows — 1 commit
- test/guardian — 1 commit
Notable commits
- fix: fix(ci): scope the build cache to the toolchain that produced it (#746)
- fix: fix(test): stop asserting atom safety against a global VM counter (#747)
- change: chore: release v2.5.0 (#749)
- change: docs: add markdown formatter to docs output (#750)
- change: feat(plug): select the verifying secret from the connection (#748)
- change: feat: reject non-numeric JWT time claims (#745)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
ueberauth/guardian was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 6e86224f9c0aaebfb7062da2aa2b0f39001cb68a — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.