credentials

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Credentials Management Skill

凭证管理技能

Load with: base.md
For securely loading API keys from a centralized access file and configuring project environments.

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

Credentials File Discovery

凭证文件发现

REQUIRED: When a project needs API keys, ask the user:
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.
必填:当项目需要API密钥时,询问用户:
我需要[服务]的API凭证。你是否有集中式访问密钥文件?

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

Default Locations to Check

默认检查位置

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

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

Supported File Formats

支持的文件格式

The credentials file can use any of these formats:
凭证文件可使用以下任意格式:

Format 1: Colon-separated

格式1:冒号分隔

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

Format 2: Key=Value

格式2:键=值

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

Format 3: Mixed/Informal

格式3:混合/非正式

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

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

Key Identification Patterns

密钥识别规则

Use these patterns to identify keys in the file:
ServicePatternEnv Variable
OpenAI
sk-proj-*
or
sk-*
OPENAI_API_KEY
Claude/Anthropic
sk-ant-*
ANTHROPIC_API_KEY
Render
rnd_*
RENDER_API_KEY
Eleven Labs
sk_*
(not sk-ant/sk-proj)
ELEVEN_LABS_API_KEY
Replicate
r8_*
REPLICATE_API_TOKEN
SupabaseURL +
eyJ*
(JWT)
SUPABASE_URL
,
SUPABASE_ANON_KEY
,
SUPABASE_SERVICE_ROLE_KEY
Redditclient_id + secret pair
REDDIT_CLIENT_ID
,
REDDIT_CLIENT_SECRET
GitHub
ghp_*
or
github_pat_*
GITHUB_TOKEN
Vercel
*_*
(from vercel.com)
VERCEL_TOKEN
Stripe (Test)
sk_test_*
,
pk_test_*
STRIPE_SECRET_KEY
,
STRIPE_PUBLISHABLE_KEY
Stripe (Live)
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*
+ secret
AWS_ACCESS_KEY_ID
,
AWS_SECRET_ACCESS_KEY
PostHog
phc_*
POSTHOG_API_KEY
,
NEXT_PUBLIC_POSTHOG_KEY

使用以下规则识别文件中的密钥:
服务规则环境变量
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
SupabaseURL +
eyJ*
(JWT)
SUPABASE_URL
,
SUPABASE_ANON_KEY
,
SUPABASE_SERVICE_ROLE_KEY
Redditclient_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*
+ secret
AWS_ACCESS_KEY_ID
,
AWS_SECRET_ACCESS_KEY
PostHog
phc_*
POSTHOG_API_KEY
,
NEXT_PUBLIC_POSTHOG_KEY

Parsing Credentials File

凭证文件解析

When reading the user's access file, extract keys using these rules:
python
undefined
读取用户的访问文件时,使用以下规则提取密钥:
python
undefined

Python parsing logic

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
// 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;
}

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
// 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;
}

Validation Commands

验证命令

After extracting keys, validate them:
提取密钥后,进行验证:

OpenAI

OpenAI

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

200 = valid

200 = 有效

undefined
undefined

Anthropic/Claude

Anthropic/Claude

bash
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
bash
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

200 = 有效

undefined
undefined

Render

Render

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

200 = valid

200 = 有效

undefined
undefined

Reddit

Reddit

bash
undefined
bash
undefined

Get OAuth token first

先获取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')
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

非空令牌 = 有效

undefined
undefined

Replicate

Replicate

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

200 = valid

200 = 有效


---

---

Project Setup Workflow

项目设置流程

When initializing a project that needs API keys:
初始化需要API密钥的项目时:

Step 1: Ask for Credentials File

步骤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:
该项目需要以下API密钥:
- ANTHROPIC_API_KEY(用于Claude)
- SUPABASE_URL 和 SUPABASE_ANON_KEY

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

Step 2: Read and Parse

步骤2:读取并解析

python
undefined
python
undefined

Read the file

读取文件

credentials = parse_credentials_file("~/Documents/Access.txt")
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}")
undefined
print("已找到的凭证:") for key, value in credentials.items(): masked = value[:8] + "..." + value[-4:] print(f" {key}: {masked}")
undefined

Step 3: Validate Keys

步骤3:验证密钥

Validating credentials...
✓ ANTHROPIC_API_KEY: Valid
✓ REDDIT_CLIENT_ID: Valid
✗ SUPABASE_URL: Not found in file
正在验证凭证...
✓ ANTHROPIC_API_KEY:有效
✓ REDDIT_CLIENT_ID:有效
✗ SUPABASE_URL:文件中未找到

Step 4: Create .env File

步骤4:创建.env文件

bash
undefined
bash
undefined

Write to project .env

写入项目.env文件

cat > .env << EOF
cat > .env << EOF

Auto-generated from ~/Documents/Access.txt

从~/Documents/Access.txt自动生成

ANTHROPIC_API_KEY=sk-ant-xxx... REDDIT_CLIENT_ID=xxx... REDDIT_CLIENT_SECRET=xxx... EOF
ANTHROPIC_API_KEY=sk-ant-xxx... REDDIT_CLIENT_ID=xxx... REDDIT_CLIENT_SECRET=xxx... EOF

Add to .gitignore if not present

如果.gitignore中没有则添加

echo ".env" >> .gitignore
undefined
echo ".env" >> .gitignore
undefined

Step 5: Report Missing Keys

步骤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?

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

是否需要我打开这些链接?

Service-Specific Setup Guides

特定服务设置指南

Reddit (from Access.txt)

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
在你的访问文件中找到:
- REDDIT_CLIENT_ID: Y1FgKA...
- REDDIT_CLIENT_SECRET: -QLoYd...

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

Supabase (typically not in file)

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)

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

必填项:
- SUPABASE_URL
- SUPABASE_ANON_KEY
- SUPABASE_SERVICE_ROLE_KEY(用于管理员操作)

Security Rules

安全规则

  • NEVER commit Access.txt or its path to git
  • NEVER log full API keys - always mask middle characters
  • ALWAYS add
    .env
    to
    .gitignore
  • ALWAYS use environment variables, never hardcode keys
  • VALIDATE keys before using them in production setup

  • 绝对不要将Access.txt或其路径提交到git
  • 绝对不要记录完整的API密钥 - 始终隐藏中间字符
  • 务必将.env添加到.gitignore
  • 务必使用环境变量,绝不要硬编码密钥
  • 务必在生产环境设置前验证密钥

Quick Reference

快速参考

bash
undefined
bash
undefined

Check if credentials file exists

检查凭证文件是否存在

ls -la ~/Documents/Access.txt
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
undefined
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
undefined

Prompt Template

提示模板

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
我需要该项目的API凭证。

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

如果有,请提供路径,我将:
1. 读取并解析你的密钥
2. 验证其有效性
3. 设置项目的.env文件
4. 告知你缺失的密钥