credentials
Opinionated project initialization for Claude Code. Security-first, spec-driven, AI-native.
448 stars37 forksUpdated Jan 20, 2026
npx skills add https://github.com/alinaqi/claude-bootstrap --skill credentialsSKILL.md
Credentials Management Skill
Load with: base.md
For securely loading API keys from a centralized access file and configuring project environments.
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.
Default Locations to Check
~/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
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
RENDER_API_KEY=rnd_xxxxx
OPENAI_API_KEY=sk-proj-xxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxx
Format 3: Mixed/Informal
Reddit api access:
client id Y1FgKALKmb6f6UxFtyMXfA
and secret is -QLoYdxMqOJkYrgk5KeGPa6Ps6vIiQ
Key Identification Patterns
Use these patterns to identify keys in the file:
| Service | Pattern | Env 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 |
| Supabase | URL + eyJ* (JWT) | SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY |
| client_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 |
Parsing Credentials File
When reading the user's access file, extract keys using these rules:
# 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)
...
Repository Stats
Stars448
Forks37
LicenseMIT License