@fastmcp-oauth/kerberos-delegation
v1.0.0
Published
Kerberos delegation module for FastMCP OAuth framework - Windows Kerberos Constrained Delegation support
Maintainers
Readme
@fastmcp-oauth/kerberos-delegation
Kerberos delegation module for the MCP OAuth framework - provides Windows Kerberos Constrained Delegation support.
Overview
This package is a reference implementation demonstrating how to build delegation modules for the MCP OAuth framework. It provides Kerberos-based authentication and delegation using:
- S4U2Self: Service for User to Self (obtain ticket on behalf of user)
- S4U2Proxy: Service for User to Proxy (delegate to backend services)
Installation
npm install @fastmcp-oauth/kerberos-delegationThis package is an optional dependency of fastmcp-oauth. The core framework works without Kerberos support.
Platform Requirements
Windows (Domain-Joined)
- Windows Server with Active Directory
- Node.js 18.0.0 or higher
- Kerberos configured service account with delegation rights
- Uses Windows SSPI (Security Support Provider Interface)
Linux
- Node.js 18.0.0 or higher
- MIT Kerberos (
krb5-userpackage) - Keytab file for service account
- Network access to Active Directory KDC
Windows (Non-Domain-Joined)
See Non-Domain-Joined Windows Setup below
Features
Security
- ✅ Windows SSPI integration via node-kerberos
- ✅ Kerberos Constrained Delegation (S4U2Self/S4U2Proxy)
- ✅ Ticket caching for performance
- ✅ Automatic ticket renewal
- ✅ Audit logging for all delegation operations
Kerberos Operations
- S4U2Self: Obtain Kerberos ticket on behalf of user
- S4U2Proxy: Act on behalf of user to backend services
- Ticket Cache: Cache Kerberos tickets with TTL
Usage
Basic Kerberos Delegation
import { KerberosDelegationModule } from '@fastmcp-oauth/kerberos-delegation';
import { DelegationRegistry } from 'fastmcp-oauth/delegation';
const kerberosModule = new KerberosDelegationModule();
await kerberosModule.initialize({
servicePrincipalName: 'HTTP/mcp-server.company.com',
realm: 'COMPANY.COM',
kdcServer: 'dc01.company.com',
ticketCache: {
enabled: true,
ttlSeconds: 3600,
maxEntries: 1000
}
});
// Register with framework
const registry = new DelegationRegistry();
registry.register(kerberosModule);
// Perform S4U2Self delegation
const result = await registry.delegate(
'kerberos',
session,
's4u2self',
{
action: 's4u2self',
userPrincipalName: '[email protected]'
}
);S4U2Proxy Delegation
// Delegate to backend service
const result = await registry.delegate(
'kerberos',
session,
's4u2proxy',
{
action: 's4u2proxy',
userPrincipalName: '[email protected]',
targetService: 'HTTP/backend.company.com'
}
);API
KerberosDelegationModule
Actions
s4u2self- Obtain Kerberos ticket on behalf of user{ action: 's4u2self', userPrincipalName: '[email protected]' }s4u2proxy- Act on behalf of user to backend service{ action: 's4u2proxy', userPrincipalName: '[email protected]', targetService: 'HTTP/backend.company.com' }ticket-cache-stats- Get ticket cache statistics{ action: 'ticket-cache-stats' }
Configuration
Kerberos Configuration
{
servicePrincipalName: string; // SPN of MCP server
realm: string; // Kerberos realm (e.g., COMPANY.COM)
kdcServer: string; // Key Distribution Center hostname
ticketCache?: {
enabled: boolean; // Enable ticket caching
ttlSeconds: number; // Ticket TTL (default: 3600)
maxEntries: number; // Max cached tickets (default: 1000)
};
}Active Directory Setup
Service Account Configuration
Create service account for MCP server:
New-ADUser -Name "mcp-service" -UserPrincipalName "[email protected]"Set Service Principal Name (SPN):
setspn -A HTTP/mcp-server.company.com COMPANY\mcp-serviceEnable delegation rights:
# Enable constrained delegation Set-ADUser -Identity "mcp-service" -Add @{'msDS-AllowedToDelegateTo'=@('HTTP/backend.company.com')}Enable protocol transition (for S4U2Self):
Set-ADAccountControl -Identity "mcp-service" -TrustedToAuthForDelegation $true
Security Considerations
Delegation Rights
Kerberos Constrained Delegation requires:
- Service account with
TrustedToAuthForDelegationflag - Specific services listed in
msDS-AllowedToDelegateToattribute - Active Directory domain functional level 2003+
Ticket Security
- Tickets are cached in memory only (not persisted to disk)
- Ticket cache supports automatic expiration and renewal
- All delegation operations are audit logged
Platform-Specific Configuration
Linux Setup with Keytab
On Linux, the recommended approach is to use a keytab file for authentication:
1. Generate Keytab on Active Directory
# On Windows AD Domain Controller
ktpass -princ HTTP/[email protected] -mapuser svc-mcp-server `
-pass YourSecurePassword123! -out mcp-server.keytab `
-ptype KRB5_NT_PRINCIPAL2. Copy Keytab to Linux Server
# Copy keytab to Linux server
scp mcp-server.keytab linux-server:/etc/keytabs/
chmod 600 /etc/keytabs/mcp-server.keytab
chown node-app-user:node-app-user /etc/keytabs/mcp-server.keytab3. Install MIT Kerberos
# Ubuntu/Debian
sudo apt-get install krb5-user
# RHEL/CentOS
sudo yum install krb5-workstation4. Configure Kerberos (/etc/krb5.conf)
[libdefaults]
default_realm = COMPANY.COM
dns_lookup_kdc = true
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
COMPANY.COM = {
kdc = dc01.company.com:88
admin_server = dc01.company.com:749
default_domain = company.com
}
[domain_realm]
.company.com = COMPANY.COM
company.com = COMPANY.COM5. Update Configuration to Use Keytab
{
"delegation": {
"modules": {
"kerberos": {
"enabled": true,
"domainController": "dc01.company.com",
"servicePrincipalName": "HTTP/mcp-server",
"realm": "COMPANY.COM",
"kdc": "dc01.company.com:88",
"serviceAccount": {
"username": "svc-mcp-server",
"keytabPath": "/etc/keytabs/mcp-server.keytab"
}
}
}
}
}6. Test Keytab
# Obtain ticket using keytab
kinit -kt /etc/keytabs/mcp-server.keytab [email protected]
# Verify ticket
klist
# Expected output:
# Ticket cache: FILE:/tmp/krb5cc_1000
# Default principal: [email protected]Non-Domain-Joined Windows Setup
For non-domain-joined Windows machines, you have several options:
Option 1: MIT Kerberos for Windows (Recommended)
Install MIT Kerberos for Windows to get the same capabilities as Linux:
Step 1: Install MIT Kerberos
# Download from: https://web.mit.edu/kerberos/dist/
# Or use Chocolatey:
choco install kerberos-for-windowsStep 2: Configure Kerberos (C:\ProgramData\MIT\Kerberos5\krb5.ini)
[libdefaults]
default_realm = COMPANY.COM
dns_lookup_kdc = true
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
COMPANY.COM = {
kdc = dc01.company.com:88
admin_server = dc01.company.com:749
default_domain = company.com
}
[domain_realm]
.company.com = COMPANY.COM
company.com = COMPANY.COMStep 3: Obtain Kerberos Ticket
# Using password
kinit [email protected]
# Or using keytab (recommended)
kinit -kt C:\keytabs\mcp-server.keytab [email protected]
# Verify ticket
klistStep 4: Run MCP Server
The kerberos npm package will automatically detect MIT Kerberos and use it instead of SSPI.
Option 2: Windows Credential Manager (SSPI)
Cache credentials using Windows built-in tools:
# Add credentials to Windows Credential Manager
cmdkey /generic:TERMSRV/dc01.company.com /user:COMPANY\svc-mcp-server /pass:YourPassword123!
# Verify
cmdkey /list
# Start a new session with domain credentials
runas /netonly /user:COMPANY\svc-mcp-server "powershell.exe"
# In the new PowerShell window, run the server
cd "C:\path\to\mcp-oauth"
npm startOption 3: ksetup Configuration
Configure the non-domain-joined machine to trust the domain:
# Run as Administrator
ksetup /setdomain COMPANY.COM
ksetup /addkdc COMPANY.COM dc01.company.com
# Map realm to domain
ksetup /addhosttorealmmap dc01.company.com COMPANY.COM
# Reboot required
shutdown /r /t 0After reboot, use runas /netonly as shown in Option 2.
Option 4: WSL2 with MIT Kerberos
Run the MCP server in WSL2 (Ubuntu) where MIT Kerberos works natively:
# In WSL2 Ubuntu
sudo apt-get install krb5-user
# Configure /etc/krb5.conf (same as Linux setup above)
sudo nano /etc/krb5.conf
# Use keytab
kinit -kt /etc/keytabs/mcp-server.keytab [email protected]
# Run server
npm startPlatform Comparison
| Feature | Windows (Domain-Joined) | Linux | Windows (Non-Domain) |
|---------|------------------------|-------|---------------------|
| Kerberos Library | Windows SSPI | MIT Kerberos | MIT Kerberos (recommended) |
| Password Auth | ❌ Not supported | ✅ Supported | ✅ With MIT Kerberos |
| Keytab Auth | ❌ Not supported by SSPI | ✅ Recommended | ✅ With MIT Kerberos |
| Current User Credentials | ✅ Default | ⚠️ Requires kinit | ⚠️ Requires kinit |
| Setup Complexity | Low (automatic) | Medium (keytab setup) | High (MIT Kerberos install) |
| Production Ready | ✅ Yes | ✅ Yes | ⚠️ Yes (with MIT Kerberos) |
Troubleshooting
Common Issues
Issue: "Kerberos client initialization failed"
- Verify service account has SPN configured
- Check KDC server is reachable
- Ensure Windows SSPI is available (or MIT Kerberos on Linux)
Issue: "No credentials are available in the security package" (Windows SSPI)
- Cause: Windows SSPI doesn't support password authentication; it requires cached credentials
- Solution 1: Install MIT Kerberos for Windows (see Option 1)
- Solution 2: Run server with
runas /netonly(see Option 2) - Solution 3: Use domain-joined machine where credentials are automatically cached
Issue: "S4U2Self failed: KDC_ERR_BADOPTION"
- Service account missing
TrustedToAuthForDelegationflag - Protocol transition not enabled in AD
Issue: "S4U2Proxy failed: KDC_ERR_BADOPTION"
- Target service not in
msDS-AllowedToDelegateTolist - Constrained delegation not configured
Issue: "Keytab contains no suitable keys" (Linux)
- Keytab file doesn't match the service principal name
- Regenerate keytab with correct SPN using
ktpass
Debug Mode
Enable debug logging:
const kerberosModule = new KerberosDelegationModule();
kerberosModule.setDebugMode(true);License
MIT
