Mastermind secrets — manage org-scoped API keys and secrets consumed by agents. Store, rotate, list, and audit secrets without exposing values in logs or state files.
Scanned 9/10/2026
Install to Claude Code
npx -y skills add monoes/monomind --skill mastermind-secrets --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mastermind Secrets?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/monoes-mastermind-secrets)More formats (shields.io, HTML) on the badges page.
---
name: mastermind-secrets
description: Mastermind secrets — manage org-scoped API keys and secrets consumed by agents. Store, rotate, list, and audit secrets without exposing values in logs or state files.
type: domain-skill
default_mode: confirm
---
# Mastermind Secrets
This skill is invoked by `mastermind:secrets` or directly via `/mastermind:secrets`.
---
## Inputs
- `brain_context`: BRAIN CONTEXT block
- `org_name`: org to manage secrets for
- `action`: list | set | rotate | revoke | audit
- `secret_name`: name/key of the secret (e.g. `OPENAI_API_KEY`, `SLACK_WEBHOOK`)
- `secret_value`: value to store (only ever passed as env var reference, NEVER hardcoded)
- `provider`: local | env | vault (default: local)
- `caller`: command | master
---
## Step 0 — Brain Load (standalone only)
If `caller` is not "command", load brain context following mastermind-protocol/SKILL.md Brain Load Procedure with namespace: `ops`.
---
## SECURITY RULES (always enforced)
- NEVER print secret values to stdout
- NEVER store secret values in state files (store only masked references: `sk-ant-***...***`)
- NEVER commit secrets to git
- Secrets passed as `secret_value` MUST come from env vars (`$MY_KEY`), NOT inline strings
---
## Step 1 — Load Secrets Registry
The secrets registry stores **metadata only** (name, provider, masked hint, rotation date):
```bash
secretsFile=".monomind/orgs/${org_name}-secrets.json"
[ ! -f "$secretsFile" ] && echo '{"secrets":[]}' > "$secretsFile"
```
Actual secret values live in:
- `local`: `.monomind/orgs/.secrets/<org_name>/<name>` (chmod 600, gitignored)
- `env`: environment variable `ORG_<ORG_NAME_UPPER>_<SECRET_NAME_UPPER>`
---
## Step 2 — Execute Action
### list (default)
Show all registered secrets for this org (metadata only, masked values):
```bash
jq -r '
(.secrets // [])[] |
"[\(.name)] provider=\(.provider) hint=\(.masked_hint // "***") set=\(.set_at // "unknown") rotated=\(.rotated_at // "never")"
' "$secretsFile" 2>/dev/null || echo "No secrets registered."
```
Render as:
```
SECRETS — org: <org_name>
──────────────────────────────────────────────
NAME PROVIDER VALUE HINT SET ROTATED
ANTHROPIC_API_KEY local sk-ant-***... 2 days ago —
SLACK_WEBHOOK env https://hooks 1 week ago —
GITHUB_TOKEN local ghp_***... 3 days ago 1 day ago
```
### set
Store a secret value. Always source from env var:
```bash
# Validate secret_name (alphanumeric + underscore only)
echo "$secret_name" | grep -qE '^[A-Z][A-Z0-9_]{0,63}$' || { echo "ERROR: secret_name must be uppercase letters, digits, underscores only."; exit 1; }
# Create secure storage dir
secretDir=".monomind/orgs/.secrets/${org_name}"
mkdir -p "$secretDir"
chmod 700 "$secretDir"
# Write value from env var reference — NEVER inline
if [ -z "${secret_value}" ]; then
echo "ERROR: Pass the secret value as an env var: secret_value=\$MY_VAR /mastermind:secrets --action set"
exit 1
fi
secretFile="${secretDir}/${secret_name}"
printf '%s' "$secret_value" > "$secretFile"
chmod 600 "$secretFile"
# Store masked hint (first 6 chars + ***)
hint="${secret_value:0:6}***...${secret_value: -3}"
# Register in secrets metadata
tmp="${secretsFile}.tmp"
jq --arg name "$secret_name" \
--arg provider "${provider:-local}" \
--arg hint "$hint" \
--arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'.secrets = [(.secrets // [])[] | select(.name != $name)] +
[{"name":$name,"provider":$provider,"masked_hint":$hint,"set_at":$ts}]' \
"$secretsFile" > "$tmp" && mv "$tmp" "$secretsFile"
echo "Secret $secret_name stored (provider: ${provider:-local})"
```
Ensure `.monomind/orgs/.secrets/` is in `.gitignore`:
```bash
grep -q '.monomind/orgs/.secrets' .gitignore 2>/dev/null || echo '.monomind/orgs/.secrets/' >> .gitignore
```
### rotate
Generate a new value from env var and update:
```bash
# Same as set but also records rotated_at
tmp="${secretsFile}.tmp"
jq --arg name "$secret_name" --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'.secrets = [(.secrets // [])[] | if .name == $name then .rotated_at = $ts | .set_at = $ts else . end]' \
"$secretsFile" > "$tmp" && mv "$tmp" "$secretsFile"
# Then re-run the set logic above with new value
```
### revoke
Remove secret value and registry entry:
```bash
rm -f ".monomind/orgs/.secrets/${org_name}/${secret_name}"
tmp="${secretsFile}.tmp"
jq --arg name "$secret_name" '.secrets = [(.secrets // [])[] | select(.name != $name)]' \
"$secretsFile" > "$tmp" && mv "$tmp" "$secretsFile"
echo "Secret $secret_name revoked."
```
### audit
Show which agents reference each secret in their adapter_config or responsibilities:
```bash
orgFile=".monomind/orgs/${org_name}.json"
echo "=== SECRET USAGE AUDIT — org: $org_name ==="
jq -r '(.roles // [])[] | "\(.id): \((.responsibilities // []) | join(", "))"' "$orgFile" | \
while IFS=: read -r role resp; do
refs=$(jq -r '(.secrets // [])[].name' "$secretsFile" | while read -r sname; do
echo "$resp" | grep -q "$sname" && echo " → $sname"
done)
[ -n "$refs" ] && echo "$role$refs"
done
echo "(Audit checks responsibilities text only — review agent prompts manually for additional references)"
```
---
## How Agents Access Secrets
Agents spawned by the boss should read secrets via:
```bash
# Read from local storage (not env):
secret=$(cat ".monomind/orgs/.secrets/${orgName}/${SECRET_NAME}" 2>/dev/null)
[ -z "$secret" ] && secret="${!SECRET_NAME}" # Fallback to env var
# Use in API calls:
curl -H "Authorization: Bearer $secret" ...
```
Never store secret values in memory namespace or state files.
---
## Step 3 — Return Output
```yaml
domain: ops
status: complete
action: <action>
org: <org_name>
secret_name: <name if applicable>
secrets_count: <N>
```
---
## Step 4 — Brain Write (standalone only)
If `caller` is not "command", follow mastermind-protocol/SKILL.md Brain Write Procedure for domain `ops`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!