Prompt Security Hardening logo

Prompt Security Hardening

Organization
ed3dai
prompt-security-hardening

Use when writing skills, CLAUDE.md files, agent prompts, or any directives that involve shell commands, environment variables, API credentials, file creation, or git operations - prevents secrets leakage into LLM context, unsafe shell patterns, and credential exposure

Overview

Publishered3dai
Repositoryed3d-plugins
Skill nameprompt-security-hardening
Stars
249
Forks
33
Bundled files
Instructions only
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by ed3dai on GitHub. Read the source before you install it.

Installation

Install the Prompt Security Hardening AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/ed3dai/ed3d-plugins.git /tmp/ed3d-plugins
mkdir -p .claude/skills
cp -r /tmp/ed3d-plugins/plugins/ed3d-extending-claude/skills/prompt-security-hardening .claude/skills/prompt-security-hardening
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Prompt Security Hardening in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Prompt Security Hardening on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Prompt Security Hardening is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Prompt Security Hardening

Your context window is sent to an API provider. Every secret that enters your context is a secret leaked to a third party. This skill defines the security boundaries you operate within.

1. Never Read Secret Values Into Context

When you need to verify an environment variable exists, check its existence without reading its value. The value should never appear in your context window, terminal output, or logs.

bash
# SAFE: check existence without reading value
if [ -z "${STRIPE_SECRET_KEY+x}" ]; then
  echo "STRIPE_SECRET_KEY is not set"
else
  echo "STRIPE_SECRET_KEY is set"
fi

# SAFE: bash 4.2+ (macOS with brew bash, most Linux)
[[ -v STRIPE_SECRET_KEY ]] && echo "set" || echo "not set"

# SAFE: direnv / .envrc-aware check
[[ -v DATABASE_URL ]] && echo "DATABASE_URL is set" || echo "DATABASE_URL is not set"
bash
# DANGEROUS: reads the value into context
echo $STRIPE_SECRET_KEY
printenv STRIPE_SECRET_KEY
echo "Key is: ${STRIPE_SECRET_KEY}"
echo "Preview: ${STRIPE_SECRET_KEY:0:8}..."    # partial values still leak
echo "Length: ${#STRIPE_SECRET_KEY}"            # length leaks entropy info
set | grep STRIPE_SECRET_KEY                    # shows the value
export | grep STRIPE_SECRET_KEY                 # shows the value
env | grep STRIPE_SECRET_KEY                    # shows the value
env | grep -q '^VAR='                           # -q is safe for existence check,
                                                # but omitting -q leaks the value

Partial values and lengths are also leaks. An 8-character prefix of a Stripe key narrows the search space enormously. The length of a secret confirms its format. Reveal nothing.

Grepping shell config files (~/.zshrc, ~/.bashrc, ~/.envrc) for a variable name will show the full export line including the value. Check for the variable name's presence without showing the line content:

bash
# SAFE: check if the variable is configured in shell config (shows nothing about value)
grep -qc 'ANTHROPIC_API_KEY' ~/.zshrc && echo "found in .zshrc" || echo "not in .zshrc"

# DANGEROUS: shows the full export line, including the secret value
grep 'ANTHROPIC_API_KEY' ~/.zshrc
grep -n 'ANTHROPIC_API_KEY' ~/.zshrc

2. Never Hardcode Secrets in Generated Code or Directives

When writing skills, agents, or CLAUDE.md files that include code examples, use environment variable references. When generating code for users, always reference environment variables or secret managers.

python
# SAFE
stripe.api_key = os.environ["STRIPE_SECRET_KEY"]

# DANGEROUS: reproduces training data patterns
stripe.api_key = "sk_live_..."
stripe.api_key = "sk_test_..."  # test keys are still keys
yaml
# SAFE: docker-compose referencing env vars
environment:
  DATABASE_URL: ${DATABASE_URL}

# DANGEROUS: inline credentials
environment:
  DATABASE_URL: postgresql://admin:password123@db:5432/myapp

Placeholder values like changeme, your-api-key-here, replace-me, or postgres://user:password@localhost/db are not acceptable. They train developers to put real values in the same location, and they appear as false positives in secret scanners, desensitizing teams to alerts. Use empty values (STRIPE_SECRET_KEY=) or environment variable references as the primary pattern.

For .env.example or template files that get committed:

bash
# SAFE: empty values in committed templates
STRIPE_SECRET_KEY=
DATABASE_URL=
JWT_SECRET=

# DANGEROUS: fake credentials that normalize the pattern
STRIPE_SECRET_KEY=sk_test_your_key_here
DATABASE_URL=postgres://user:password@localhost:5432/myapp
JWT_SECRET=change-this-to-something-secure

3. Set Restrictive File Permissions on Sensitive Files

When creating files that contain or will contain secrets (.env, .envrc, config files, key files), set restrictive permissions immediately.

bash
# Create with restrictive permissions from the start
touch .env && chmod 600 .env
# Then populate the file

# SSH keys require restrictive permissions to function
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

# Application secret files
chmod 600 /etc/myapp/secrets.conf

Default file creation mode (typically 644) makes files world-readable. SSH will refuse to use a key with open permissions, but .env files and config files have no such guardrail.

4. Verify .gitignore Before Creating Secret-Bearing Files

Before creating .env, .envrc, or any file that will contain secrets, verify the gitignore rules will exclude it. If they won't, add the rule first.

bash
# SAFE: check first, then create
git check-ignore -v .env || echo ".env" >> .gitignore
touch .env && chmod 600 .env

# Also check for .envrc (direnv)
git check-ignore -v .envrc || echo ".envrc" >> .gitignore

This applies to any file that will hold credentials: .env, .envrc, secrets.conf, credentials.json, key files, MCP configuration with embedded tokens.

5. Keep Secrets Out of URLs and Process-Visible Arguments

Tokens in URLs get logged in server access logs, proxy logs, and browser history. Tokens in command-line arguments are visible to other users via ps aux.

bash
# SAFE: token in header, not URL
curl -H "Authorization: Bearer ${API_TOKEN}" https://api.example.com/data

# DANGEROUS: token in URL query parameter (logged in server logs)
curl "https://api.example.com/data?api_key=${API_TOKEN}"

For git operations, avoid embedding tokens in clone URLs:

bash
# DANGEROUS: token in URL, persists in .git/config and shell history
git clone "https://${GITHUB_TOKEN}@github.com/org/repo.git"

# SAFER: use credential helper or environment-based auth
GIT_ASKPASS=$(mktemp) && chmod 700 "$GIT_ASKPASS"
printf '#!/bin/sh\necho "${GITHUB_TOKEN}"' > "$GIT_ASKPASS"
GIT_ASKPASS="$GIT_ASKPASS" git clone https://github.com/org/repo.git
rm "$GIT_ASKPASS"

# SAFER: configure credential helper
git config --global credential.helper store
echo "https://oauth2:${GITHUB_TOKEN}@github.com" | git credential-store store
git clone https://github.com/org/repo.git

When a token must be passed as an argument and there is no header/stdin alternative, use process substitution to limit exposure:

bash
# Reduces exposure window via process substitution
curl -H @<(echo "Authorization: Bearer ${API_TOKEN}") https://api.example.com/data

6. Sanitize External Input in Shell Commands

When constructing shell commands from file contents, tool results, or user-provided values, always quote variables and validate input.

bash
# DANGEROUS: unquoted variable, metacharacter injection
FILENAME=$(some_tool_output)
cat $FILENAME

# SAFE: quoted
cat "$FILENAME"

# DANGEROUS: user input interpolated into command
USER_INPUT="$1"
find . -name $USER_INPUT

# SAFE: quoted and validated
USER_INPUT="$1"
if [[ ! "$USER_INPUT" =~ ^[a-zA-Z0-9._-]+$ ]]; then
  echo "Invalid input" >&2
  exit 1
fi
find . -name "$USER_INPUT"

For SQL in shell scripts, use parameterized queries:

bash
# DANGEROUS: string interpolation
psql -c "SELECT * FROM users WHERE name = '$USERNAME'"

# SAFE: psql variable binding
psql --variable="username=$USERNAME" -c "SELECT * FROM users WHERE name = :'username'"

7. Guard Against Context Contamination From Files

When you read a file, its contents enter your context window and are sent to the API provider. Before reading any file, evaluate whether it might contain secrets.

Files likely to contain secrets — read with extreme caution or avoid entirely:

  • .env, .envrc, *.env.*
  • credentials.json, secrets.*, *-key.pem
  • MCP configuration files with env blocks
  • Docker .env files
  • ~/.aws/credentials, ~/.netrc, ~/.npmrc with tokens

When debugging configuration issues, check file existence and structure without reading secret values:

bash
# SAFE: check structure without reading values
wc -l .env                           # line count
grep -c '=' .env                     # count of key=value pairs
grep '^[A-Z_]*=' .env | cut -d= -f1 # list keys only, not values
stat .env                            # file metadata

Applying This Skill to Directives

When writing skills, CLAUDE.md files, or agent prompts:

  1. Code examples in directives must use environment variable references, not placeholder secrets
  2. Shell examples that check configuration must use existence checks, not value reads
  3. Workflow steps involving credentials must specify the safe pattern explicitly — if you leave it to default behavior, the unsafe pattern will be used inconsistently
  4. File creation steps must include permission setting and gitignore verification
  5. Never instruct an agent to read a secrets file to verify its contents — instruct it to verify structure or key names only

Quick Reference

NeedSafe PatternDangerous Pattern
Check env var exists[ -z "${VAR+x}" ] or [[ -v VAR ]]echo $VAR, printenv VAR
Use credential in codeos.environ["KEY"]key = "sk_live_..."
Create secret filetouch f && chmod 600 fecho "secret" > f (644)
Pre-commit safetygit check-ignore -v .envCreate .env and hope
API authentication-H "Authorization: Bearer $TOKEN"?api_key=$TOKEN in URL
Git clone with tokenCredential helper or GIT_ASKPASShttps://token@github.com
Verify file configgrep '^KEY=' f | cut -d= -f1cat f or source f
Shell variable use"$VAR" (quoted)$VAR (unquoted)

Frequently asked questions

What does the Prompt Security Hardening AI skill do?

Use when writing skills, CLAUDE.md files, agent prompts, or any directives that involve shell commands, environment variables, API credentials, file creation, or git operations - prevents secrets leakage into LLM context, unsafe shell patterns, and credential exposure

Why use Prompt Security Hardening on TypingMind?

Because you install it once and use it with any model. Prompt Security Hardening is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Prompt Security Hardening in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/ed3dai/ed3d-plugins/tree/main/plugins/ed3d-extending-claude/skills/prompt-security-hardening. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Prompt Security Hardening?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Prompt Security Hardening?

As many as you like. As long as a model supports skills, you can use Prompt Security Hardening with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Prompt Security Hardening AI skill free?

It is published on GitHub by ed3dai. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇