mcpField
C
credentials

credentials

github.com/alinaqi安全710280 次安装2 周前更新
代码仓库

关于 credentials

用于从集中凭据文件中查找 API 密钥、验证密钥并配置项目环境变量的技能,涵盖多种文件格式、服务密钥模式及秘密保护规则。

主要功能

  1. 01检查常见凭据文件位置
  2. 02解析多种键值格式
  3. 03识别特定服务凭据
  4. 04验证指定 API 密钥
  5. 05安全配置环境变量

适用场景

  1. 01为新项目准备凭据
  2. 02将密钥写入项目 .env 文件
  3. 03检查支持的 API 密钥是否有效

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alinaqi/maggy --skill credentials

安装后在 Claude Code 中输入/credentials确认已加载。

详细介绍

凭据管理技能

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


凭据文件发现

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

I need API credentials for [service]. Do you have a centralized access keys file?

Please provide the path (e.g., ~/Documents/Access.txt) or type 'manual' to enter keys directly.
要检查的默认位置
~/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

密钥识别模式

使用以下模式识别文件中的密钥:

服务模式环境变量
OpenAIsk-proj-* 或 sk-*OPENAI_API_KEY
Claude/Anthropicsk-ant-*ANTHROPIC_API_KEY
Renderrnd_*RENDER_API_KEY
Eleven Labssk_*(不是 sk-ant/sk-proj)ELEVEN_LABS_API_KEY
Replicater8_*REPLICATE_API_TOKEN
SupabaseURL + eyJ*(JWT)SUPABASE_URL、SUPABASE_ANON_KEY、SUPABASE_SERVICE_ROLE_KEY
Redditclient_id + secret 配对REDDIT_CLIENT_ID、REDDIT_CLIENT_SECRET
GitHubghp_* 或 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 Webhookwhsec_*STRIPE_WEBHOOK_SECRET
TwilioSK* + Account SIDTWILIO_API_KEY、TWILIO_ACCOUNT_SID
SendGridSG.*SENDGRID_API_KEY
AWSAKIA* + secretAWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY
PostHogphc_*POSTHOG_API_KEY、NEXT_PUBLIC_POSTHOG_KEY

解析凭据文件

读取用户的访问文件时,请按照以下规则提取密钥:

# Python parsing logic
import re
from pathlib import Path

def parse_credentials_file(file_path: str) -> dict[str, str]:
    """Parse various credential file formats."""
    content = Path(file_path).expanduser().read_text()
    credentials = {}

    # Pattern matching for known key formats
    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 requires special handling (URL + JWT tokens)
    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 requires special handling (client_id + secret pair)
    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 parsing logic
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 pair
  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 = valid
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 = valid
Render
curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $RENDER_API_KEY" \
  https://api.render.com/v1/services
# 200 = valid
Reddit
# Get OAuth token first
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')
# Non-null token = valid
Replicate
curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Token $REPLICATE_API_TOKEN" \
  https://api.replicate.com/v1/models
# 200 = valid

项目设置工作流

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

步骤 1:索取凭据文件
This project needs the following API keys:
- ANTHROPIC_API_KEY (for Claude)
- SUPABASE_URL and SUPABASE_ANON_KEY

Do you have an access keys file? Please provide the path:
步骤 2:读取并解析
# Read the file
credentials = parse_credentials_file("~/Documents/Access.txt")

# Show what was found
print("Found credentials:")
for key, value in credentials.items():
    masked = value[:8] + "..." + value[-4:]
    print(f"  {key}: {masked}")
步骤 3:验证密钥
Validating credentials...
✓ ANTHROPIC_API_KEY: Valid
✓ REDDIT_CLIENT_ID: Valid
✗ SUPABASE_URL: Not found in file
步骤 4:创建 .env 文件
# Write to project .env
cat > .env << EOF
# Auto-generated from ~/Documents/Access.txt
ANTHROPIC_API_KEY=sk-ant-xxx...
REDDIT_CLIENT_ID=xxx...
REDDIT_CLIENT_SECRET=xxx...
EOF

# Add to .gitignore if not present
echo ".env" >> .gitignore
步骤 5:报告缺失的密钥
Missing credentials that need manual setup:
- SUPABASE_URL: Get from supabase.com/dashboard/project/[ref]/settings/api
- SUPABASE_ANON_KEY: Same location as above

Would you like me to open these URLs?

特定服务设置指南

Reddit(来自 Access.txt)
Found in your access file:
- REDDIT_CLIENT_ID: Y1FgKA...
- REDDIT_CLIENT_SECRET: -QLoYd...

Also needed (add to Access.txt or enter manually):
- REDDIT_USER_AGENT: YourApp/1.0 by YourUsername
Supabase(通常不在文件中)
Supabase credentials are project-specific. Get them from:
https://supabase.com/dashboard/project/[your-ref]/settings/api

Required:
- SUPABASE_URL
- SUPABASE_ANON_KEY
- SUPABASE_SERVICE_ROLE_KEY (for admin operations)

安全规则

  • 绝不将 Access.txt 或其路径提交到 git
  • 绝不记录完整的 API 密钥;务必遮蔽中间字符
  • 务必将 .env 添加到 .gitignore
  • 务必使用环境变量,绝不硬编码密钥
  • 验证密钥后再用于生产环境设置

快速参考

# Check if credentials file exists
ls -la ~/Documents/Access.txt

# Common env var names
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
提示词模板
I need API credentials for this project.

Do you have a centralized access keys file (like ~/Documents/Access.txt)?

If yes, provide the path and I'll:
1. Read and parse your keys
2. Validate they're working
3. Set up your project's .env file
4. Tell you which keys are missing

评论

支持 Markdown