凭证管理技能 credentials

集中管理API密钥,安全加载和配置项目环境

DevOps 0 次安装 0 次浏览 更新于 3/5/2026

name: 凭证管理技能 description: 从Access.txt集中管理API密钥

凭证管理技能

使用base.md加载

用于安全地从集中访问文件加载API密钥并配置项目环境。


凭证文件发现

必需:当项目需要API密钥时,询问用户:

我需要[服务]的API凭证。您是否有集中访问密钥文件?

请提供路径(例如,~/Documents/Access.txt)或输入'manual'直接输入密钥。

默认检查位置

~/Documents/Access.txt
~/Access.txt
~/.secrets/keys.txt
~/.credentials.txt

支持的文件格式

凭证文件可以使用以下任何格式:

格式1:冒号分隔

Render API: rnd_xxxxx
OpenAI API: sk-proj-xxxxx
Claude API: sk-ant-xxxxx
Reddit client id: xxxxx
Reddit secret: xxxxx

格式2:键=值

RENDER_API_KEY=rnd_xxxxx
OPENAI_API_KEY=sk-proj-xxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxx

格式3:混合/非正式

Reddit api access:
client id Y1FgKALKmb6f6UxFtyMXfA
and secret is -QLoYdxMqOJkYrgk5KeGPa6Ps6vIiQ

密钥识别模式

使用这些模式在文件中识别密钥:

服务 模式 环境变量
OpenAI sk-proj-*sk-* OPENAI_API_KEY
Claude/Anthropic sk-ant-* ANTHROPIC_API_KEY
Render rnd_* RENDER_API_KEY
Eleven Labs sk_* (不是sk-ant/sk-proj) ELEVEN_LABS_API_KEY
Replicate r8_* REPLICATE_API_TOKEN
Supabase URL + eyJ* (JWT) SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY
Reddit client_id + secret对 REDDIT_CLIENT_ID, REDDIT_CLIENT_SECRET
GitHub ghp_*github_pat_* GITHUB_TOKEN
Vercel *_*来自vercel.com VERCEL_TOKEN
Stripe (测试) sk_test_*, pk_test_* STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY
Stripe (实时) sk_live_*, pk_live_* STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY
Stripe Webhook whsec_* STRIPE_WEBHOOK_SECRET
Twilio SK* + Account SID TWILIO_API_KEY, TWILIO_ACCOUNT_SID
SendGrid SG.* SENDGRID_API_KEY
AWS AKIA* + 密文 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
PostHog phc_* POSTHOG_API_KEY, NEXT_PUBLIC_POSTHOG_KEY

解析凭证文件

当读取用户的访问文件时,使用这些规则提取密钥:

# Python解析逻辑
import re
from pathlib import Path

def parse_credentials_file(file_path: str) -> dict[str, str]:
    """解析各种凭证文件格式。"""
    content = Path(file_path).expanduser().read_text()
    credentials = {}

    # 已知密钥格式的模式匹配
    patterns = {
        'OPENAI_API_KEY': r'sk-proj-[A-Za-z0-9_-]+',
        'ANTHROPIC_API_KEY': r'sk-ant-[A-Za-z0-9_-]+',
        'RENDER_API_KEY': r'rnd_[A-Za-z0-9]+',
        'REPLICATE_API_TOKEN': r'r8_[A-Za-z0-9]+',
        'ELEVEN_LABS_API_KEY': r'sk_[a-f0-9]{40,}',
        'GITHUB_TOKEN': r'ghp_[A-Za-z0-9]+|github_pat_[A-Za-z0-9_]+',
        'STRIPE_SECRET_KEY': r'sk_(live|test)_[A-Za-z0-9]+',
        'STRIPE_PUBLISHABLE_KEY': r'pk_(live|test)_[A-Za-z0-9]+',
        'STRIPE_WEBHOOK_SECRET': r'whsec_[A-Za-z0-9]+',
        'POSTHOG_API_KEY': r'phc_[A-Za-z0-9]+',
    }

    # Supabase需要特殊处理(URL + JWT令牌)
    supabase_url = re.search(r'https://[a-z0-9]+\.supabase\.co', content)
    anon_key = re.search(r'anon[^:]*:\s*(eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)', content, re.I)
    service_role = re.search(r'service.?role[^:]*:\s*(eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)', content, re.I)

    if supabase_url:
        credentials['SUPABASE_URL'] = supabase_url.group(0)
    if anon_key:
        credentials['SUPABASE_ANON_KEY'] = anon_key.group(1)
    if service_role:
        credentials['SUPABASE_SERVICE_ROLE_KEY'] = service_role.group(1)

    for env_var, pattern in patterns.items():
        match = re.search(pattern, content)
        if match:
            credentials[env_var] = match.group(0)

    # Reddit需要特殊处理(client_id + secret对)
    reddit_id = re.search(r'client.?id[:\s]+([A-Za-z0-9_-]+)', content, re.I)
    reddit_secret = re.search(r'secret[:\s]+([A-Za-z0-9_-]+)', content, re.I)
    if reddit_id:
        credentials['REDDIT_CLIENT_ID'] = reddit_id.group(1)
    if reddit_secret:
        credentials['REDDIT_CLIENT_SECRET'] = reddit_secret.group(1)

    return credentials
// TypeScript解析逻辑
function parseCredentialsFile(content: string): Record<string, string> {
  const credentials: Record<string, string> = {};

  const patterns: Record<string, RegExp> = {
    OPENAI_API_KEY: /sk-proj-[A-Za-z0-9_-]+/,
    ANTHROPIC_API_KEY: /sk-ant-[A-Za-z0-9_-]+/,
    RENDER_API_KEY: /rnd_[A-Za-z0-9]+/,
    REPLICATE_API_TOKEN: /r8_[A-Za-z0-9]+/,
    ELEVEN_LABS_API_KEY: /sk_[a-f0-9]{40,}/,
    GITHUB_TOKEN: /ghp_[A-Za-z0-9]+|github_pat_[A-Za-z0-9_]+/,
    STRIPE_SECRET_KEY: /sk_(live|test)_[A-Za-z0-9]+/,
    STRIPE_PUBLISHABLE_KEY: /pk_(live|test)_[A-Za-z0-9]+/,
    STRIPE_WEBHOOK_SECRET: /whsec_[A-Za-z0-9]+/,
    POSTHOG_API_KEY: /phc_[A-Za-z0-9]+/,
  };

  for (const [envVar, pattern] of Object.entries(patterns)) {
    const match = content.match(pattern);
    if (match) credentials[envVar] = match[0];
  }

  // Reddit对
  const redditId = content.match(/client.?id[:\s]+([A-Za-z0-9_-]+)/i);
  const redditSecret = content.match(/secret[:\s]+([A-Za-z0-9_-]+)/i);
  if (redditId) credentials.REDDIT_CLIENT_ID = redditId[1];
  if (redditSecret) credentials.REDDIT_CLIENT_SECRET = redditSecret[1];

  return credentials;
}

验证命令

提取密钥后,验证它们:

OpenAI

curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  https://api.openai.com/v1/models
# 200 = 有效

Anthropic/Claude

curl -s -o /dev/null -w "%{http_code}" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  https://api.anthropic.com/v1/models
# 200 = 有效

Render

curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $RENDER_API_KEY" \
  https://api.render.com/v1/services
# 200 = 有效

Reddit

# 首先获取OAuth令牌
TOKEN=$(curl -s -X POST \
  -u "$REDDIT_CLIENT_ID:$REDDIT_CLIENT_SECRET" \
  -d "grant_type=client_credentials" \
  -A "CredentialTest/1.0" \
  https://www.reddit.com/api/v1/access_token | jq -r '.access_token')
# 非空令牌 = 有效

Replicate

curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Token $REPLICATE_API_TOKEN" \
  https://api.replicate.com/v1/models
# 200 = 有效

项目设置工作流程

当初始化需要API密钥的项目时:

第1步:询问凭证文件

该项目需要以下API密钥:
- ANTHROPIC_API_KEY(用于Claude)
- SUPABASE_URL和SUPABASE_ANON_KEY

您是否有访问密钥文件?请提供路径:

第2步:读取和解析

# 读取文件
credentials = parse_credentials_file("~/Documents/Access.txt")

# 显示找到的内容
print("找到的凭证:")
for key, value in credentials.items():
    masked = value[:8] + "..." + value[-4:]
    print(f"  {key}: {masked}")

第3步:验证密钥

验证凭证...
✓ ANTHROPIC_API_KEY:有效
✓ REDDIT_CLIENT_ID:有效
✗ SUPABASE_URL:文件中未找到

第4步:创建.env文件

# 写入项目.env
cat > .env << EOF
# 从~/Documents/Access.txt自动生成
ANTHROPIC_API_KEY=sk-ant-xxx...
REDDIT_CLIENT_ID=xxx...
REDDIT_CLIENT_SECRET=xxx...
EOF

# 如果.gitignore中不存在,则添加
echo ".env" >> .gitignore

第5步:报告缺失的密钥

缺少需要手动设置的凭证:
- SUPABASE_URL:从supabase.com/dashboard/project/[ref]/settings/api获取
- SUPABASE_ANON_KEY:同上位置

您希望我打开这些URL吗?

服务特定设置指南

Reddit(来自Access.txt)

在您的访问文件中找到:
- REDDIT_CLIENT_ID:Y1FgKA...
- REDDIT_CLIENT_SECRET:-QLoYd...

还需要(添加到Access.txt或手动输入):
- REDDIT_USER_AGENT:YourApp/1.0 by YourUsername

Supabase(通常不在文件中)

Supabase凭证是项目特定的。从以下位置获取:
https://supabase.com/dashboard/project/[your-ref]/settings/api

所需:
- SUPABASE_URL
- SUPABASE_ANON_KEY
- SUPABASE_SERVICE_ROLE_KEY(用于管理操作)

安全规则

  • 永不 提交Access.txt或其路径到git
  • 永不 登录完整的API密钥 - 始终遮蔽中间字符
  • 始终.env添加到.gitignore
  • 始终 使用环境变量,不要硬编码密钥
  • 验证 生产设置中的密钥

快速参考

# 检查凭证文件是否存在
ls -la ~/Documents/Access.txt

# 常见的环境变量名称
OPENAI_API_KEY
ANTHROPIC_API_KEY
RENDER_API_KEY
REDDIT_CLIENT_ID
REDDIT_CLIENT_SECRET
REPLICATE_API_TOKEN
ELEVEN_LABS_API_KEY
SUPABASE_URL
SUPABASE_ANON_KEY
GITHUB_TOKEN

提示模板

我需要这个项目的API凭证。

您是否有集中访问密钥文件(如~/Documents/Access.txt)?

如果有,请提供路径,我将:
1. 读取和解析您的密钥
2. 验证它们是否有效
3. 设置您项目的.env文件
4. 告诉您哪些密钥缺失