@@ -80,7 +80,7 @@ URL paths encode evaluation metadata that gets injected as Langfuse tags:
80803 . ** Retry logic** : Automatic retries with exponential backoff for incomplete traces
8181
8282### Multi-Project Support
83- - Store Langfuse credentials for multiple projects in ` secrets.json `
83+ - Store Langfuse credentials for multiple projects in ` secrets.yaml `
8484- Route requests to the correct project via ` project_id ` in URL or use default
8585- Credentials never exposed to clients
8686
@@ -94,21 +94,17 @@ URL paths encode evaluation metadata that gets injected as Langfuse tags:
9494
95951 . ** Create secrets file:**
9696 ``` bash
97- cp proxy_core/secrets.json .example proxy_core/secrets.json
97+ cp proxy_core/secrets.yaml .example proxy_core/secrets.yaml
9898 ```
9999
100- 2 . ** Edit ` proxy_core/secrets.json ` ** with your Langfuse credentials.
101- ** Important** : where we have "my-project", you would use the ID of your Langfuse project, similar to format ` cmg00asdf0123... ` .
102- ``` json
103- {
104- "langfuse_keys" : {
105- "my-project" : {
106- "public_key" : " pk-lf-..." ,
107- "secret_key" : " sk-lf-..."
108- }
109- },
110- "default_project_id" : " my-project"
111- }
100+ 2 . ** Edit ` proxy_core/secrets.yaml ` ** with your Langfuse credentials.
101+ ** Important** : use your real Langfuse project ID (e.g. ` cmg00asdf0123... ` ).
102+ ``` yaml
103+ langfuse_keys :
104+ my-project :
105+ public_key : pk-lf-...
106+ secret_key : sk-lf-...
107+ default_project_id : my-project
112108 ` ` `
113109
1141103. **Start services:**
@@ -238,31 +234,27 @@ Forwards any other request to LiteLLM backend with API key injection.
238234| ` REDIS_HOST ` | Yes | - | Redis hostname |
239235| ` REDIS_PORT ` | No | 6379 | Redis port |
240236| ` REDIS_PASSWORD ` | No | - | Redis password |
241- | ` SECRETS_PATH ` | No | ` proxy_core/secrets.json ` | Path to secrets file |
242- | ` REQUEST_TIMEOUT ` | No | 300.0 | Request timeout in seconds |
237+ | ` SECRETS_PATH ` | No | ` proxy_core/secrets.yaml ` | Path to secrets file (YAML) |
238+ | ` LANGFUSE_HOST ` | No | ` https://cloud.langfuse.com ` | Langfuse base URL |
239+ | ` REQUEST_TIMEOUT ` | No | 300.0 | Request timeout (LLM calls) in seconds |
243240| ` LOG_LEVEL ` | No | INFO | Logging level |
244241| ` PORT ` | No | 4000 | Gateway port |
245242
246243### Secrets Configuration
247244
248- Create ` proxy_core/secrets.json ` :
249- ``` json
250- {
251- "langfuse_keys" : {
252- "project-1" : {
253- "public_key" : " pk-lf-..." ,
254- "secret_key" : " sk-lf-..."
255- },
256- "project-2" : {
257- "public_key" : " pk-lf-..." ,
258- "secret_key" : " sk-lf-..."
259- }
260- },
261- "default_project_id" : " project-1"
262- }
245+ Create ` proxy_core/secrets.yaml ` :
246+ ``` yaml
247+ langfuse_keys :
248+ project-1 :
249+ public_key : pk-lf-...
250+ secret_key : sk-lf-...
251+ project-2 :
252+ public_key : pk-lf-...
253+ secret_key : sk-lf-...
254+ default_project_id : project-1
263255` ` `
264256
265- ** Security:** Add ` secrets.json ` to ` .gitignore ` (already configured) .
257+ **Security:** ` secrets.yaml` is ignored via `.gitignore`.
266258
267259# ## LiteLLM Configuration
268260
@@ -332,7 +324,7 @@ eval_protocol/proxy/
332324│ ├── models.py # Pydantic models
333325│ ├── auth.py # Authentication
334326│ ├── main.py # Entry point
335- │ └── secrets.json .example
327+ │ └── secrets.yaml .example
336328├── docker-compose.yml # Local development stack
337329├── Dockerfile.gateway # Gateway container
338330├── config_no_cache.yaml # LiteLLM config
@@ -345,17 +337,17 @@ eval_protocol/proxy/
345337Extend `AuthProvider` in `auth.py`:
346338```python
347339from .auth import AuthProvider
348- from fastapi import HTTPException
340+ from fastapi import HTTPException, Request
349341
350342class MyAuthProvider(AuthProvider):
351- def validate(self, api_key: Optional[str]) -> Optional[str]:
352- if not api_key or not self.is_valid(api_key):
343+ def validate(self, request: Request) -> Optional[str]:
344+ api_key = None
345+ auth_header = request.headers.get("authorization", "")
346+ if auth_header.startswith("Bearer "):
347+ api_key = auth_header.replace("Bearer ", "").strip()
348+ if not api_key:
353349 raise HTTPException(status_code=401, detail="Invalid API key")
354350 return api_key
355-
356- def is_valid(self, api_key: str) -> bool:
357- # Your validation logic
358- return True
359351```
360352
361353Then pass it to ` create_app ` :
0 commit comments