Learn-skills.dev hive-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 local encrypted 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/hive-credentials" ~/.claude/skills/neversight-learn-skills-dev-hive-credentials && rm -rf "$T"
data/skills-md/adenhq/hive/hive-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 Missing Credentials
Use the
check_missing_credentials MCP tool to detect what the agent needs and what's already configured. This tool loads the agent, inspects its required tools and node types, maps them to credentials via CREDENTIAL_SPECS, and checks both the encrypted store and environment variables.
check_missing_credentials(agent_path="exports/{agent_name}")
The tool returns a JSON response:
{ "agent": "exports/{agent_name}", "missing": [ { "credential_name": "brave_search", "env_var": "BRAVE_SEARCH_API_KEY", "description": "Brave Search API key for web search", "help_url": "https://brave.com/search/api/", "tools": ["web_search"] } ], "available": [ { "credential_name": "anthropic", "env_var": "ANTHROPIC_API_KEY", "source": "encrypted_store" } ], "total_missing": 1, "ready": false }
If
is true (nothing missing): Report all credentials as configured and skip Steps 3-5. Example:ready
All required credentials are already configured: ✓ anthropic (ANTHROPIC_API_KEY) ✓ brave_search (BRAVE_SEARCH_API_KEY) Your agent is ready to run!
If credentials are missing: Continue to Step 3 with the
missing list.
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 Platform (OAuth) (Recommended) Secure OAuth2 flow via hive.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) Local Credential Setup (Advanced) Programmatic configuration for CI/CD - For automated deployments - Requires manual API calls
Step 4: Execute Auth Flow Based on User Choice
Prerequisite: Ensure HIVE_CREDENTIAL_KEY Is Available
Before storing any credentials, verify
HIVE_CREDENTIAL_KEY is set (needed to encrypt/decrypt the local store). Check both the current session and shell config:
# Check current session printenv HIVE_CREDENTIAL_KEY > /dev/null 2>&1 && echo "session: set" || echo "session: not set" # Check shell config files for f in ~/.zshrc ~/.bashrc ~/.profile; do [ -f "$f" ] && grep -q 'HIVE_CREDENTIAL_KEY' "$f" && echo "$f"; done
- In current session — proceed to store credentials
- In shell config but NOT in current session — run
(orsource ~/.zshrc
) first, then proceed~/.bashrc - Not set anywhere —
will auto-generate one. After storing, tell the user to persist it:EncryptedFileStorage
in their shell profileexport HIVE_CREDENTIAL_KEY="{generated_key}"
⚠️ IMPORTANT: After adding
to the user's shell config, always display:HIVE_CREDENTIAL_KEY⚠️ Environment variables were added to your shell config. Open a NEW TERMINAL for them to take effect outside this session.
Option 1: Aden Platform (OAuth)
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://hive.adenhq.com 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 Platform (OAuth) API key" ) if success: source_cmd = get_shell_source_command() print(f"Saved to {config_path}") print(f"Run: {source_cmd}")
⚠️ IMPORTANT: After adding
to the user's shell config, always display:ADEN_API_KEY⚠️ Environment variables were added to your shell config. Open a NEW TERMINAL for them to take effect outside this session.
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://hive.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 Local Encrypted 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: Local Credential Setup (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
Use the
verify_credentials MCP tool to confirm everything is properly configured:
verify_credentials(agent_path="exports/{agent_name}")
The tool returns:
{ "agent": "exports/{agent_name}", "ready": true, "missing_credentials": [], "warnings": [], "errors": [] }
If
ready is true, report success. If missing_credentials is non-empty, identify what failed and loop back to Step 3 for the remaining credentials.
Health Check Reference
Health checks validate credentials by making lightweight API calls:
| Credential | Endpoint | What It Checks |
|---|---|---|
| | API key validity |
| | API key validity |
| | API key + CSE ID validity |
| | Token validity, user identity |
| | 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 local encrypted 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
/~/.bashrc
or a secrets manager)~/.zshrc - Without this key, stored credentials cannot be decrypted
Shell config rule: Only TWO keys belong in shell config (
~/.zshrc/~/.bashrc):
— encryption key for the credential storeHIVE_CREDENTIAL_KEY
— Aden platform auth key (needed before the store can sync)ADEN_API_KEY
All other API keys (Brave, Google, HubSpot, etc.) must go in the encrypted store only. Never offer to add them to shell config.
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
- NEVER offer to save API keys to shell config (
/~/.zshrc
) — the only keys that belong in shell config are~/.bashrc
andHIVE_CREDENTIAL_KEY
. All other credentials (Brave, Google, HubSpot, GitHub, Resend, etc.) go in the encrypted store only.ADEN_API_KEY - ALWAYS use
from Pydantic when handling credential values in PythonSecretStr - ALWAYS use the local encrypted 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 |
| | No | |
| Integrations | , , | No / 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: /hive-credentials for my research-agent Agent: Let me check what credentials your research-agent needs. [Calls check_missing_credentials(agent_path="exports/research-agent")] → Returns: available: anthropic (encrypted_store), brave_search (encrypted_store) missing: google_search (GOOGLE_API_KEY), google_cse (GOOGLE_CSE_ID) ready: false Agent: 2 of 4 required credentials are already configured. Only Google Custom Search needs setup (2 values). --- Setting up Google Custom Search (google_search + google_cse) --- This requires two values that work together. [Checks HIVE_CREDENTIAL_KEY before storing] $ printenv HIVE_CREDENTIAL_KEY > /dev/null 2>&1 && echo "set" || echo "not set" set First, the Google API Key: 1. Go to https://console.cloud.google.com/apis/credentials 2. Create a new project (or select an existing one) 3. Enable the "Custom Search API" from the API Library 4. Go to Credentials > Create Credentials > API Key 5. Copy the generated API key [AskUserQuestion: "Please provide your Google API key:"] [User provides key] Now, the Custom Search Engine ID: 1. Go to https://programmablesearchengine.google.com/controlpanel/all 2. Click "Add" to create a new search engine 3. Under "What to search", select "Search the entire web" 4. Give your search engine a name 5. Click "Create" 6. Copy the Search Engine ID (cx value) [AskUserQuestion: "Please provide your Google CSE ID:"] [User provides ID] [Runs health check with both values - GET /customsearch/v1?q=test&num=1 → 200 OK] [Stores both in local encrypted store, exports to env] ✓ Google Custom Search credentials valid [Calls verify_credentials(agent_path="exports/research-agent")] → Returns: ready: true, missing_credentials: [] All credentials are now configured: ✓ anthropic (ANTHROPIC_API_KEY) — already in encrypted store ✓ brave_search (BRAVE_SEARCH_API_KEY) — already in encrypted store ✓ google_search (GOOGLE_API_KEY) — stored in encrypted store ✓ google_cse (GOOGLE_CSE_ID) — stored in encrypted store ┌─────────────────────────────────────────────────────────────────────────────┐ │ ✅ CREDENTIALS CONFIGURED │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ OPEN A NEW TERMINAL before running commands below. │ │ Environment variables were saved to your shell config but │ │ only take effect in new terminal sessions. │ │ │ │ NEXT STEPS: │ │ │ │ 1. RUN YOUR AGENT: │ │ │ │ hive tui │ │ │ │ 2. IF YOU ENCOUNTER ISSUES, USE THE DEBUGGER: │ │ │ │ /hive-debugger │ │ │ │ The debugger analyzes runtime logs, identifies retry loops, tool │ │ failures, stalled execution, and provides actionable fix suggestions. │ │ │ └─────────────────────────────────────────────────────────────────────────────┘