Skip to main content

OAuth 2.1 Security Implementation

Plugged.in implements OAuth 2.1 security best practices to ensure the highest level of security for MCP server authentication. This document outlines the security measures in place.

OAuth 2.1 Overview

OAuth 2.1 is the next evolution of the OAuth 2.0 framework, consolidating security best practices from various OAuth extensions and eliminating insecure patterns.
Key Difference: OAuth 2.1 is NOT a separate specification, but rather a consolidation of OAuth 2.0 + security best practices (PKCE, token rotation, etc.)

Implemented Security Features

1. PKCE (Proof Key for Code Exchange)

RFC 7636 - Mandatory for all OAuth flows

Protection Against

  • Authorization code interception attacks
  • Code injection attacks
  • Man-in-the-middle attacks

Implementation

  • S256 challenge method (SHA-256)
  • 256-bit code verifier entropy
  • Automatic verification on callback
How it works:

2. State Parameter Integrity Binding

OAuth 2.1 Best Practice - Prevents PKCE state tampering
Attack Prevented: Attackers cannot modify stored PKCE state parameters (server UUID, user ID, code verifier) to steal tokens or hijack flows.
Implementation:
Files:
  • lib/oauth/integrity.ts - HMAC generation and verification
  • app/actions/trigger-mcp-oauth.ts - Hash creation
  • app/api/oauth/callback/route.ts - Hash verification

3. Reduced PKCE Expiration (5 Minutes)

OAuth 2.1 Recommendation - Reduced attack window
OAuth 2.1 recommends shorter PKCE state expiration to minimize the window for:
  • Replay attacks
  • Code interception attempts
  • State prediction attacks
Previous: 10 minutes (OAuth 2.0 typical) Current: 5 minutes (OAuth 2.1 recommended)
Files:
  • db/schema.ts - Schema documentation
  • app/actions/trigger-mcp-oauth.ts:447 - State creation
  • app/api/oauth/callback/route.ts:166 - Expiration check

4. Refresh Token Rotation

OAuth 2.1 Best Practice - Prevents token reuse attacks

Single-Use Tokens

Each refresh token can only be used once. After use, it’s immediately invalidated.

Reuse Detection

If a refresh token is reused, all tokens are revoked as a security measure.
Implementation Flow: Code:
Database Schema:
Files:
  • db/schema.ts:1940 - Schema definition
  • lib/oauth/token-refresh-service.ts:97-104 - Reuse detection
  • lib/oauth/token-refresh-service.ts:128-139 - Mark as used
  • lib/oauth/token-refresh-service.ts:179-190 - Store new tokens

5. HTTP Basic Authentication for Client Credentials

RFC 6749 Section 2.3.1 - Prevents credential logging
Security Issue: Sending client_secret in URL-encoded body causes it to be logged in:
  • Proxy access logs
  • WAF logs
  • Server access logs
  • Load balancer logs
Secure Method:
Files:
  • lib/oauth/token-refresh-service.ts:134-140 - Token refresh
  • app/api/oauth/callback/route.ts - Token exchange

Security Enhancements Summary


Attack Scenarios Prevented

Before OAuth 2.1 Implementation

Authorization Code Injection → Attacker could hijack victim’s OAuth flow Token Reuse Attacks → Stolen refresh tokens could be used indefinitely State Parameter Tampering → Attacker could modify PKCE state to steal tokens Credential Logging → Client secrets exposed in access logs Extended Attack Window → 10-minute PKCE expiration too long

After OAuth 2.1 Implementation

All OAuth flows bound to authenticated userRefresh tokens are single-use onlyHMAC integrity verification prevents tamperingClient secrets never logged (HTTP Basic Auth)5-minute PKCE expiration reduces riskAutomatic token revocation on reuseServer ownership validationRate limiting on OAuth endpoints

Multi-Instance & Production Requirements

Redis Rate Limiting (CRITICAL)

Multi-Instance Deployments: Redis is REQUIRED for distributed rate limiting when running multiple application instances. In-memory rate limiting is NOT SAFE for horizontal scaling.
Why Redis is Required:
  • Rate limits are enforced per instance with in-memory storage
  • Attackers can bypass rate limits by distributing requests across instances
  • OAuth callback rate limits become ineffective
  • Token refresh rate limits become ineffective
Setup:
Verification: The application will log on startup:
If you see this warning in production:
Action required: Configure REDIS_URL immediately.

Performance Optimizations

OAuth Config Caching

OAuth configurations are cached for 5 minutes to reduce database load:
Impact: Significantly reduces database queries for frequently refreshed tokens.

Server Ownership Validation

Optimized from 3 sequential queries to 1 JOIN query:
Impact: 60-70% latency improvement for token refresh operations.

Request Timeouts

All OAuth API calls now have 10-second timeouts:
Impact: Prevents resource exhaustion from unresponsive OAuth providers.

IPv6 Support

Metrics endpoint now supports IPv6 CIDR validation:

Production Security Checklist

Pre-Production Checklist

Rate Limiting:
  • Redis configured with REDIS_URL
  • Verify Redis connection on startup
  • No rate limit warnings in production logs
Metrics Security:
  • METRICS_ALLOWED_IPS restricted to Prometheus IP only
  • Default 10.0.0.0/8 removed (16.7M IPs)
  • IPv6 ranges validated if applicable
OAuth Configuration:
  • All instances share same NEXTAUTH_SECRET
  • All instances connect to same database
  • OAuth config caching verified (check logs)
Performance:
  • Database connection pooling configured
  • Server ownership queries optimized (JOIN)
  • Request timeouts enabled (10s)

Multi-Instance Deployment

For complete multi-instance deployment guide, see:

Multi-Instance Deployment

Production-ready horizontal scaling with Redis, load balancing, and high availability

Migration Notes

Database Changes

Two migrations were applied to support OAuth 2.1: Migration 0071: State Integrity Hash
Migration 0072: Refresh Token Rotation

Backward Compatibility

Fully Backward Compatible
  • Existing OAuth flows continue to work
  • New security features apply to all new flows
  • No breaking changes to API
  • Automatic migration on application upgrade

Environment Variables

Required

.env
.env

Monitoring & Observability

Structured Logging with Loki

Plugged.in uses structured JSON logging with Loki for comprehensive OAuth security monitoring. All security events are automatically logged with full context for analysis.
See Observability Documentation for complete setup guide

Security Events Logged

All OAuth operations emit structured JSON logs to Loki:

LogQL Security Queries

Critical Security Events (Last Hour):
All Integrity Violations:
Token Refresh Failures:
OAuth Flow Success Rate:

Prometheus Metrics

17 OAuth-specific metrics for real-time monitoring:

Flow Success Rate

oauth_flows_total{status="success"} / oauth_flows_totalSLO: > 95%

Token Reuse Detection

oauth_token_refresh_total{status="reuse_detected"}Alert: > 0 (Critical)

Code Injection Attempts

oauth_code_injection_attempts_totalAlert: > 0 (Critical)

Integrity Violations

oauth_integrity_violations_totalAlert: > 0 (High)
PromQL Alert Queries:

Grafana Dashboards

Pre-built dashboards available in /observability/dashboards:

OAuth Overview

  • Success rates
  • Operations/min
  • Active tokens
  • Error trends

Security Dashboard

  • Security events timeline
  • Attack heatmap
  • Top attackers
  • Violation breakdown

Performance Dashboard

  • Latency percentiles (p50, p95, p99)
  • Throughput by provider
  • Slow operations
  • Discovery performance

Critical Alerts Configuration

Configure these alerts in Grafana:

Metrics to Monitor

percentage
required
SLO: > 95%Metric: oauth_flows_total{status="success"} / oauth_flows_totalAlert if: < 95% for 5 minutes
percentage
required
SLO: > 99%Metric: oauth_token_refresh_total{status="success"} / oauth_token_refresh_totalAlert if: < 99% for 5 minutes
counter
required
Expected: 0Metric: oauth_token_refresh_total{status="reuse_detected"}Alert if: > 0 (IMMEDIATE - Critical)
counter
required
Expected: 0Metric: oauth_code_injection_attempts_totalAlert if: > 0 (IMMEDIATE - Critical)
counter
Expected: ~0Metric: oauth_integrity_violations_totalAlert if: > 5 per 15 minutes (High)
duration
SLO: < 2 secondsMetric: histogram_quantile(0.95, oauth_token_refresh_duration_seconds_bucket)Alert if: > 2s for 5 minutes

Incident Response Playbooks

Severity: Critical - Immediate action requiredIndicators:
  • oauth_refresh_token_reuse_detected event in logs
  • oauth_token_refresh_total{status="reuse_detected"} > 0
Automatic Actions:
  • ✅ All tokens for server immediately revoked
  • ✅ User forced to re-authenticate
  • ✅ Security event logged with full context
Manual Response:
  1. Check logs for serverUuid and userId
  2. Review user’s recent OAuth activity
  3. Check for concurrent requests (race condition vs. attack)
  4. If attack: Block user IP, audit account
  5. If race condition: Review application logs, check for retry logic issues
Loki Query:
Severity: Critical - Immediate action requiredIndicators:
  • oauth_code_injection_attempt event in logs
  • oauth_code_injection_attempts_total > 0
Automatic Actions:
  • ✅ Authorization code rejected
  • ✅ Security event logged with attacker/victim details
Manual Response:
  1. Identify attacker from logs: attackerUserId
  2. Identify victim: victimUserId
  3. Block attacker account immediately
  4. Notify victim user of attempted account compromise
  5. Audit all OAuth flows for both users in last 24h
  6. Check for pattern of attacks (same IP, same target servers)
Loki Query:
Severity: High - Investigate within 1 hourIndicators:
  • oauth_integrity_violation events in logs
  • oauth_integrity_violations_total increasing
Possible Causes:
  • State tampering attempt
  • Database corruption
  • Application bug (HMAC calculation mismatch)
Manual Response:
  1. Check violationType: hash_mismatch, state_reuse, user_mismatch
  2. Review affected serverUuid and userId
  3. If single occurrence: Likely user error or network issue
  4. If multiple from same user: Possible attack or client issue
  5. If widespread: Check for application deployment issues
Loki Query:
Severity: High - Investigate within 1 hourIndicators:
  • OAuth success rate < 95%
  • Increased error rates in dashboards
Possible Causes:
  • OAuth server downtime
  • Network issues
  • Configuration changes
  • High user error rate (expired states, etc.)
Manual Response:
  1. Check recent deployments
  2. Review error distribution by type
  3. Check OAuth server status
  4. Review network connectivity
  5. Check for expired PKCE states (>5 minutes)
PromQL Query:

Sensitive Data Redaction

All sensitive OAuth data is automatically redacted in logs:
Redacted Fields (never logged in plaintext):
  • access_token
  • refresh_token
  • code_verifier
  • client_secret
  • authorization_code
Example redacted log:

Testing OAuth 2.1 Compliance

Test State Integrity

Test Refresh Token Reuse

Test PKCE Expiration


References

RFC 7636

PKCE - Proof Key for Code Exchange

RFC 6749

OAuth 2.0 Authorization Framework

OAuth 2.1 Draft

OAuth 2.1 Specification (Draft)

Security BCP

OAuth 2.0 Security Best Practices

Summary

Plugged.in implements industry-leading OAuth 2.1 security with: 5 Core Security Enhancements beyond OAuth 2.0 ✅ 8 Attack Scenarios prevented ✅ Zero Breaking Changes for existing integrations ✅ Comprehensive Monitoring and alerting ✅ Full RFC Compliance with OAuth 2.1 draft Your MCP server authentication is enterprise-grade secure.