How Pi Web Manages API Keys: Secure Server-Side Storage and Retrieval
Pi Web manages API keys through secure Next.js API routes that store credentials server-side using the Pi SDK's AuthStorage layer, never exposing raw keys to the client while automatically injecting them into outbound provider requests.
The agegr/pi-web repository implements a robust security architecture for handling sensitive provider credentials. Instead of storing API keys in browser storage or environment variables exposed to the frontend, the application leverages AuthStorage from the Pi SDK to persist keys in the user's local ~/.pi/agent directory. This server-side approach ensures that authentication secrets remain inaccessible to client-side JavaScript while remaining available for backend request injection.
Secure Storage with AuthStorage
Pi Web delegates all credential persistence to the Pi SDK's AuthStorage layer. When a user saves an API key, the system writes the encrypted value to the local filesystem at ~/.pi/agent, keeping sensitive data entirely within the server environment. This design prevents accidental exposure through browser dev tools or cross-site scripting vulnerabilities, as raw keys never traverse the network to the frontend.
API Route Implementation for Key Management
The core logic resides in app/api/auth/api-key/[provider]/route.ts, which implements a RESTful interface for credential lifecycle management. This dynamic route handles three distinct operations for each provider ID passed as a parameter.
Retrieving Authentication Status (GET)
The GET method checks for the existence of a stored key without revealing its contents. It returns a status object such as { status: "has-key" } or { status: "missing" }, allowing the frontend to toggle UI states without handling sensitive material. This pattern ensures that even if the API response is intercepted, no secret credentials leak to unauthorized parties.
Storing Provider Credentials (POST)
The POST handler accepts a JSON payload containing { apiKey: string } and writes the value to AuthStorage. Internally, the route examines the provider's prompt configuration to determine whether to store the value as an api-key or bearer-token type, accommodating different authentication schemes across model providers like OpenAI, Google, or Anthropic.
// Save a new API key for a specific provider
await fetch(`/api/auth/api-key/${encodeURIComponent(providerId)}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ apiKey: "YOUR_KEY_HERE" })
});
Revoking Access (DELETE)
The DELETE method permanently removes the stored credential from AuthStorage, effectively revoking the application's access to that provider. This operation is irreversible and requires the user to re-authenticate before subsequent API calls can succeed.
// Delete a stored API key
await fetch(`/api/auth/api-key/${encodeURIComponent(providerId)}`, {
method: "DELETE"
});
Frontend Integration with ModelsConfig
The ModelsConfig component located at components/ModelsConfig.tsx (lines 1359-1384) serves as the primary interface for key management. This React component manages provider configuration UI and communicates with the API routes using standard fetch requests. When users input new credentials or click "Remove," the component dispatches the appropriate POST or DELETE requests to the dynamic routes, then refreshes the authentication status via GET requests to update the UI indicators.
// Check if user has configured a key (returns status, not the key)
const status = await fetch(
`/api/auth/api-key/${encodeURIComponent(providerId)}`
).then(r => r.json());
// Returns: { status: "has-key" } or { status: "missing" }
Automatic Key Injection for Model Discovery
When Pi Web discovers available models from third-party providers, it automatically injects stored credentials into outgoing requests. The route at app/api/models-config/discover/route.ts (lines 23-26) intercepts model discovery calls and checks for missing authentication headers such as x-api-key or x-goog-api-key. If the request lacks these headers, the middleware retrieves the corresponding key from AuthStorage and appends it to the headers before forwarding the request to the provider's API.
This injection mechanism ensures that provider通信 remains authenticated without requiring manual header management in the frontend code, while maintaining zero exposure of secrets to the browser.
Summary
- Server-side storage: API keys persist in the Pi SDK's AuthStorage at
~/.pi/agent, never touching localStorage or cookies. - Status-only retrieval: The GET endpoint at
app/api/auth/api-key/[provider]/route.tsreturns only presence indicators, never raw values. - Dynamic provider support: The POST handler automatically selects between
api-keyandbearer-tokenstorage types based on provider configuration. - Automatic injection: The discovery route at
app/api/models-config/discover/route.tstransparently adds stored keys to outbound provider requests when headers likex-api-keyare missing. - Secure deletion: DELETE requests permanently revoke credentials from AuthStorage without leaving residual data in browser memory.
Frequently Asked Questions
Where are API keys physically stored in Pi Web?
API keys are stored in the Pi SDK's AuthStorage layer, which writes encrypted files to the local ~/.pi/agent directory on the server. This location is inaccessible to browser clients and requires server-side code execution to read or modify, providing a secure vault for sensitive credentials.
Does Pi Web expose API keys to the browser?
No. According to the source code in app/api/auth/api-key/[provider]/route.ts, GET requests return only authentication status strings like "has-key" or "missing". The raw API key values never leave the server environment, ensuring complete isolation from client-side JavaScript and network inspection tools.
How does Pi Web handle different authentication types across providers?
The POST handler in the API key route inspects each provider's prompt configuration to determine the appropriate storage format. It automatically categorizes credentials as either api-key or bearer-token types, allowing the system to support diverse authentication schemes (API keys, JWT tokens, or OAuth bearer tokens) within a unified storage interface.
What happens when a user deletes an API key in the UI?
When triggered from the ModelsConfig component, a DELETE request to /api/auth/api-key/[provider] invokes AuthStorage to remove the credential from the ~/.pi/agent directory. This immediately revokes the application's access to that provider, and subsequent model discovery attempts will fail authentication until a new key is configured.
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 →