Learn-skills.dev setup-credentials
Set up and install credentials for an agent. Detects missing credentials from agent config, collects them from the user, and stores them securely in the encrypted credential store at ~/.hive/credentials.
git clone https://github.com/NeverSight/learn-skills.dev
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/adenhq/hive/setup-credentials" ~/.claude/skills/neversight-learn-skills-dev-setup-credentials && rm -rf "$T"
data/skills-md/adenhq/hive/setup-credentials/SKILL.mdSetup Credentials
Interactive credential setup for agents with multiple authentication options. Detects what's missing, offers auth method choices, validates with health checks, and stores credentials securely.
When to Use
- Before running or testing an agent for the first time
- When
fails with "missing required credentials"AgentRunner.run() - When a user asks to configure credentials for an agent
- After building a new agent that uses tools requiring API keys
Workflow
Step 1: Identify the Agent
Determine which agent needs credentials. The user will either:
- Name the agent directly (e.g., "set up credentials for hubspot-agent")
- Have an agent directory open (check
for agent dirs)exports/ - Be working on an agent in the current session
Locate the agent's directory under
exports/{agent_name}/.
Step 2: Detect Required Credentials
Read the agent's configuration to determine which tools and node types it uses:
from core.framework.runner import AgentRunner runner = AgentRunner.load("exports/{agent_name}") validation = runner.validate() # validation.missing_credentials contains env var names # validation.warnings contains detailed messages with help URLs
Alternatively, check the credential store directly:
from core.framework.credentials import CredentialStore # Use encrypted storage (default: ~/.hive/credentials) store = CredentialStore.with_encrypted_storage() # Check what's available available = store.list_credentials() print(f"Available credentials: {available}") # Check if specific credential exists if store.is_available("hubspot"): print("HubSpot credential found") else: print("HubSpot credential missing")
To see all known credential specs (for help URLs and setup instructions):
from aden_tools.credentials import CREDENTIAL_SPECS for name, spec in CREDENTIAL_SPECS.items(): print(f"{name}: env_var={spec.env_var}, aden={spec.aden_supported}")
Step 3: Present Auth Options for Each Missing Credential
For each missing credential, check what authentication methods are available:
from aden_tools.credentials import CREDENTIAL_SPECS spec = CREDENTIAL_SPECS.get("hubspot") if spec: # Determine available auth options auth_options = [] if spec.aden_supported: auth_options.append("aden") if spec.direct_api_key_supported: auth_options.append("direct") auth_options.append("custom") # Always available # Get setup info setup_info = { "env_var": spec.env_var, "description": spec.description, "help_url": spec.help_url, "api_key_instructions": spec.api_key_instructions, }
Present the available options using AskUserQuestion:
Choose how to configure HUBSPOT_ACCESS_TOKEN: 1) Aden Authorization Server (Recommended) Secure OAuth2 flow via integration.adenhq.com - Quick setup with automatic token refresh - No need to manage API keys manually 2) Direct API Key Enter your own API key manually - Requires creating a HubSpot Private App - Full control over scopes and permissions 3) Custom Credential Store (Advanced) Programmatic configuration for CI/CD - For automated deployments - Requires manual API calls
Step 4: Execute Auth Flow Based on User Choice
Option 1: Aden Authorization Server
This is the recommended flow for supported integrations (HubSpot, etc.).
How Aden OAuth Works:
The ADEN_API_KEY represents a user who has already completed OAuth authorization on Aden's platform. When users sign up and connect integrations on Aden, those OAuth tokens are stored server-side. Having an ADEN_API_KEY means:
- User has an Aden account
- User has already authorized integrations (HubSpot, etc.) via OAuth on Aden
- We just need to sync those credentials down to the local credential store
4.1a. Check for ADEN_API_KEY
import os aden_key = os.environ.get("ADEN_API_KEY")
If not set, guide user to get one from Aden (this is where they do OAuth):
from aden_tools.credentials import open_browser, get_aden_setup_url # Open browser to Aden - user will sign up and connect integrations there url = get_aden_setup_url() # https://integration.adenhq.com/setup success, msg = open_browser(url) print("Please sign in to Aden and connect your integrations (HubSpot, etc.).") print("Once done, copy your API key and return here.")
Ask user to provide the ADEN_API_KEY they received.
4.1b. Save ADEN_API_KEY to Shell Config
With user approval, persist ADEN_API_KEY to their shell config:
from aden_tools.credentials import ( detect_shell, add_env_var_to_shell_config, get_shell_source_command, ) shell_type = detect_shell() # 'bash', 'zsh', or 'unknown' # Ask user for approval before modifying shell config # If approved: success, config_path = add_env_var_to_shell_config( "ADEN_API_KEY", user_provided_key, comment="Aden authorization server API key" ) if success: source_cmd = get_shell_source_command() print(f"Saved to {config_path}") print(f"Run: {source_cmd}")
Also save to
~/.hive/configuration.json for the framework:
import json from pathlib import Path config_path = Path.home() / ".hive" / "configuration.json" config = json.loads(config_path.read_text()) if config_path.exists() else {} config["aden"] = { "api_key_configured": True, "api_url": "https://api.adenhq.com" } config_path.parent.mkdir(parents=True, exist_ok=True) config_path.write_text(json.dumps(config, indent=2))
4.1c. Sync Credentials from Aden Server
Since the user has already authorized integrations on Aden, use the one-liner factory method:
from core.framework.credentials import CredentialStore # This single call handles everything: # - Creates encrypted local storage at ~/.hive/credentials # - Configures Aden client from ADEN_API_KEY env var # - Syncs all credentials from Aden server automatically store = CredentialStore.with_aden_sync( base_url="https://api.adenhq.com", auto_sync=True, # Syncs on creation ) # Check what was synced synced = store.list_credentials() print(f"Synced credentials: {synced}") # If the required credential wasn't synced, the user hasn't authorized it on Aden yet if "hubspot" not in synced: print("HubSpot not found in your Aden account.") print("Please visit https://integration.adenhq.com to connect HubSpot, then try again.")
For more control over the sync process:
from core.framework.credentials import CredentialStore from core.framework.credentials.aden import ( AdenCredentialClient, AdenClientConfig, AdenSyncProvider, ) # Create client (API key loaded from ADEN_API_KEY env var) client = AdenCredentialClient(AdenClientConfig( base_url="https://api.adenhq.com", )) # Create provider and store provider = AdenSyncProvider(client=client) store = CredentialStore.with_encrypted_storage() # Manual sync synced_count = provider.sync_all(store) print(f"Synced {synced_count} credentials from Aden")
4.1d. Run Health Check
from aden_tools.credentials import check_credential_health # Get the token from the store cred = store.get_credential("hubspot") token = cred.keys["access_token"].value.get_secret_value() result = check_credential_health("hubspot", token) if result.valid: print("HubSpot credentials validated successfully!") else: print(f"Validation failed: {result.message}") # Offer to retry the OAuth flow
Option 2: Direct API Key
For users who prefer manual API key management.
4.2a. Show Setup Instructions
from aden_tools.credentials import CREDENTIAL_SPECS spec = CREDENTIAL_SPECS.get("hubspot") if spec and spec.api_key_instructions: print(spec.api_key_instructions) # Output: # To get a HubSpot Private App token: # 1. Go to HubSpot Settings > Integrations > Private Apps # 2. Click "Create a private app" # 3. Name your app (e.g., "Hive Agent") # ... if spec and spec.help_url: print(f"More info: {spec.help_url}")
4.2b. Collect API Key from User
Use AskUserQuestion to securely collect the API key:
Please provide your HubSpot access token: (This will be stored securely in ~/.hive/credentials)
4.2c. Run Health Check Before Storing
from aden_tools.credentials import check_credential_health result = check_credential_health("hubspot", user_provided_token) if not result.valid: print(f"Warning: {result.message}") # Ask user if they want to: # 1. Try a different token # 2. Continue anyway (not recommended)
4.2d. Store in Encrypted Credential Store
from core.framework.credentials import CredentialStore, CredentialObject, CredentialKey from pydantic import SecretStr store = CredentialStore.with_encrypted_storage() cred = CredentialObject( id="hubspot", name="HubSpot Access Token", keys={ "access_token": CredentialKey( name="access_token", value=SecretStr(user_provided_token), ) }, ) store.save_credential(cred)
4.2e. Export to Current Session
export HUBSPOT_ACCESS_TOKEN="the-value"
Option 3: Custom Credential Store (Advanced)
For programmatic/CI/CD setups.
4.3a. Show Documentation
For advanced credential management, you can use the CredentialStore API directly: from core.framework.credentials import CredentialStore, CredentialObject, CredentialKey from pydantic import SecretStr store = CredentialStore.with_encrypted_storage() cred = CredentialObject( id="hubspot", name="HubSpot Access Token", keys={"access_token": CredentialKey(name="access_token", value=SecretStr("..."))} ) store.save_credential(cred) For CI/CD environments: - Set HIVE_CREDENTIAL_KEY for encryption - Pre-populate ~/.hive/credentials programmatically - Or use environment variables directly (HUBSPOT_ACCESS_TOKEN) Documentation: See core/framework/credentials/README.md
Step 5: Record Configuration Method
Track which auth method was used for each credential in
~/.hive/configuration.json:
import json from pathlib import Path from datetime import datetime config_path = Path.home() / ".hive" / "configuration.json" config = json.loads(config_path.read_text()) if config_path.exists() else {} if "credential_methods" not in config: config["credential_methods"] = {} config["credential_methods"]["hubspot"] = { "method": "aden", # or "direct" or "custom" "configured_at": datetime.now().isoformat(), } config_path.write_text(json.dumps(config, indent=2))
Step 6: Verify All Credentials
Run validation again to confirm everything is set:
runner = AgentRunner.load("exports/{agent_name}") validation = runner.validate() assert not validation.missing_credentials, "Still missing credentials!"
Report the result to the user.
Health Check Reference
Health checks validate credentials by making lightweight API calls:
| Credential | Endpoint | What It Checks |
|---|---|---|
| | Bearer token validity, CRM scopes |
| | API key validity |
from aden_tools.credentials import check_credential_health, HealthCheckResult result: HealthCheckResult = check_credential_health("hubspot", token_value) # result.valid: bool # result.message: str # result.details: dict (status_code, rate_limited, etc.)
Encryption Key (HIVE_CREDENTIAL_KEY)
The encrypted credential store requires
HIVE_CREDENTIAL_KEY to encrypt/decrypt credentials.
- If the user doesn't have one,
will auto-generate one and log itEncryptedFileStorage - The user MUST persist this key (e.g., in
or a secrets manager)~/.bashrc - Without this key, stored credentials cannot be decrypted
- This is the ONLY secret that should live in
or environment config~/.bashrc
If
HIVE_CREDENTIAL_KEY is not set:
- Let the store generate one
- Tell the user to save it:
export HIVE_CREDENTIAL_KEY="{generated_key}" - Recommend adding it to
or their shell profile~/.bashrc
Security Rules
- NEVER log, print, or echo credential values in tool output
- NEVER store credentials in plaintext files, git-tracked files, or agent configs
- NEVER hardcode credentials in source code
- ALWAYS use
from Pydantic when handling credential values in PythonSecretStr - ALWAYS use the encrypted credential store (
) for persistence~/.hive/credentials - ALWAYS run health checks before storing credentials (when possible)
- ALWAYS verify credentials were stored by re-running validation, not by reading them back
- When modifying
or~/.bashrc
, confirm with the user first~/.zshrc
Credential Sources Reference
All credential specs are defined in
tools/src/aden_tools/credentials/:
| File | Category | Credentials | Aden Supported |
|---|---|---|---|
| LLM Providers | | No |
| Search Tools | , , | No |
| Integrations | | Yes |
Note: Additional LLM providers (Cerebras, Groq, OpenAI) are handled by LiteLLM via environment variables (
CEREBRAS_API_KEY, GROQ_API_KEY, OPENAI_API_KEY) but are not yet in CREDENTIAL_SPECS.
Add them to llm.py as needed.
To check what's registered:
from aden_tools.credentials import CREDENTIAL_SPECS for name, spec in CREDENTIAL_SPECS.items(): print(f"{name}: aden={spec.aden_supported}, direct={spec.direct_api_key_supported}")
Migration: CredentialManager → CredentialStore
CredentialManager is deprecated. Use CredentialStore instead.
| Old (Deprecated) | New (Recommended) |
|---|---|
| |
| or |
| Use per credential |
| Check |
| Access directly |
Why migrate?
- CredentialStore supports encrypted storage, multi-key credentials, template resolution, and automatic token refresh
- CredentialManager only reads from environment variables and .env files (no encryption, no refresh)
- CredentialStoreAdapter exists for backward compatibility during migration
# Old way (deprecated) from aden_tools.credentials import CredentialManager creds = CredentialManager() token = creds.get("hubspot") # New way (recommended) from core.framework.credentials import CredentialStore store = CredentialStore.with_encrypted_storage() token = store.get("hubspot") # With Aden sync (recommended for OAuth integrations) store = CredentialStore.with_aden_sync() token = store.get_key("hubspot", "access_token")
Example Session
User: /setup-credentials for my hubspot-agent Agent: Let me check what credentials your hubspot-agent needs. [Runs validation, finds ANTHROPIC_API_KEY and HUBSPOT_ACCESS_TOKEN missing] Agent: Your hubspot-agent requires 2 credentials: 1. ANTHROPIC_API_KEY - Anthropic API key for LLM calls 2. HUBSPOT_ACCESS_TOKEN - HubSpot access token Let's set these up one at a time. --- Setting up ANTHROPIC_API_KEY --- This credential only supports direct API key entry. [Shows instructions for getting Anthropic API key] [AskUserQuestion: "Please provide your Anthropic API key:"] [User provides key] [Stores in credential store, exports to env] --- Setting up HUBSPOT_ACCESS_TOKEN --- [AskUserQuestion with 3 options] Choose how to configure HUBSPOT_ACCESS_TOKEN: 1) Aden Authorization Server (Recommended) 2) Direct API Key 3) Custom Credential Store (Advanced) User: 1 (Aden) Agent: Great! Let me check if you have an Aden API key configured... [Checks for ADEN_API_KEY, not found] [Opens browser to integration.adenhq.com/setup] Agent: I've opened Aden's setup page. Please: 1. Sign in or create an account 2. Connect your HubSpot account (OAuth happens on Aden's site) 3. Copy the API key shown after setup [AskUserQuestion: "Please provide your Aden API key:"] [User provides key] Agent: Would you like me to save this to your shell config (~/.zshrc) for future sessions? [User approves] [Saves to ~/.zshrc and ~/.hive/configuration.json] Agent: Let me sync your credentials from Aden... [Syncs credentials from Aden server - OAuth already done on Aden's side] [Runs health check] Agent: HubSpot credentials validated successfully! All credentials are now configured: - ANTHROPIC_API_KEY: Stored in encrypted credential store - HUBSPOT_ACCESS_TOKEN: Synced from Aden (OAuth completed on Aden) - Validation passed - your agent is ready to run!