getsops/sops
Simple and flexible tool for managing secrets
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1d ago
- ✓10 active contributors
- ✓MPL-2.0 licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 64% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/getsops/sops)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/getsops/sops on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: getsops/sops
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/getsops/sops shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 1d ago
- 10 active contributors
- MPL-2.0 licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 64% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live getsops/sops
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/getsops/sops.
What it runs against: a local clone of getsops/sops — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in getsops/sops | Confirms the artifact applies here, not a fork |
| 2 | License is still MPL-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of getsops/sops. If you don't
# have one yet, run these first:
#
# git clone https://github.com/getsops/sops.git
# cd sops
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of getsops/sops and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "getsops/sops(\\.git)?\\b" \\
&& ok "origin remote is getsops/sops" \\
|| miss "origin remote is not getsops/sops (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MPL-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MPL-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is MPL-2.0" \\
|| miss "license drift — was MPL-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/getsops/sops"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
SOPS (Secrets OPerationS) is a command-line tool and Go library for encrypting and decrypting secrets in YAML, JSON, ENV, INI, and BINARY files using cloud KMS providers (AWS KMS, GCP KMS, Azure Key Vault, HuaweiCloud KMS) and local encryption methods (age, PGP). It allows teams to version control encrypted secrets alongside code while keeping plaintext secrets out of repositories. Modular architecture with cryptography providers as separate packages (aes/, age/, azkv/, kms/, pgp/) each containing keysource.go implementations. CLI sits in cmd/sops/main.go with subcommands in cmd/sops/ (decrypt.go, encrypt.go, edit.go, rotate.go, set.go, exec/). Core encryption logic in root-level aes/ package. Configuration driven by .sops.yaml with audit logging via audit/audit.go. Functional tests in Rust (tempfile, serde setup visible in Cargo.toml snippet).
👥Who it's for
DevOps engineers and platform teams who need to manage encrypted secrets in infrastructure-as-code repos, particularly those using Kubernetes, Helm, or other IaC tools that consume YAML/JSON config. Also used by security-conscious development teams deploying to AWS, GCP, or Azure.
🌱Maturity & risk
Production-ready and actively maintained. The codebase shows mature CI/CD setup (GitHub Actions for CLI, CodeQL, linters, releases) with automated builds across multiple platforms (.goreleaser.yaml, release Dockerfiles). Requires Go >= 1.25 indicating recent maintenance. Multiple keysource implementations (aes/, age/, azkv/, kms/, pgp/) and stable Go module versioning (v3) confirm production use.
Low risk for a secrets tool. Single-maintainer risk exists (getsops organization but core contribution patterns suggest small team), but security-critical code is well-tested (aes/cipher_test.go, age/keysource_test.go patterns). Heavy dependency on cloud provider SDKs (AWS SDK Go v2) means upstream breaking changes in major versions could impact. No obvious red flags in recent commits visible, but secrets tools require extra scrutiny for timing attacks and key management correctness.
Active areas of work
Active development with recent dependency updates (Dependabot configured in .github/dependabot.yaml). Multiple release channels visible (.release/ has Alpine and standard Dockerfiles suggesting packaging improvements). Linter and CodeQL workflows indicate ongoing code quality focus. Audit system recently active (audit/ package present with schema.sql). No specific beta features obvious, suggesting stable feature set with maintenance-mode operations.
🚀Get running
Clone and build with:
mkdir -p $GOPATH/src/github.com/getsops/
git clone https://github.com/getsops/sops.git $GOPATH/src/github.com/getsops/sops/
cd $GOPATH/src/github.com/getsops/sops/
make install
Requires Go >= 1.25. Set AWS/GCP/Azure credentials via environment (e.g., SOPS_KMS_ARN for AWS, ~/.aws/credentials) before using cloud KMS features.
Daily commands:
For CLI: make install builds the sops binary. For development iteration: go build ./cmd/sops produces cmd/sops/main executable. Run with sops directly: sops encrypt file.yaml or sops decrypt file.yaml. Set SOPS_KMS_ARN/credentials before using KMS. For tests: go test ./... runs unit tests; Rust functional tests use cargo test.
🗺️Map of the codebase
- cmd/sops/main.go: CLI entry point and subcommand dispatcher; required to understand overall command structure
- cmd/sops/formats/formats.go: File format abstraction layer that routes YAML/JSON/ENV/INI/BINARY handling to correct parser
- aes/cipher.go: Core symmetric encryption implementation using AES-GCM; central to how secrets are actually encrypted at rest
- age/keysource.go: Example of keysource interface implementation for age encryption; pattern repeated in kms/, azkv/, pgp/ packages
- kms/keysource.go: AWS KMS provider implementation showing cloud integration pattern; most common production keysource
- .sops.yaml: Configuration file example showing how SOPS selects encryption providers based on file paths and rules
- cmd/sops/decrypt.go: Decrypt subcommand implementation; paired with encrypt.go to understand full secret lifecycle
- audit/audit.go: Audit logging system that records secret access; compliance-critical for regulated deployments
🛠️How to make changes
New KMS provider: Add new package parallel to age/, azkv/, kms/ with keysource.go implementing the keysource interface. CLI command: Edit cmd/sops/main.go and add subcommand file like cmd/sops/decrypt.go. File format: Extend cmd/sops/formats/formats.go and implement format parser. Encryption logic: aes/cipher.go for symmetric ops. Start with tests in *_test.go files in the same directory. Check CONTRIBUTING.md for DCO requirements.
🪤Traps & gotchas
KMS credentials required: Many code paths require AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY or equivalent cloud creds; tests without real KMS will fail. SOPS_KMS_ARN format strict: Expects comma-separated ARNs; malformed values silently fail to specific error paths. age key format: SSH private key parsing in age/ssh_parse.go is finicky; test keys must be exact format. Binary format: cmd/sops/formats/formats.go handles BINARY specially; don't assume JSON/YAML patterns apply. .sops.yaml discovery: Looks up directory tree; nested configs override parent settings. Go version lock: Requires Go >= 1.25 (recent, not all systems have it); older Go will have cryptography API gaps. Makefile assumptions: make install uses $GOPATH; non-standard Go setups may need go install ./cmd/sops explicitly.
💡Concepts to learn
- Key Envelope Encryption (Data Encryption Key / Key Encryption Key pattern) — SOPS encrypts file contents with a local DEK (stored in aes/cipher.go) and encrypts the DEK with a remote KMS (AWS/GCP/Azure); understanding this two-level encryption model is critical for debugging why decrypt fails despite valid KMS access
- keysource Interface — All KMS providers (age, AWS, Azure, GCP, PGP) implement a shared keysource contract; modifying or adding providers requires understanding this polymorphic pattern in age/keysource.go, kms/keysource.go, etc.
- AES-GCM (Authenticated Encryption with Associated Data) — aes/cipher.go uses AES-GCM mode, not raw AES; this is critical because GCM provides both confidentiality and authenticity, preventing tampering with encrypted secrets
- Age Format (RFC 9180 / armored format) — age/ package implements age encryption standard used for local key-based SOPS; understanding its ASCII-armored text format and SSH key integration is essential for troubleshooting age-encrypted files
- Cryptographic Key Rotation — cmd/sops/rotate.go implements key rotation for rekeying secrets across providers; this operation rewraps encrypted DEKs without decrypting plaintext, critical for compliance and breach response
- Tree Walking / Abstract Syntax Tree (AST) Traversal — SOPS parses YAML/JSON into tree structures (cmd/sops/formats/) and walks them to selectively encrypt specific fields; understanding this traversal model explains how .sops.yaml rules like 'encrypt data/* but not data/public' work
- Audit Logging (Write-once append-only log with SQL schema) — audit/audit.go and audit/schema.sql implement compliance logging for secret access events; critical for understanding SOPS in regulated environments (healthcare, finance) where secret access must be immutable
🔗Related repos
mozilla/pass— Predecessor password manager that inspired SOPS's secret-in-config-files philosophy; shows evolution of secret management toolingFiloSottile/age— Standalone age encryption tool that SOPS wraps in age/ package; core encryption dependency for local key-based secretshashicorp/vault— Alternative enterprise secrets management system; SOPS users evaluating whether to integrate or replace with Vaulthelm/helm— Kubernetes package manager that SOPS commonly integrates with for encrypted Helm values; primary use case is Helm chart secret managementsealed-secrets/sealed-secrets— Kubernetes-native alternative to SOPS for encrypting secrets; competing approach with different operational model (in-cluster key management)
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for Azure Key Vault (azkv) key source
The azkv/keysource_integration_test.go file exists but is likely incomplete or skipped in CI. The repo has integration tests for other key sources but Azure KMS integration tests may not be running in the CLI workflow (.github/workflows/cli.yml). Adding proper integration test coverage with mock Azure services would improve reliability of Azure Key Vault secret management and prevent regressions.
- [ ] Review azkv/keysource_integration_test.go and identify missing test cases for key operations (encrypt, decrypt, rotate)
- [ ] Update .github/workflows/cli.yml to run Azure integration tests with appropriate environment setup or mocking
- [ ] Add test cases for error handling scenarios (invalid credentials, key not found, network failures)
Add comprehensive end-to-end tests for sops exec subcommand across platforms
The cmd/sops/subcommand/exec directory has platform-specific implementations (exec_unix.go, exec_windows.go) but likely lacks comprehensive testing. The exec functionality is critical for secret injection into processes. Adding cross-platform e2e tests would catch platform-specific bugs and ensure the exec subcommand works reliably on both Unix and Windows.
- [ ] Create cmd/sops/subcommand/exec/exec_test.go with tests for basic command execution with secret injection
- [ ] Add platform-specific test files (exec_unix_test.go, exec_windows_test.go) for Unix/Windows-specific behavior
- [ ] Update .github/workflows/cli.yml to run exec tests on both ubuntu-latest and windows-latest runners
Add unit tests for config/config.go key resolution logic
The config/config.go file handles parsing .sops.yaml and resolving which encryption keys to use based on file paths and patterns. This is core to SOPS functionality, but config/config_test.go may lack coverage for complex key resolution scenarios. Adding comprehensive tests for key selection logic (KMS ARN selection, age key matching, key rotation scenarios) would prevent configuration bugs.
- [ ] Review config/config_test.go and identify gaps in key resolution test coverage
- [ ] Add test cases for multiple key backends in same config, key selection by file path patterns, and key rotation scenarios
- [ ] Add test cases for edge cases like missing .sops.yaml, invalid YAML syntax, and conflicting key specifications
🌿Good first issues
- Add unit tests for cmd/sops/set.go: set.go command exists but no *_test.go file visible in listing; setting nested secret paths deserves parameterized tests for edge cases (special chars, deep nesting, type coercion)
- Expand cmd/sops/formats/formats_test.go to cover INI and BINARY parsing: formats_test.go exists but listing doesn't show comprehensive coverage for all 5 file formats; INI and BINARY likely under-tested compared to YAML/JSON
- Document keysource interface contract and add example in docs/: No docs/ folder visible but age/keysource.go, kms/keysource.go, azkv/keysource.go repeat same interface; new contributor building custom keysource has no reference implementation guide
⭐Top contributors
Click to expand
Top contributors
- @felixfontein — 64 commits
- @dependabot[bot] — 15 commits
- @DnR-iData — 6 commits
- @hiddeco — 5 commits
- @knowald — 3 commits
📝Recent commits
Click to expand
Recent commits
af88df5— Merge pull request #2176 from felixfontein/release-3.13.0 (felixfontein)1b19ee2— Bump version to 3.13.0. (felixfontein)934e5ba— Add 3.13.0 changelog. (felixfontein)da120c7— Merge pull request #2120 from felixfontein/mapstructure (felixfontein)a2ab197— Re-add some of Hidde's comments. (felixfontein)9061d01— Handle empty branch inconvert(hiddeco)ae2fdad— Drop unused newline-escaping helpers (hiddeco)cc4f025— Drop redundantSopsPrefixconstant in dotenv store (hiddeco)a1e776c— Compact comment-skipping insopsToGoSlice(hiddeco)8621559— Apply review nits to metadata helpers (hiddeco)
🔒Security observations
SOPS is a cryptographic tool with a solid security foundation, as managing secrets encryption is its core purpose. The codebase shows awareness of
- Medium · SQL Injection Risk in Audit Module —
audit/schema.sql, audit/audit.go. The audit module includes a schema.sql file (audit/schema.sql) which suggests direct SQL query execution. If user input is incorporated into SQL queries without proper parameterization, this could lead to SQL injection vulnerabilities. The presence of raw SQL files warrants careful review of how queries are constructed. Fix: Ensure all SQL queries use parameterized statements or prepared statements. Never concatenate user input directly into SQL queries. Implement input validation and sanitization for all database operations. - Medium · Potential Hardcoded Secrets in Configuration Examples —
example.yaml, example.json, example.ini, example.txt, .sops.yaml, config/test_resources/example.yaml. The repository contains example configuration files (.sops.yaml, example.yaml, example.json, example.ini, example.txt) and test resources. While these are likely intentionally included as examples, they demonstrate the tool's usage with actual encryption keys and may inadvertently serve as templates that users could populate with real secrets. Fix: Clearly mark all example files as non-production examples. Use placeholder values like <YOUR_KEY_HERE> instead of realistic-looking keys. Add prominent warnings in documentation about not committing real secrets to version control. - Medium · Key Material in Exec Subcommand —
cmd/sops/subcommand/exec/exec.go, cmd/sops/subcommand/exec/exec_unix.go, cmd/sops/subcommand/exec/exec_windows.go. The exec subcommand (cmd/sops/subcommand/exec/) executes arbitrary commands with decrypted secrets. If command-line arguments are improperly sanitized, this could lead to command injection attacks. The separate handling for Unix and Windows (exec_unix.go, exec_windows.go) increases the attack surface. Fix: Use proper shell escaping and avoid shell interpretation of secrets. Pass secrets via environment variables rather than command-line arguments when possible. Validate and sanitize all command components before execution. Use os/exec with explicit argument arrays rather than shell interpolation. - Low · TUI Component in Age Module —
age/tui.go. The age module includes a TUI (Text User Interface) component (age/tui.go) which handles user input for key management. TUI components can be vulnerable to terminal injection attacks if user input is not properly sanitized before display. Fix: Sanitize all user input before displaying in the TUI. Avoid using raw user input in ANSI escape sequences. Use established TUI libraries that handle input sanitization automatically. - Low · SSH Key Parsing in Age Module —
age/ssh_parse.go. The age module includes SSH key parsing functionality (age/ssh_parse.go). Improper parsing of SSH keys could lead to acceptance of malformed or malicious keys, or information disclosure vulnerabilities. Fix: Use well-tested SSH key parsing libraries. Implement strict validation of SSH key format and structure. Add comprehensive error handling for malformed keys. Include unit tests covering edge cases and invalid key formats. - Low · Azure Key Vault Integration Tests with Potential Credentials —
azkv/keysource_integration_test.go. Integration tests for Azure Key Vault (azkv/keysource_integration_test.go) may require real credentials or connection strings to test against actual services. If not properly isolated, these could leak credentials. Fix: Ensure integration tests use mocked Azure Key Vault services or temporary credentials that are automatically revoked. Use environment variables for sensitive configuration in tests. Never commit real credentials or connection strings. Document the test setup requirements clearly. - Low · Incomplete Dependency Security Metadata —
Package dependencies (Cargo.toml for functional tests). The provided Cargo.toml shows dependencies without vulnerability scanning configuration. While the dependencies themselves appear reasonable, there's no evidence of automated dependency vulnerability scanning in the CI/CD pipeline. Fix: Implement automated dependency vulnerability scanning using tools likecargo audit,dependabot, orsnyk. Add security policy enforcement to CI/CD pipeline. Regularly update dependencies to patch security vulnerabilities.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.