How Authentication Credentials Are Stored and Secured in the System Keychain in Auth0 MCP Server
The Auth0 MCP server stores all sensitive credentials in the operating system’s native secure credential store using the keytar library, with a singleton KeychainService abstracting access to tokens, domains, and refresh tokens under the service name auth0-mcp.
The Auth0 MCP server manages sensitive authentication data including access tokens, refresh tokens, and tenant configuration that must remain encrypted at rest. Rather than persisting these secrets to environment variables or unencrypted files, the system delegates storage to the OS-native keychain. This architecture ensures that authentication credentials stored and secured in the system keychain benefit from hardware-backed encryption and strict user-account isolation provided by the underlying operating system.
KeychainService Architecture in src/utils/keychain.ts
All credential operations are centralized in src/utils/keychain.ts, which implements a dedicated KeychainService class to wrap the keytar library.
Singleton Pattern and Service Configuration
The module exports a singleton instance instantiated with the constant service name auth0-mcp. This guarantees that every read and write operation targets the same secure namespace within the system keychain.
// src/utils/keychain.ts (lines 7-8)
export const keychain = new KeychainService(KEYCHAIN_SERVICE_NAME);
Using a singleton prevents credential leakage through multiple service instances and ensures consistent error handling across the application.
Supported Credential Types and Storage Keys
The service manages four distinct sensitive items mapped to specific keychain identifiers:
- Access token: Stored under the key
AUTH0_TOKENviasetToken()and retrieved viagetToken() - Tenant domain: Stored under
AUTH0_DOMAINviasetDomain()andgetDomain() - Refresh token: Stored under
AUTH0_REFRESH_TOKENviasetRefreshToken()andgetRefreshToken() - Expiration timestamp: Stored as a string under
AUTH0_TOKEN_EXPIRES_ATviasetTokenExpiresAt()and parsed back to a number viagetTokenExpiresAt()
Each getter and setter delegates to private set and get helpers that perform the actual keychain I/O.
Storing and Retrieving Credentials Securely
The KeychainService delegates all cryptographic storage operations to keytar, which binds to the native OS credential APIs. The private set method stores values using keytar.setPassword, while the private get method retrieves them using keytar.getPassword.
// Storage operation (conceptual implementation from src/utils/keychain.ts)
await keytar.setPassword(this.serviceName, key, value); // Encrypt and store
await keytar.getPassword(this.serviceName, key); // Decrypt and retrieve
All operations are asynchronous and return promises. The service implements defensive error handling (lines 76-84 for writes, lines 176-184 for reads) that catches exceptions, logs them via the internal logger, and returns a boolean success flag rather than crashing the process.
Practical Usage Examples
The following patterns demonstrate how the application interacts with the secure store:
import { keychain } from './utils/keychain.js';
// Store a new access token after authentication
await keychain.setToken('eyJhbGciOiJIUzI1NiIsInR5cCI6...');
// Retrieve the stored token for API calls
const token = await keychain.getToken();
if (token) {
// Use token to call Auth0 Management API
}
// Persist tenant configuration
await keychain.setDomain('my-tenant.auth0.com');
// Store refresh token and expiration metadata
await keychain.setRefreshToken('r1.2a3b4c5d...');
await keychain.setTokenExpiresAt(Date.now() + 3600 * 1000);
Secure Cleanup and Session Management
The service provides a clearAll() method (lines 124-149) that iterates over every defined keychain item (ALL_KEYCHAIN_ITEMS) and attempts deletion. This is critical for logout operations or credential rotation scenarios.
// Clear all credentials (e.g., on logout)
const results = await keychain.clearAll();
results.forEach(r => console.log(`${r.item}: ${r.success ? 'deleted' : 'error'}`));
The method returns a detailed report indicating success or failure for each item, allowing the application to handle partial cleanup gracefully.
OS-Level Security Guarantees
Because keytar interfaces directly with the host operating system, credentials receive platform-specific encryption:
- macOS: Credentials are stored in the Keychain, encrypted using the user’s login keychain keys.
- Windows: Credentials are stored in the Windows Credential Vault, encrypted with the user’s account credentials.
- Linux: Credentials are stored via libsecret, typically backed by the GNOME Keyring or KDE Wallet.
This architecture ensures that secrets are inaccessible to other user accounts and are encrypted at rest using the OS’s native cryptographic facilities. The auth0-mcp service name acts as a namespace that isolates these credentials from other applications sharing the system keychain.
Summary
- The
KeychainServiceinsrc/utils/keychain.tsprovides a singleton interface for all credential storage operations. - Four sensitive items (access token, domain, refresh token, expiration) are stored under the service name
auth0-mcpusing thekeytarlibrary. - All read and write operations use native OS APIs (Keychain, Credential Vault, or libsecret), ensuring encryption at rest and user-account isolation.
- Error handling returns boolean success flags and logs failures without exposing stack traces to the UI.
- The
clearAll()method enables secure cleanup of all stored credentials during logout or reset operations.
Frequently Asked Questions
What library does the Auth0 MCP server use for system keychain storage?
The server uses the keytar library, a Node.js native module that binds to the operating system’s secure credential store. According to the package.json and source implementation in src/utils/keychain.ts, keytar provides the underlying setPassword, getPassword, and deletePassword functions that encrypt and decrypt credentials using OS-native mechanisms.
Where are the credentials physically stored on disk?
Credentials are not stored in application files. Instead, keytar delegates to the OS-native store: the Keychain on macOS, the Credential Vault on Windows, and the libsecret service (GNOME Keyring/KDE Wallet) on Linux. These locations are managed by the operating system and are only accessible to the current user account, providing hardware-backed encryption and access controls.
How does the application handle failures when accessing the keychain?
If a keychain operation fails—whether due to user denial, locked keychain, or system errors—the KeychainService catches the exception (lines 76-84 for writes, lines 176-184 for reads), logs the error via the internal logger, and returns false or null rather than throwing. This prevents the MCP server from crashing and allows the calling code to fallback to unauthenticated states or retry logic.
How can I programmatically clear all stored Auth0 credentials?
Invoke the clearAll() method on the keychain singleton. This method iterates over ALL_KEYCHAIN_ITEMS, attempts to delete each entry using keytar.deletePassword, and returns an array of results indicating which items were successfully removed. This is the recommended approach for implementing logout or "forget credentials" functionality in CLI tools or integrations using this server.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →