Skip to content

Commit 3ecf15c

Browse files
committed
init untested
1 parent 1fdedf4 commit 3ecf15c

File tree

9 files changed

+906
-7
lines changed

9 files changed

+906
-7
lines changed

.env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
VERCEL_OIDC_TOKEN="create with vercel cli"
1+
# Enable bun.secrets for secure credential storage (1=enabled, 0=disabled)
2+
# When enabled, secrets are stored in the OS credential manager instead of .env
3+
USE_BUN_SECRETS=1
4+
5+
VERCEL_OIDC_TOKEN="create with vercel cli"

AGENTS.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,51 @@ bun run generate-report.ts results/result-2024-12-07-14-30-45.json
2222

2323
# Run TypeScript type checking
2424
bun tsc --noEmit
25+
26+
# Manage secrets (bun.secrets integration)
27+
bun run secrets
28+
29+
# Test secrets integration
30+
bun run test:secrets
31+
```
32+
33+
## Environment Variables & Secrets Management
34+
35+
This project supports both traditional environment variables and bun.secrets for secure credential storage. See [docs/secrets.md](./docs/secrets.md) for complete bun.secrets documentation.
36+
37+
### bun.secrets Integration
38+
39+
Enable secure credential storage using your operating system's native credential manager:
40+
41+
```bash
42+
# Enable bun.secrets (recommended for development)
43+
export USE_BUN_SECRETS=1
44+
45+
# Initialize secrets from existing environment variables
46+
bun run secrets init
47+
48+
# Manage secrets interactively
49+
bun run secrets
2550
```
2651

27-
## Environment Variables
52+
**Benefits:**
53+
- ✅ Encrypted storage using OS credential manager
54+
- ✅ No plain text API keys in .env files
55+
- ✅ Survives application restarts
56+
- ✅ User-level access control
57+
58+
**Quick Setup:**
59+
```bash
60+
# 1. Enable bun.secrets
61+
export USE_BUN_SECRETS=1
62+
63+
# 2. Set your API keys
64+
bun run secrets set
65+
# Select "ANTHROPIC_API_KEY" and enter your key
66+
67+
# 3. Verify setup
68+
bun run secrets status
69+
```
2870

2971
### MODEL Configuration
3072

@@ -106,11 +148,27 @@ MCP_SERVER_URL=
106148

107149
### Required API Keys
108150

109-
- `ANTHROPIC_API_KEY`: Required when using `anthropic/*` models
151+
The following API keys are required for different model providers. These can be stored as environment variables or using bun.secrets:
152+
153+
- `ANTHROPIC_API_KEY`: Required when using `anthropic/*` models (get at https://console.anthropic.com/)
110154
- `OPENAI_API_KEY`: Required when using `openai/*` models (get at https://platform.openai.com/api-keys)
111155
- `OPENROUTER_API_KEY`: Required when using `openrouter/*` models (get at https://openrouter.ai/keys)
156+
- `VERCEL_OIDC_TOKEN`: Optional for Vercel integration (create with `vercel link`)
112157
- No API key required for `lmstudio/*` models (runs locally)
113158

159+
**With bun.secrets:**
160+
```bash
161+
export USE_BUN_SECRETS=1
162+
bun run secrets set # Select which keys to configure
163+
```
164+
165+
**With environment variables:**
166+
```bash
167+
export ANTHROPIC_API_KEY="your-key-here"
168+
export OPENAI_API_KEY="your-key-here"
169+
export OPENROUTER_API_KEY="your-key-here"
170+
```
171+
114172
### Provider Routing
115173

116174
The benchmark tool automatically routes to the correct provider based on the `MODEL` prefix:

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,44 @@ To install dependencies:
1010
bun install
1111
```
1212

13-
## Setup
13+
## bun.secrets Integration
14+
15+
This project includes secure credential storage using bun.secrets. Store API keys in your OS credential manager instead of plain text .env files.
16+
17+
### Quick Start
18+
19+
```bash
20+
# 1. Enable bun.secrets
21+
export USE_BUN_SECRETS=1
22+
23+
# 2. Initialize from existing .env (optional)
24+
bun run secrets init
25+
26+
# 3. Set your API keys
27+
bun run secrets set
28+
29+
# 4. Run the benchmark
30+
bun run index.ts
31+
```
32+
33+
### Commands
34+
35+
- `bun run secrets` - Interactive secrets management
36+
- `bun run secrets status` - Show current status
37+
- `bun run secrets set` - Set a secret value
38+
- `bun run secrets init` - Initialize from environment variables
39+
- `bun run test:secrets` - Test the integration
40+
41+
### Supported Secrets
42+
43+
- `VERCEL_OIDC_TOKEN` - Vercel authentication
44+
- `ANTHROPIC_API_KEY` - Anthropic Claude API
45+
- `OPENAI_API_KEY` - OpenAI API
46+
- `OPENROUTER_API_KEY` - OpenRouter API
47+
48+
See [docs/secrets.md](./docs/secrets.md) for complete documentation.
49+
50+
---
1451

1552
Configure your API keys in `.env`:
1653

docs/secrets.md

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# bun.secrets Integration
2+
3+
This project includes a modular `bun.secrets` integration for secure credential storage and management. This allows you to store API keys and other sensitive data in your operating system's native credential manager instead of plain text `.env` files.
4+
5+
## Quick Start
6+
7+
1. **Enable bun.secrets:**
8+
```bash
9+
export USE_BUN_SECRETS=1
10+
```
11+
12+
2. **Initialize your secrets from existing environment variables:**
13+
```bash
14+
bun run secrets init
15+
```
16+
17+
3. **Manage secrets interactively:**
18+
```bash
19+
bun run secrets
20+
```
21+
22+
## Available Commands
23+
24+
### `bun run secrets`
25+
Interactive CLI for managing secrets:
26+
- 📊 Show status
27+
- 📋 List all secrets
28+
- 🔐 Set a secret
29+
- 🔍 Get a secret
30+
- 🗑️ Delete a secret
31+
- 🚀 Initialize from environment
32+
33+
### `bun run secrets <action>`
34+
Direct command execution:
35+
```bash
36+
bun run secrets status # Show current status
37+
bun run secrets list # List all configured secrets
38+
bun run secrets set # Set a secret value
39+
bun run secrets get # Retrieve a secret value
40+
bun run secrets delete # Delete a secret
41+
bun run secrets init # Initialize from environment variables
42+
```
43+
44+
### `bun run test:secrets`
45+
Test the secrets integration and verify functionality.
46+
47+
## Environment Variables
48+
49+
### USE_BUN_SECRETS
50+
- `0` or `false`: Use traditional environment variables (default)
51+
- `1` or `true`: Use bun.secrets for credential storage
52+
53+
When enabled, the application will:
54+
1. First try to retrieve secrets from bun.secrets
55+
2. Fall back to environment variables if not found
56+
3. Store new secrets using bun.secrets
57+
58+
### Supported Secrets
59+
60+
The system supports these secrets by default:
61+
62+
| Secret Key | Description | Environment Variable |
63+
|------------|-------------|---------------------|
64+
| `VERCEL_OIDC_TOKEN` | Vercel OIDC authentication token | `VERCEL_OIDC_TOKEN` |
65+
| `ANTHROPIC_API_KEY` | Anthropic Claude API key | `ANTHROPIC_API_KEY` |
66+
| `OPENAI_API_KEY` | OpenAI API key | `OPENAI_API_KEY` |
67+
| `OPENROUTER_API_KEY` | OpenRouter API key | `OPENROUTER_API_KEY` |
68+
69+
## Platform-Specific Storage
70+
71+
- **macOS**: Keychain Services
72+
- **Linux**: libsecret (GNOME Keyring, KWallet, etc.)
73+
- **Windows**: Windows Credential Manager
74+
75+
## Usage Examples
76+
77+
### Setting Secrets
78+
79+
```bash
80+
# Enable bun.secrets
81+
export USE_BUN_SECRETS=1
82+
83+
# Set API key interactively
84+
bun run secrets set
85+
# Select "ANTHROPIC_API_KEY" from the menu
86+
# Enter your key when prompted
87+
```
88+
89+
### Migrating from .env Files
90+
91+
```bash
92+
# With your .env file in place and USE_BUN_SECRETS=1
93+
bun run secrets init
94+
# This will copy all environment variables into bun.secrets
95+
```
96+
97+
### Programmatic Usage
98+
99+
```typescript
100+
import { getSecret, setSecret, isBunSecretsEnabled } from "./lib/secrets.ts";
101+
102+
// Check if bun.secrets is enabled
103+
if (isBunSecretsEnabled()) {
104+
// Get a secret
105+
const apiKey = await getSecret("ANTHROPIC_API_KEY");
106+
107+
// Set a secret
108+
await setSecret("CUSTOM_SECRET", "super-secret-value");
109+
}
110+
```
111+
112+
## Security Considerations
113+
114+
- ✅ Credentials are encrypted by the operating system
115+
- ✅ Access is restricted to the user who stored them
116+
- ✅ No plain text storage of sensitive data
117+
- ✅ Memory is zeroed after use
118+
- ✅ Survives application restarts
119+
120+
## Migration from Environment Variables
121+
122+
1. **Enable bun.secrets:**
123+
```bash
124+
export USE_BUN_SECRETS=1
125+
```
126+
127+
2. **Initialize from current environment:**
128+
```bash
129+
bun run secrets init
130+
```
131+
132+
3. **Verify migration:**
133+
```bash
134+
bun run secrets list
135+
```
136+
137+
4. **Optional:** Remove sensitive values from .env files
138+
139+
## Custom Secret Definitions
140+
141+
The system is modular and can be extended with custom secrets:
142+
143+
```typescript
144+
import { DEFAULT_SECRETS, type SecretDefinition } from "./lib/secrets.ts";
145+
146+
const customSecrets: SecretDefinition = {
147+
...DEFAULT_SECRETS,
148+
MY_CUSTOM_API_KEY: {
149+
service: "my-app",
150+
name: "custom-api-key",
151+
envVar: "MY_CUSTOM_API_KEY",
152+
},
153+
};
154+
155+
// Use custom secrets
156+
await setSecret("MY_CUSTOM_API_KEY", "my-secret-value", customSecrets);
157+
```
158+
159+
## Troubleshooting
160+
161+
### "bun.secrets is not enabled"
162+
Set `USE_BUN_SECRETS=1` in your environment.
163+
164+
### "Failed to retrieve secret"
165+
- Check that the secret exists: `bun run secrets list`
166+
- Verify the secret name in the configuration
167+
- Check OS-specific permissions for credential storage
168+
169+
### Linux: "Secret service daemon not running"
170+
Install and start a secret service:
171+
```bash
172+
# Ubuntu/Debian
173+
sudo apt-get install libsecret-1-0
174+
# GNOME Keyring should start automatically
175+
176+
# Or for systems without GUI
177+
sudo apt-get install gnome-keyring
178+
eval $(gnome-keyring-daemon --start)
179+
```
180+
181+
### Windows: Credential Manager access denied
182+
Ensure you're running with appropriate permissions to access Windows Credential Manager.
183+
184+
## Best Practices
185+
186+
1. **Enable bun.secrets in development** for better security
187+
2. **Use environment variables in CI/CD** (bun.secrets is not for production secrets)
188+
3. **Initialize secrets** when switching between bun.secrets and environment variables
189+
4. **Regularly check status** with `bun run secrets status`
190+
5. **Remove old .env values** after successful migration to avoid confusion

index.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import {
3131
type ModelPricing,
3232
type ModelPricingLookup,
3333
} from "./lib/pricing.ts";
34+
import { createModel, validateModelSecrets } from "./lib/gateway.ts";
35+
import { isBunSecretsEnabled } from "./lib/secrets.ts";
3436
import type { LanguageModel } from "ai";
3537
import {
3638
intro,
@@ -161,6 +163,11 @@ async function validateAndConfirmPricing(
161163
async function selectOptions(): Promise<SelectOptionsResult> {
162164
intro("🚀 Svelte AI Bench");
163165

166+
// Show secrets status
167+
const secretsEnabled = isBunSecretsEnabled();
168+
const secretsStatus = secretsEnabled ? "🔐 bun.secrets enabled" : "🌐 Environment variables";
169+
note(secretsStatus, "Authentication Method");
170+
164171
const available_models = await gateway.getAvailableModels();
165172

166173
const models = await multiselect({
@@ -196,6 +203,31 @@ async function selectOptions(): Promise<SelectOptionsResult> {
196203

197204
const selectedModels = models.filter((model) => model !== "custom");
198205

206+
// Validate that we have the required secrets for the selected models
207+
const validation = await validateModelSecrets(selectedModels);
208+
if (!validation.valid) {
209+
const errorMessage = [
210+
"Missing required API keys:",
211+
...validation.missing.map(missing => ` • ${missing}`),
212+
"",
213+
secretsEnabled
214+
? "Run 'bun run secrets' to configure your secrets."
215+
: "Set the required environment variables or enable bun.secrets.",
216+
].join("\n");
217+
218+
note(errorMessage, "❌ Authentication Error");
219+
220+
const proceed = await confirm({
221+
message: "Continue anyway? Some models may fail.",
222+
initialValue: false,
223+
});
224+
225+
if (isCancel(proceed) || !proceed) {
226+
cancel("Operation cancelled.");
227+
process.exit(0);
228+
}
229+
}
230+
199231
// Validate pricing for selected models
200232
const pricing = await validateAndConfirmPricing(selectedModels);
201233

@@ -608,8 +640,8 @@ async function main() {
608640
);
609641
}
610642

611-
// Get the model from gateway
612-
const model = gateway.languageModel(modelId);
643+
// Get the model with secret integration
644+
const model = await createModel(modelId);
613645

614646
// Run all tests
615647
const testResults: SingleTestResult[] = [];

0 commit comments

Comments
 (0)