Building OAuth Guardian: Part 1

Part 1: The Problem with OAuth Security. A 3-part series in building an open-source OAuth 2.0 security auditor from real-world government experience.

Alexander Garcia is an effective JavaScript Engineer who crafts stunning web experiences.

Alexander Garcia is a meticulous Web Architect who creates scalable, maintainable web solutions.

Alexander Garcia is a passionate Software Consultant who develops extendable, fault-tolerant code.

Alexander Garcia is a detail-oriented Web Developer who builds user-friendly websites.

Alexander Garcia is a passionate Lead Software Engineer who builds user-friendly experiences.

Alexander Garcia is a trailblazing UI Engineer who develops pixel-perfect code and design.

Building OAuth Guardian: Part 1 - The Problem with OAuth Security

A three-part series on building an open-source OAuth 2.0 security auditor from real-world government experience


Why This Tool Needed to Exist

For five years, I served as Lead Frontend Engineer on the Identity team at VA.gov, where I architected and built authentication systems processing over 200 million sign-ins for Veterans and their families. During that time, I hand-wrote custom OAuth 2.0 implementations, built cryptographic libraries from scratch (because we couldn't use external dependencies), and witnessed firsthand how easy it is to misconfigure OAuth even when you deeply understand the specifications.

If a team at the Department of Veterans Affairs with security experts, compliance officers, and rigorous review processes struggles with OAuth configuration complexity, what chance do smaller teams have?

That question led me to build OAuth Guardian a CLI tool and npm package that audits OAuth 2.0 implementations against OWASP, NIST, and RFC specifications.

The Scale of the Problem

OAuth 2.0 has become the de facto standard for authentication and authorization on the web. It powers sign-in for:

  • Social media platforms (Google, Facebook, Twitter)
  • Enterprise applications (Slack, GitHub, Salesforce)
  • Government services (VA.gov, Login.gov, ID.me)
  • Banking and financial services
  • Healthcare portals
  • Countless SaaS applications

But OAuth's flexibility is both its strength and weakness. The spec provides a framework, not a prescription, leaving critical security decisions up to implementers. The result? A minefield of potential vulnerabilities.

Common OAuth Misconfigurations I've Seen

1. Missing PKCE Implementation

The Problem: PKCE (Proof Key for Code Exchange) is a security extension that protects against authorization code interception attacks. It's essential for public clients like mobile apps and single-page applications.

Real-World Impact: At VA.gov, we couldn't use any existing OAuth libraries because of security constraints. I had to hand-write PKCE implementation, including the cryptographic utilities for:

  • Generating code verifiers
  • Creating SHA-256 challenge codes
  • Managing state parameters
  • Validating callbacks

Working with Node v14 meant no modern crypto conveniences I built everything from primitives. This deep dive showed me how easy it is to get PKCE wrong: incorrect challenge generation, improper validation timing, or state parameter mismatches can all compromise security.

Why It's Missed: Many OAuth servers don't require PKCE for backward compatibility, so developers skip it without realizing the risk.

2. Insecure Token Storage

The Problem: Where you store tokens matters as much as how you obtain them.

What I've Seen:

  • Access tokens in localStorage (vulnerable to XSS)
  • Refresh tokens in browser storage (persistent attack surface)
  • Tokens in URL parameters (logged in browser history, proxies, analytics)
  • Tokens without encryption in transit

The Right Way: At VA.gov, we implemented:

  • HttpOnly cookies for session management
  • Secure cookie flags (HttpOnly, Secure, SameSite)
  • Short-lived access tokens
  • Automatic token refresh with rotation

3. Weak Redirect URI Validation

The Problem: If your OAuth server doesn't strictly validate redirect URIs, attackers can steal authorization codes.

Real-World Attack:

Attacker registers: https://evil.com
Legitimate app uses: https://myapp.com

Weak validation accepts: https://myapp.com.evil.com
OR: https://myapp.com@evil.com
OR: https://myapp.com?next=https://evil.com

The Fix: Exact match validation only. No wildcards, no subdomain matching, no query parameter appending.

4. Missing State Parameter (CSRF Protection)

The Problem: The state parameter protects against Cross-Site Request Forgery (CSRF) attacks during the OAuth flow.

How Attacks Work:

  1. Attacker initiates OAuth flow with their account
  2. Attacker sends victim the callback URL with authorization code
  3. Victim clicks link, gets authenticated as attacker
  4. Victim's actions are now performed under attacker's account

Why It's Critical: I built state parameter generation and validation into VA.gov's OAuth implementation. We generate cryptographically random state values, tie them to user sessions, and validate on callback. Without this, account takeover attacks become trivial.

5. Non-Compliant NIST Authentication Assurance Levels

The Problem: Government systems and regulated industries must meet NIST 800-63B compliance for authentication assurance levels (AAL1, AAL2, AAL3).

What I Learned at VA.gov:

  • AAL1: Single-factor authentication (password)
  • AAL2: Multi-factor authentication with approved methods
  • AAL3: Hardware-based authenticators (FIDO2, PIV cards)

We had to ensure our OAuth implementation met AAL2 requirements:

  • Proper MFA enforcement
  • Session timeout policies
  • Reauthentication requirements
  • Authenticator lifecycle management

Most OAuth implementations ignore NIST requirements entirely, even when they're legally required.

Why TypeScript for OAuth Guardian?

When I started building OAuth Guardian, choosing TypeScript wasn't just about personal preference it was strategic:

1. Type Safety for Security-Critical Code

OAuth implementations deal with:

  • Cryptographic operations
  • Token validation
  • URL parsing and validation
  • State management across async operations

One typo in a security check can create vulnerabilities. TypeScript catches these at compile time:

// TypeScript catches this before it becomes a security bug interface CheckResult { status: CheckStatus; // Enum: PASS | FAIL | WARNING | SKIPPED | ERROR severity?: Severity; // Only present when status is FAIL or WARNING } // This fails at compile time: const result: CheckResult = { status: CheckStatus.PASS, severity: Severity.CRITICAL, // ❌ Type error: PASS shouldn't have severity };

2. Self-Documenting Security Checks

OAuth Guardian implements dozens of security checks. TypeScript makes the intent crystal clear:

export interface CheckContext { targetUrl: string; httpClient: HttpClient; logger?: Logger; config?: Record<string, unknown>; } export abstract class BaseCheck { abstract readonly id: string; abstract readonly name: string; abstract readonly category: CheckCategory; abstract readonly defaultSeverity: Severity; abstract readonly description: string; abstract execute(context: CheckContext): Promise<CheckResult>; }

Anyone extending this system knows exactly what's required. No ambiguity.

3. Developer Experience for Security Engineers

OAuth Guardian's target users are security engineers, DevOps teams, and compliance officers. They need:

  • Clear API contracts
  • IntelliSense in their IDE
  • Compile-time guarantees
  • Easy extensibility for custom checks

TypeScript delivers all of this. When someone writes a custom security check, they get full autocomplete and type checking.

4. Future-Proof Architecture

OAuth Guardian started as a CLI tool, but the TypeScript architecture makes it easy to extend:

  • ✅ npm package (programmatic API)
  • 🚀 GitHub Action (coming soon)
  • 🚀 VS Code extension (planned)
  • 🚀 Web dashboard (planned)

TypeScript ensures consistency across all these interfaces.

5. The npm Ecosystem

Choosing TypeScript + Node.js gave me:

  • Rich OAuth/crypto libraries for reference (even though I couldn't use them at VA.gov, I can now)
  • CLI tooling ecosystem (commander, chalk, ora)
  • Testing frameworks (Vitest with first-class TS support)
  • Easy distribution via npm
  • Familiar environment for web developers (my target audience)

What Makes OAuth Guardian Different?

Building this tool from government-scale experience gives it unique advantages:

1. Real-World Vulnerability Knowledge

I've seen OAuth misconfigurations cause:

  • Security incidents requiring emergency patches
  • Failed compliance audits
  • Performance degradation from excessive redirects (27 down to 7 at VA.gov)
  • Credential leaks
  • Account takeover attempts

OAuth Guardian checks for real vulnerabilities, not theoretical ones.

2. Compliance-First Approach

Most security tools focus on OWASP Top 10. OAuth Guardian also validates:

  • NIST 800-63B compliance (AAL levels, session management, authenticator lifecycle)
  • OAuth 2.0 RFC specifications (RFC 6749, RFC 7636 PKCE, RFC 8252)
  • Security Best Current Practice (OAuth 2.0 SCP draft)

This makes it invaluable for government contractors, healthcare, finance, and regulated industries.

3. Actionable Remediation

Every failed check includes:

  • Clear explanation of the vulnerability
  • Impact analysis (what attacks are possible?)
  • Step-by-step remediation guidance
  • Code examples showing the fix
  • Links to RFC specifications and security resources

I learned at VA.gov that security tools that only report "FAIL" are useless. Engineers need to know how to fix it.

4. CI/CD Integration

OAuth Guardian is built for automation:

# Fail builds on critical security issues oauth-guardian $AUTH_SERVER --format json --fail-on critical

This prevents OAuth misconfigurations from reaching production.

What's Next?

In Part 2, I'll walk through the architecture of OAuth Guardian: how the check system works, why I chose specific design patterns, and how TypeScript enabled rapid development without sacrificing security.

In Part 3, I'll share the implementation journey: building the PKCE detection check, implementing the report system, adding YAML configuration with Zod validation, and generating beautiful HTML reports with Handlebars. Plus: the lessons learned shipping an open-source security tool.


Try OAuth Guardian Today

# Install globally npm install -g oauth-guardian # Or use with npx (no installation) npx oauth-guardian https://your-oauth-server.com # Generate HTML report oauth-guardian https://accounts.google.com --format html --output report.html

GitHub: github.com/asg5704/oauth-guardian npm: npmjs.com/package/oauth-guardian


About the Author

Alexander Garcia is a Lead Frontend Engineer who spent 5+ years building authentication infrastructure at VA.gov, processing 200M+ authentications for Veterans and their families. He hand-wrote OAuth 2.0 implementations, built custom cryptographic libraries, and architected systems serving millions of users.

Connect: alexandergarcia.dev | GitHub | LinkedIn


This is Part 1 of a 3-part series. Read Part 2: Architecture & Design →