Configuration
Triks often need access to API keys, tokens, and other secrets. TrikHub provides a secure, isolated configuration system where each Trik can only access its own credentials.
The Problem
Without configuration isolation:
- A malicious trik could access another trik’s API keys
- Users would need to manage environment variables manually
- No validation of required credentials before execution
With TrikHub’s configuration system, each Trik declares what it needs, and users configure secrets once in a central location.
How Configuration Works
1. Declare Requirements in Manifest
Triks declare their configuration needs in manifest.json:
{
"config": {
"required": [
{ "key": "API_KEY", "description": "Your OpenAI API key" },
{ "key": "BASE_URL", "description": "API base URL" }
],
"optional": [
{ "key": "MODEL", "description": "Model name", "default": "gpt-4" }
]
}
}| Field | Description |
|---|---|
required | Gateway warns on load if these are missing; trik may fail at runtime |
optional | Trik works without these; can have defaults |
2. User Configuration
Users store secrets in JSON files, organized by trik ID:
Global configuration: ~/.trikhub/secrets.json
Applies to all projects on your machine:
{
"@molefas/gpt-trik": {
"API_KEY": "sk-...",
"BASE_URL": "https://api.openai.com/v1"
},
"@yourname/another-trik": {
"TOKEN": "abc123"
}
}Local configuration: .trikhub/secrets.json
Project-specific overrides (takes precedence over global):
{
"@molefas/gpt-trik": {
"API_KEY": "sk-different-key-for-this-project"
}
}3. Access via TrikContext
The gateway passes a TrikConfigContext to your trik through TrikContext.config. How you access it depends on your trik’s mode.
Conversational Mode
In a conversational trik, config is typically used in the agent factory to set up the LLM and tools:
import { wrapAgent } from '@trikhub/sdk';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { ChatOpenAI } from '@langchain/openai';
import { transferBackTool } from '@trikhub/sdk';
export default wrapAgent(async (context) => {
// Access config in the factory — runs once at initialization
const apiKey = context.config.get('API_KEY');
const baseUrl = context.config.get('BASE_URL');
const model = context.config.get('MODEL') ?? 'gpt-4';
if (!context.config.has('API_KEY')) {
throw new Error('API_KEY is required');
}
const llm = new ChatOpenAI({
apiKey,
configuration: { baseURL: baseUrl },
model,
});
return createReactAgent({
llm,
tools: [/* your tools */, transferBackTool],
});
});Config is also available in tool closures:
export default wrapAgent(async (context) => {
const fetchData = tool(
async ({ query }) => {
const response = await fetch(context.config.get('BASE_URL') + '/search', {
headers: { 'Authorization': `Bearer ${context.config.get('API_KEY')}` },
method: 'POST',
body: JSON.stringify({ query }),
});
return await response.text();
},
{
name: 'fetchData',
description: 'Fetch data from the API',
schema: z.object({ query: z.string() }),
}
);
// ...
});Tool Mode
In a tool-mode trik, config is available through the context passed to each handler:
import { wrapToolHandlers } from '@trikhub/sdk';
export default wrapToolHandlers({
search: async (input, context) => {
const apiKey = context.config.get('API_KEY');
const model = context.config.get('MODEL') ?? 'gpt-4';
// List all available keys (for debugging)
console.log('Configured keys:', context.config.keys());
const response = await fetch('https://api.example.com/search', {
headers: { 'Authorization': `Bearer ${apiKey}` },
method: 'POST',
body: JSON.stringify({ query: input.query, model }),
});
const data = await response.json();
return { count: data.results.length, status: 'success' };
},
});Config Context API
| Method | Returns | Description |
|---|---|---|
get(key) | string | undefined | Get value by key, returns undefined if not set |
has(key) | boolean | Check if a key exists |
keys() | string[] | List all configured keys for this trik |
Security
Isolation
Each trik only sees its own configuration. A trik with ID @alice/trik-a cannot access configuration for @bob/trik-b, even if both are loaded in the same gateway.
No Logging
Configuration values are never exposed in logs or error messages. If a required config is missing, the error says “missing API_KEY” but never reveals actual values.
Local Overrides
Local project configuration (.trikhub/secrets.json) takes precedence over global (~/.trikhub/secrets.json). This allows:
- Different API keys per project
- Development vs production credentials
- Team-specific configurations
Validation
Gateway Load-Time Warnings
When the gateway loads a trik, it checks whether all config.required keys are present. If any are missing, it prints a warning to stderr but still loads the trik (the trik may fail later at runtime when it tries to use the missing config):
[TrikGateway] Warning: trik "@molefas/gpt-trik" is missing required config: API_KEY
Add to .trikhub/secrets.json: { "@molefas/gpt-trik": { "API_KEY": "..." } }This behavior is enabled by default. To disable it, set validateConfig: false in the gateway config.
CLI Install Hints
When you install a trik that declares config.required, the CLI shows the required configuration keys and how to set them up:
$ trik install @molefas/gpt-trik
✔ Installed @molefas/gpt-trik@1.0.0
⚙ This trik requires configuration:
• API_KEY — Your OpenAI API key
Add to .trikhub/secrets.json or ~/.trikhub/secrets.json:
{
"@molefas/gpt-trik": {
"API_KEY": "your-value-here"
}
}Best Practices
- Describe keys clearly - Help users understand what each key is for
- Use defaults for optional config - Don’t require more than necessary
- Never hardcode secrets - Always use the config context
- Check before using - Validate config exists before making API calls
Next: Learn about Cross-Environment Execution for running triks across runtimes.