How tres-finance-plugin Uses userConfig for Secure API Key Management
The tres-finance-plugin declares API credentials in its plugin.json manifest under the userConfig field, enabling Claude to expose a secure configuration UI where users input their DeBank Pro API key, which skill scripts then access at runtime via the ${user_config.DEBANK_API_KEY} environment variable.
The tres-finance-plugin demonstrates the canonical pattern for handling sensitive third-party credentials within the Claude plugin ecosystem. Located in the anthropics/claude-plugins-community repository, this plugin leverages native userConfig declarations to securely collect DeBank API keys while keeping secrets out of chat history and shell logs. Understanding how tres-finance-plugin uses userConfig for API keys provides a security-first blueprint for developers building financial data integrations.
Declaring API Keys in plugin.json
The configuration flow begins in the plugin manifest at tres-finance-plugin/.claude-plugin/plugin.json. Here, the plugin defines a sensitive string field named DEBANK_API_KEY within the userConfig object.
{
"userConfig": {
"DEBANK_API_KEY": {
"title": "DeBank API Key",
"description": "Your DeBank Pro API key for balance validation (from https://cloud.debank.com)",
"type": "string",
"sensitive": true
}
}
}
Setting "sensitive": true instructs Claude’s plugin framework to mask the input value in the UI, treating it as a password field rather than plain text. When a user installs the plugin, Claude renders a dedicated settings page containing this configuration input, prompting the user to obtain their key from https://cloud.debank.com and paste it into the secure field.
Runtime Access in Skill Scripts
Once persisted, the API key becomes available to all skills within the plugin namespace via the user_config object. The tres-asset-balance-validation skill demonstrates the retrieval pattern in its documentation at skills/tres-asset-balance-validation/SKILL.md.
Authenticating DeBank API Requests
Skill scripts reference the variable directly in shell commands to inject the AccessKey header required by DeBank’s Pro OpenAPI:
curl -s -G \
-H "AccessKey: ${user_config.DEBANK_API_KEY}" \
--data-urlencode "id=$WALLET_ADDR" \
"https://pro-openapi.debank.com/v1/user/all_token_list"
This approach keeps the secret out of process listings and chat transcripts while ensuring each request carries valid authentication credentials.
Handling Missing Configuration
The skill implements defensive programming to prevent execution without credentials. If the user has not configured the key, the script halts with an explicit error message:
if [ -z "${user_config.DEBANK_API_KEY}" ]; then
echo "DEBANK_API_KEY is not configured. Please add it via the plugin settings (obtain your key at https://cloud.debank.com)."
exit 1
fi
This guard clause ensures that API calls fail fast with actionable guidance rather than exposing cryptic authentication errors from the upstream service.
Security Benefits of the userConfig Pattern
Using userConfig for API keys provides three critical security advantages:
- Isolation from chat history: Secrets reside in Claude’s encrypted plugin configuration store, never appearing in conversation logs or model context windows.
- UI-level protection: The
"sensitive": trueflag triggers password masking and prevents shoulder-surfing during configuration. - Scoped access: Only skills within the
tres-finance-pluginnamespace can accessuser_config.DEBANK_API_KEY, minimizing the blast radius of potential credential leakage.
Summary
- The tres-finance-plugin declares
DEBANK_API_KEYas a sensitive string in.claude-plugin/plugin.jsonunder theuserConfigobject. - Users input their DeBank Pro API key through Claude’s secure plugin settings UI, accessible immediately after installation.
- Skills access the key at runtime using
${user_config.DEBANK_API_KEY}to authenticate requests tohttps://pro-openapi.debank.com. - The
tres-asset-balance-validationskill validates the presence of the key before executingcurlcommands, aborting with a helpful error if the configuration is missing. - This pattern ensures API secrets remain encrypted at rest and are never exposed in chat history or shell process lists.
Frequently Asked Questions
What file defines the API key configuration for tres-finance-plugin?
The configuration schema resides in tres-finance-plugin/.claude-plugin/plugin.json. This JSON manifest contains the userConfig object where DEBANK_API_KEY is declared with type string and sensitive: true, which signals Claude to render a secure input field in the plugin settings interface.
How do skill scripts access the API key provided by the user?
Skill scripts access the key through the user_config environment object. Specifically, the tres-asset-balance-validation skill references ${user_config.DEBANK_API_KEY} within bash scripts to populate the AccessKey header when calling DeBank’s API endpoints. This variable is automatically injected by Claude’s plugin runtime at execution time.
What happens if the DeBank API key is not configured?
If the DEBANK_API_KEY field is empty or undefined, the skill detects this condition using a bash null check (-z) and immediately exits with status code 1. The error message explicitly instructs the user to add the key via plugin settings and provides the URL https://cloud.debank.com for obtaining credentials, preventing unauthorized or malformed API requests.
Why is the sensitive flag important in the userConfig declaration?
The "sensitive": true property ensures that Claude treats the input as a password field, masking characters during entry and storing the value in an encrypted configuration store rather than plain text. This prevents the API key from appearing in UI logs, chat history, or debug output, significantly reducing the risk of accidental credential exposure.
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 →