npx claudepluginhub joaquimscosta/arkhe-claude-plugins --plugin devtoolsThis skill uses the workspace's default tool permissions.
Interactive setup for SOPS + age encryption. Detects current state and guides through configuration.
Encrypts .env files using SOPS + age by converting dotenv to YAML to avoid SOPS bug #1435. Auto-detects unencrypted files in sops-setup projects.
Manages full lifecycle of secrets and environment variables: decides placement (constant, .env, CI secret, env var), scaffolds .env.example/.gitignore, add/update/rotate/remove/migrate/audit/provision across envs. Language-agnostic.
Manages configs across dev/staging/prod with .env files, Kubernetes ConfigMaps/Secrets, AWS SSM. Audits values, encrypts secrets via sops, validates schemas, detects drift, enables promotion workflows.
Share bugs, ideas, or general feedback.
Interactive setup for SOPS + age encryption. Detects current state and guides through configuration.
Important: This skill uses YAML format for encrypted files (not dotenv) because SOPS has a known bug (#1435) where the dotenv store corrupts backslash and \n sequences on decrypt. A helper script handles dotenv↔YAML conversion transparently.
Run the detection script to understand current state:
python3 ${CLAUDE_SKILL_DIR}/scripts/detect_sops.py <project-root>
Run the detector on the project root:
python3 ${CLAUDE_SKILL_DIR}/scripts/detect_sops.py <project-root>
Summarize findings — show a status table:
| Component | Status | Detail |
|---|---|---|
| sops binary | installed/missing | version, path |
| age binary | installed/missing | version, path |
| age key | exists/missing | public key (truncated) |
| .sops.yaml | exists/missing | # of authorized keys |
| .env files | N found | list of filenames |
| encrypted files | N found | list of *.enc.yaml files |
| .gitignore | ok/needs update | env ignored, enc.yaml not ignored |
Walk through each missing component. Skip steps where detection shows everything is already configured.
Install tools (if tools.sops.installed or tools.age.installed is false):
os field:
brew install sops ageGenerate age key (if age_key.exists is false):
mkdir -p ~/.config/sops/ageage-keygen -o ~/.config/sops/age/keys.txtchmod 600 ~/.config/sops/age/keys.txtGenerate backup key (recommended):
AskUserQuestion — offer to create an offline backup key for disaster recoveryage-keygen 2>&1 | tee /dev/stderr | grep "public key:" | awk '{print $NF}'
Display BOTH the public key AND the full output (which includes the private key).
Tell user: Copy the entire output (including the private key line starting with AGE-SECRET-KEY-) to a password manager or secure offline storage. This is your recovery key..sops.yaml alongside the machine keyCreate .sops.yaml (if project.sops_yaml.exists is false):
.sops.yaml with machine key + backup key (if generated):
creation_rules:
- path_regex: (^|/)\.env\.[^/]+\.enc\.yaml$
age: >-
<machine-public-key>,
<backup-public-key>
.sops.yaml already exists but is missing this machine's key, offer to add itSet up .gitattributes for diff-friendly encrypted files:
.gitattributes:
*.enc.yaml diff=sopsdiffer
git config diff.sopsdiffer.textconv "sops decrypt"
git diff show decrypted content for encrypted filesUpdate .gitignore (if needed):
.env* patterns are ignored (secrets must not be committed in plaintext)*.enc.yaml is NOT ignored (encrypted files should be committed)Encrypt files (if project.env_files is non-empty):
AskUserQuestion (multiSelect: true) — show detected .env* filespython3 ${CLAUDE_SKILL_DIR}/scripts/dotenv_yaml.py to-yaml <file> > <file>.enc.yaml.tmp
sops --encrypt <file>.enc.yaml.tmp > <file>.enc.yaml
rm <file>.enc.yaml.tmp
Example: .env.local → .env.local.enc.yamlConfirmation summary — show table of all actions taken:
| Step | Action | Result |
|------|--------|--------|
| Tools | sops 3.9.4, age 1.2.0 | installed |
| Key | Machine key generated | age1abc...def |
| Key | Backup key generated | age1xyz...uvw (save offline!) |
| Permissions | chmod 600 keys.txt | done |
| Config | .sops.yaml created | 2 keys authorized |
| Git | .gitattributes updated | sopsdiffer configured |
| Git | .gitignore updated | .env* ignored |
| Encrypt | .env.local → .env.local.enc.yaml | done |
## Next Steps
- Commit .sops.yaml, .gitattributes, and *.enc.yaml files to git
- On another machine: clone, install sops+age, place age key, run /devtools:sops-decrypt
- To add another machine: /devtools:sops-add-key
- To encrypt after editing .env: /devtools:sops-encrypt
- To decrypt after pulling: /devtools:sops-decrypt
AskUserQuestion for every decision. Do not assume user preferences.--input-type dotenv. Use the dotenv_yaml.py helper for conversion.