blindfold
A security wrapper for handling API keys and credentials without exposing them in chat or files.
Install
mkdir -p .claude/skills/blindfold && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/18124" && unzip -o skill.zip -d .claude/skills/blindfold && rm skill.zipInstalls to .claude/skills/blindfold
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use Blindfold (Terminal 3 TDX enclave wrapper) to seal and use API keys safely. Invoke when the user mentions sealing/sealing a key, asks "how do I protect my API key", pastes a credential into chat, or asks for help with secrets in this project. Always prefer the no-paste workflow — propose commands the user runs in their own terminal, verify by fingerprint, never write keys to files.Key capabilities
- →Propose commands for users to seal API keys in their terminal
- →Verify sealed keys by fingerprint, not by value
- →Generate code that fetches provider keys from Terminal 3 just-in-time
- →Propose .env cleanup after successful key sealing
- →Troubleshoot Blindfold issues using diagnostic commands
How it works
The skill guides the user to seal API keys using Blindfold, a Terminal 3 TDX-enclave wrapper, by proposing terminal commands and verifying the sealing process without exposing the key value. It also provides code templates for using sealed keys.
Inputs & outputs
When to use blindfold
- →Seal API keys for environment use
- →Protect sensitive credentials
- →Set up secure vaulting
- →Handle project-specific secrets safely
About this skill
Blindfold skill — the rulebook
You're working in (or with) Blindfold — a Terminal 3 TDX-enclave wrapper that keeps AI-agent API keys un-leakable. Read current_status.md, process.md, usage_by_claude.md, and vicky.md for context; this file is the agent-side rulebook that decides how you behave.
When to invoke this skill
- User pastes (or is about to paste) any API key, password, token, or credential.
- User asks "how do I use [provider]" in a way that implies handling a key.
- User asks about
.env, sealing, vaulting, or "where do I put my key". - You're about to write code that would read
process.env.SOME_PROVIDER_KEYfor an outbound call. - User says "use Blindfold" or "seal it" or "make this safe".
- User has no Terminal 3 tenant yet ("how do I start", "I don't have an account/DID",
doctorshows creds MISSING) → point them at self-serveblindfold signup(see below).
The four rules (mirror of usage_by_claude.md §3)
- R1 — no-paste-into-chat. If a new secret needs sealing, propose the command (
blindfold register --name <KV_KEY>) for the user to run in their own terminal. Do NOT ask them to paste the value into chat. Only useprintf 'VALUE' | ...from chat as a fallback, and only after the user explicitly says "go ahead from here". - R2 — verify by fingerprint, never by value. To check what's sealed:
blindfold sealed. To check what's in.env:npm run env:fingerprint. To check a specific sealed key matches an expected value:npx tsx scripts/test-v5-release.ts <secret_name>(printsfirst3…last2 (N bytes), never plaintext). Ask the user to paste the output of those commands — that's safe. - R3 — code uses release-broker pattern. Any code you write that needs a provider key must fetch it from T3 just-in-time via
tenant.contracts.execute("blindfold-proxy", { version: CONTRACT_VERSION, functionName: "release-to-tenant", input: { secret_key: "<name>" } }), use it inside atry { … } finally { /* dropped */ }, and never referenceprocess.env.<provider>_API_KEY. Reference templates:examples/grok-via-blindfold.ts(HTTPS) andscripts/smtp-with-blindfold.ts(non-HTTP). - R4 — propose
.envcleanup after every successful seal. The sealed copy is canonical; the.envcopy is leak surface. Exception:T3N_API_KEYitself stays in.env— it's the root credential, can't be sealed (chicken-and-egg).
Command kit (every output is safe to share)
| Command | Purpose | Safe to paste output? |
|---|---|---|
blindfold signup --email <addr> | self-serve: mint a new testnet tenant (key local, email-verified) | ⚠ tell user to run it (prompts for the emailed code) |
blindfold doctor | mode + cred presence (yes/no) | ✅ |
blindfold verify | T3 round-trip status | ✅ |
blindfold credit | tenant token/credit balance | ✅ |
blindfold attest [--pin] | verify enclave TDX attestation; --pin gates seal/proxy on the code measurement | ✅ |
blindfold login | store tenant creds in ~/.blindfold (OS keychain for the key) — works from any dir | ⚠ tell user to run it (prompts for key) |
blindfold whoami | show config path, tenant, env, key source (never the value) | ✅ |
blindfold logout | remove stored creds (keychain + ~/.blindfold/config.json) | ✅ |
blindfold sealed | sealed-keys ledger (metadata only, LOCAL) | ✅ |
blindfold audit | reconcile ledger against the ENCLAVE — what's actually usable now | ✅ |
blindfold status | one-glance: mode, tenant health, sealed list | ✅ |
npm run env:fingerprint | .env lines as KEY = first3…last2 (N bytes) | ✅ |
npx tsx scripts/test-v5-release.ts <name> | fingerprint of the released value | ✅ |
npm run dashboard | live HTML dashboard at http://127.0.0.1:8799 | n/a (UI) |
blindfold register --name <K> | interactive seal (no echo) | ⚠ tell user to run in their terminal |
printf 'V' | blindfold register --name <K> | piped seal (value briefly in this process) | ⚠ only if user already pasted value |
blindfold delete --name <K> [--yes] | remove a sealed secret (empties enclave + ledger, re-chained) | ⚠ destructive — confirm first; tell user to run it |
Seal once, use forever (no re-seal per session)
A sealed key lives in the Terminal 3 enclave, not in a session, terminal, or
machine. So the answer to "do I need to re-seal in a new session?" is no —
any new session can use an already-sealed key directly. Don't propose re-running
register for a key that's already sealed.
To use already-sealed keys, a session needs three persistent things (all survive across sessions — none require re-sealing):
- Tenant creds —
T3N_API_KEY+DID. These authenticate to the enclave and are what release/proxy require. Ways to provide them:blindfold signup --email [email protected](self-serve, the fastest start): mints a brand-new Terminal 3 testnet tenant with no manual token claim — generates the tenant key locally (→ OS keychain, never printed), verifies the email by an emailed code, self-admits, and mints welcome credits. One email binds to one tenant. Use this when the user has no tenant yet.- Repo
.env(dev). Exception to R4: they stay in.env; see R4. blindfold login(v0.2+, product path, for an EXISTING tenant): stores DID + settings in~/.blindfold/config.jsonand the tenant key in the OS keychain (v0.3; macOS Keychain / Linux secret-tool) — so the CLI works from any directory and the key isn't a readable file. Precedence:process.env> repo.env>~/.blindfold. State (ledger/usage/egress) also lives in~/.blindfold.
- Egress already granted for the host you'll call (
blindfold grant --host <host>). The grant is per-tenant and persistent. - The proxy running if using the HTTP path:
blindfold proxy(listens on127.0.0.1:8787). Point the tool at it with base URLhttp://127.0.0.1:8787/v1and key__BLINDFOLD__. (Code paths use the release-broker instead — see R3.) On a shared machine, runproxy --auth: it mints a per-session token so only the wrapped agent (not any co-resident process) can use the proxy — pass it viaBLINDFOLD_PROXY_TOKEN/wrap(client, { token }), orcurl -H "x-blindfold-token: <token>".
Before assuming a key is usable, run audit, not sealed. sealed only
reads the LOCAL ledger; audit reconciles it against the enclave (the source of
truth) and marks each key present (usable now) or MISSING (needs a re-seal).
A key in sealed but MISSING in audit is the only case that needs
re-sealing.
What to do, by scenario
"I'm new / I don't have a Terminal 3 tenant yet" (onboarding)
Blindfold is published on npm and onboarding is self-serve — no manual token claim. Propose (the user runs it in their own terminal):
npm i -g @fiscalmindset/blindfold
blindfold signup --email [email protected]
signup generates the tenant key locally (→ OS keychain, never printed),
verifies the email by an emailed code, self-admits a funded testnet tenant,
and mints welcome credits. Then confirm with blindfold doctor (should show the
tenant active) and blindfold credit (token balance). After that they can
register and use keys. Notes: testnet-only; one email = one tenant (Gmail
+aliases give fresh identities); if the email is already registered, use
blindfold login with that tenant's key instead.
"I want to seal my Stripe key" (or any new credential)
Don't ask for the value. Respond with:
In your own terminal, run:
blindfold register --name stripe_api_keyIt'll prompt for the value with input hidden (no echo, no shell history). Paste your
sk_live_…there, press Enter. Once done, paste me the output ofblindfold sealedso I can verify it landed in the right place.
"I sealed the wrong thing / want to remove a sealed secret"
Use blindfold delete --name <secret> (alias remove). It empties the value in
the enclave (current tenant) and removes the entry from the local ledger,
re-chaining so blindfold audit still passes (the old ledger is backed up).
Propose it for the user to run; it prompts for confirmation (--yes skips).
Critical: if the value they mis-sealed was a real credential (e.g. they put
an API key in the --name field), deleting it here does NOT un-expose it — tell
them to revoke/rotate that key at its provider, then re-seal correctly
(--name is a short label; the value is prompted hidden).
"Seal / use a webhook URL (Discord, Slack, …)"
A webhook is special: the secret is the entire URL (e.g.
https://discord.com/api/webhooks/<id>/<token>), POSTed with no auth header.
Seal it like any secret (register --name webhook_discord_url --from-env …),
then two ways to use it:
- Release path (works everywhere): inject into one command —
blindfold use --name webhook_discord_url --as HOOK -- sh -c 'curl -X POST -H "Content-Type: application/json" -d "{\"content\":\"hi\"}" "$HOOK"' - Proxy path (agent never holds the URL; contract v0.5.5+): the
webhookscheme substitutes the sealed URL in the URL inside the enclave. There's a/discordprovider — grant egress (grant --host discord.com), run the proxy, and POST a JSON body tohttp://127.0.0.1:8787/discord. Seeexamples/discord-webhook/.
"Add support for an API that isn't a provider yet" (register a new proxy provider)
If the user wants an API Blindfold doesn't list (unlisted paths get a 404 "no
upstream mapping" — deny-by-default), prefer adding a first-class proxy provider
over the release-broker fallback — the proxy path never returns plaintext, so it's
the stronger option. This is pure code (no secret value), so you can do it end to
end; only the final register (plaintext) is handed back to the user.
- Add a ~5-line entry to
packages/blindfold/src/providers.ts— no enclave/Rust change is
Content truncated.
When not to use it
- →Writing a real plaintext key value to any file
- →Logging a value whose origin is process.env.*_API_KEY
- →Generating code that references process.env.<provider>_API_KEY for outbound calls
Limitations
- →Cannot write plaintext key values to files or logs
- →Cannot suggest pasting keys into chat as a default
- →Cannot generate code referencing process.env.<provider>_API_KEY for outbound calls
How it compares
This skill enforces a no-paste workflow for API keys and integrates with a secure enclave for key management, which is more secure than directly pasting credentials into chat or storing them in .env files.
Compared to similar skills
blindfold side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| blindfold (this skill) | 0 | 17d | Caution | Intermediate |
| 1password | 27 | 2mo | Review | Intermediate |
| security-compliance | 19 | 7mo | Review | Advanced |
| information-security-manager-iso27001 | 11 | 7mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
1password
openclaw
Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.
security-compliance
davila7
Guides security professionals in implementing defense-in-depth security architectures, achieving compliance with industry frameworks (SOC2, ISO27001, GDPR, HIPAA), conducting threat modeling and risk assessments, managing security operations and incident response, and embedding security throughout the SDLC.
information-security-manager-iso27001
davila7
Senior Information Security Manager specializing in ISO 27001 and ISO 27002 implementation for HealthTech and MedTech companies. Provides ISMS implementation, cybersecurity risk assessment, security controls management, and compliance oversight. Use for ISMS design, security risk assessments, control implementation, and ISO 27001 certification activities.
cursor-sso-integration
jeremylongshore
Configure SSO and enterprise authentication in Cursor. Triggers on "cursor sso", "cursor saml", "cursor oauth", "enterprise cursor auth", "cursor okta". Use when working with cursor sso integration functionality. Trigger with phrases like "cursor sso integration", "cursor integration", "cursor".
springboot-security
affaan-m
Spring Security best practices for authn/authz, validation, CSRF, secrets, headers, rate limiting, and dependency security in Java Spring Boot services.
django-security
affaan-m
Django security best practices, authentication, authorization, CSRF protection, SQL injection prevention, XSS prevention, and secure deployment configurations.