How k-skill Handles Sensitive Data and Credentials: A Tiered Security Architecture

k-skill protects secrets through a five-tier resolution strategy that never exposes plaintext values to the LLM, utilizing agent-hosted vaults first and falling back to permission-locked local files only when necessary.

The open-source k-skill framework (available at NomaDamas/k-skill) implements a defense-in-depth approach to credential management designed specifically for AI agent runtimes. When building skills that interact with external APIs and sensitive services, understanding how k-skill handles sensitive data and credentials securely ensures your agents operate with minimal attack surface and maximum auditability.

The Five-Tier Credential Resolution Strategy

The runtime resolves credentials through a strictly ordered hierarchy defined in docs/security-and-secrets.md. This tiered approach ensures the most secure storage option is always attempted before falling back to less privileged alternatives.

Tier 1: Dolshoi Vault Mode

When DOLSHOI_ACTION_BROKER_URL is defined and the vault-run capability is available, k-skill connects directly to the provisioned agent-hosted vault (such as 1Password, Bitwarden, or macOS Keychain). The LLM never receives the plaintext ID, password, or API key; the runtime retrieves values directly from the vault process.

Tier 2: Interactive Vault Provisioning

If the vault capability is absent, the runtime invokes the request_vault_credential tool. This opens the host machine's native vault UI, allowing the user to supply the secret securely. The system stores the credential in the vault and automatically retries the original action without exposing the plaintext value to the agent.

Tier 3: Generic Injected Secrets

In non-Dolshoi environments, k-skill utilizes secrets already injected via environment variables or the host-level vault. These values remain in process memory and are never logged or transmitted to the language model.

Tier 4: Local Dotenv Fallback

When no injected secrets exist, the runtime reads from ~/.config/k-skill/secrets.env. This plain-dotenv file must be created with permissions 0600 (read/write for owner only) and is excluded from version control via .gitignore. The framework enforces this permission level to prevent unauthorized access.

Tier 5: Secure User Prompting

If no credential source yields a value, k-skill requests the secret through the safest available input surface (such as a secure UI dialog). The system stores the response in either the vault or the dotenv file, ensuring the plaintext is never echoed back to the LLM or logged in conversation history.

Core Security Guarantees

The implementation enforces strict policies to prevent credential leakage:

  • Never output plaintext secrets – All snapshots and tests assert that the model does not ask for, print, or store raw secret values according to the runtime contract.
  • Least-privilege storage – The fallback dotenv file at ~/.config/k-skill/secrets.env requires mode 0600 and explicit exclusion from git repositories.
  • Explicit secret naming – Only a curated list of well-known variable names (such as KSKILL_SRT_ID and KSKILL_KOSIS_API_KEY) is permitted, reducing the attack surface against arbitrary secret injection.
  • No secret-driven workarounds – If a required secret is missing, the system never switches to unofficial APIs or hard-coded credentials; it strictly prompts the user for safe provisioning.
  • Portable fallback compatibility – Non-Dolshoi runtimes maintain backward compatibility using standard environment-variable conventions while preserving the same security boundaries.

Runtime Implementation and Auditing

All top-level SKILL.md files include a "Runtime contract (required)" block that codifies these policies. The docs/runtime-action-audit.md document verifies that each skill respects the credential flow and contains no unauthorized secret handling patterns.

The getCredential function in the runtime package encapsulates the resolution order. Skills import this helper to ensure consistent security behavior:

// Resolve credentials for a SRT booking skill
import { getCredential } from "@nomadamas/k-skill-runtime";

/* Attempt Dolshoi vault first, then fall back to env/dotenv */
const srtId = await getCredential("KSKILL_SRT_ID");
const srtPwd = await getCredential("KSKILL_SRT_PASSWORD");

/* 
 * If credentials are missing, the runtime automatically invokes 
 * request_vault_credential and retries without exposing values 
 * to the LLM context.
 */

This helper ensures that even if a skill author forgets to check for vault capabilities, the runtime intercepts the request and routes it through the safest available channel.

Local Development and Fallback Configuration

For development environments without vault capabilities, create the fallback secrets file with strict permissions:


# Create the config directory

mkdir -p ~/.config/k-skill

# Write secrets with restricted permissions

cat > ~/.config/k-skill/secrets.env <<'EOS'
KSKILL_SRT_ID=my-srt-id
KSKILL_SRT_PASSWORD=my-srt-pwd
KSKILL_KOSIS_API_KEY=my-api-key
EOS

# Enforce owner-only access (required by k-skill)

chmod 600 ~/.config/k-skill/secrets.env

The runtime validates these permissions at startup. If the file is readable by group or others, k-skill refuses to load the credentials and exits with a security error.

Summary

  • k-skill implements a five-tier hierarchy for credential resolution, prioritizing agent-hosted vaults over local files.
  • The LLM never sees plaintext secrets; all values resolve through secure channels or user prompts outside the model context.
  • Permission enforcement ensures fallback files use mode 0600 and remain excluded from version control.
  • Explicit allowlisting of variable names prevents arbitrary secret exfiltration.
  • Runtime auditing via SKILL.md contracts and docs/runtime-action-audit.md ensures compliance across all skills.

Frequently Asked Questions

Does k-skill ever send my passwords or API keys to the LLM?

No. The framework architecture ensures that raw credential values never enter the LLM context window. When using Dolshoi mode, the runtime retrieves secrets directly from the vault process. In fallback scenarios, the system either reads from environment variables or prompts the user through secure OS-level dialogs, storing results in ~/.config/k-skill/secrets.env without echoing them back to the conversation.

What happens if I don't have a password manager installed?

k-skill falls back to environment variables or the local secrets.env file. If neither exists, the runtime invokes request_vault_credential to open your system's native credential UI. If no vault is available, it prompts for the secret through the safest input method supported by your operating system, then stores it in the local dotenv file with 0600 permissions for future use.

Why does k-skill require 0600 permissions on the secrets file?

The 0600 permission bit (read/write for owner only) ensures that no other user or process on the system can access your stored credentials. k-skill validates these permissions before loading ~/.config/k-skill/secrets.env. If the file is group-readable or world-readable, the runtime exits immediately to prevent accidental credential exposure in shared or compromised environments.

Which specific environment variables does k-skill support?

k-skill uses an explicit allowlist defined in docs/security-and-secrets.md. Common variables include KSKILL_SRT_ID, KSKILL_SRT_PASSWORD, and KSKILL_KOSIS_API_KEY. This restricted naming convention prevents skills from requesting arbitrary secrets outside their intended scope, reducing the risk of credential stuffing attacks or unintended data exfiltration.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →