kelseyhightower/confd
Manage local application configuration files using templates and data from etcd or consul
Healthy across all four use cases
weakest axisPermissive 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.
- ✓26+ active contributors
- ✓MIT licensed
- ✓CI configured
Show all 6 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 2y ago
- ⚠Concentrated ownership — top contributor handles 59% 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/kelseyhightower/confd)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/kelseyhightower/confd on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: kelseyhightower/confd
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/kelseyhightower/confd 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 all four use cases
- 26+ active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ Concentrated ownership — top contributor handles 59% 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 kelseyhightower/confd
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/kelseyhightower/confd.
What it runs against: a local clone of kelseyhightower/confd — 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 kelseyhightower/confd | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 690 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of kelseyhightower/confd. If you don't
# have one yet, run these first:
#
# git clone https://github.com/kelseyhightower/confd.git
# cd confd
#
# 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 kelseyhightower/confd and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "kelseyhightower/confd(\\.git)?\\b" \\
&& ok "origin remote is kelseyhightower/confd" \\
|| miss "origin remote is not kelseyhightower/confd (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master 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 690 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~660d)"
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/kelseyhightower/confd"
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
confd is a lightweight, Go-based configuration management daemon that watches data sources (etcd, Consul, DynamoDB, Redis, Vault, ZooKeeper, AWS SSM, or environment variables) and automatically regenerates local application config files from templates when upstream data changes. It solves the problem of keeping application configuration in sync across distributed systems without requiring heavy orchestration frameworks. Monolithic CLI application structured by backend driver: backends/ contains pluggable clients for each data source (consul/, etcd/, etcdv3/, dynamodb/, redis/, vault/, etc.), each implementing a common client.go interface. Core logic in confd.go (main daemon loop) and config.go (configuration parsing), with template processing handled via Go's text/template. Integration tests in integration/, documentation in docs/.
👥Who it's for
DevOps engineers and infrastructure teams running containerized applications or microservices who need to dynamically manage application configuration files (nginx.conf, app.properties, etc.) based on centralized configuration stores without restarting orchestration systems.
🌱Maturity & risk
Actively maintained and production-ready. The project shows sustained development (Go 1.19 support, recent dependency updates in go.mod), comprehensive documentation in docs/, Travis CI integration, and multiple working backend implementations. Currently undergoing cleanup work to modernize Go versions and remove deprecated etcd v2 support, indicating active stewardship rather than abandonment.
Low-to-moderate risk: single maintainer (Kelsey Hightower's personal repo) is a concentration point, though the project is stable and widely deployed. Recent major removal of encryption template functions (cget/cgets) due to unmaintained dependencies signals dependency hygiene focus. No visible breaking changes in near-term pipeline, but contributors must pin to stable releases if encryption was previously used.
Active areas of work
Active modernization: merging etcd and etcdv3 backends into single etcdv3-based implementation, removing deprecated encryption functions (cget/cgets), upgrading to Go 1.19+, and adopting native Go modules. This is cleanup work to build on later Go versions rather than feature development.
🚀Get running
mkdir -p $GOPATH/src/github.com/kelseyhightower
git clone https://github.com/kelseyhightower/confd.git $GOPATH/src/github.com/kelseyhightower/confd
cd $GOPATH/src/github.com/kelseyhightower/confd
make
./bin/confd -version
Daily commands:
make
./bin/confd -help # shows all flags
./bin/confd -backend etcd -node http://localhost:2379 # connect to etcd
./bin/confd -backend consul -node localhost:8500 # connect to Consul
Note: requires a running backend service (etcd, Consul, etc.) to be useful. See docs/quick-start-guide.md for working examples.
🗺️Map of the codebase
- confd.go: Main daemon loop and orchestration logic; reads config, connects to backend, processes templates, handles reload commands.
- config.go: Configuration parsing from flags and TOML files; defines all CLI flags and configuration structure for the application.
- backends/client.go: Interface definition that all backend implementations must satisfy; defines GetValues(), Watch(), and WatchPrefix() contract.
- backends/etcdv3/client.go: Primary etcd backend implementation using etcd v3 client; shows pattern for key-value stores with watch capability.
- backends/consul/client.go: Consul backend implementation; demonstrates integration with different KV store APIs (Consul-specific HTTP client).
- docs/template-resources.md: Defines all available template functions and directives; essential reference for template-based configuration generation.
- config_test.go: Test suite for configuration parsing and validation; shows expected behavior for flag handling and TOML parsing.
🛠️How to make changes
Adding a new backend: Create backends/newbackend/client.go implementing the Client interface in backends/client.go, following the pattern in backends/consul/client.go or backends/redis/client.go. Fixing template issues: Edit template processing logic in confd.go and add tests to config_test.go. Docs: Add feature documentation to docs/templates.md or docs/template-resources.md. Configuration flags: Modify config.go and config_test.go, update docs/command-line-flags.md.
🪤Traps & gotchas
Backend service required: confd cannot run standalone; it must connect to at least one configured backend (etcd, Consul, etc.) or it will error. Template function removal: cget/cgets/cgetv/cgetvs are completely removed; any config using encryption will fail with no fallback. Path sensitivity: template and config file paths are relative to working directory unless absolute paths specified; different backends expect different directory structures (e.g., backends/consul expects Consul HTTP API at /v1/kv/). Reload behavior: application reloads triggered by config changes only if reload command is configured; without it, new configs are generated but not applied. Go module specifics: requires Go 1.19+; older versions will not compile due to go.mod constraints.
💡Concepts to learn
- Template-driven configuration generation — confd's core pattern: application configs are templates with placeholders filled from external data sources at runtime, avoiding static config files and enabling dynamic updates without recompilation.
- Watch-based eventual consistency — confd uses backend Watch() calls to detect upstream data changes and trigger local file regeneration; understanding watch semantics and consistency guarantees is critical for debugging stale config issues.
- Pluggable backend abstraction — confd's backends/client.go interface enables adding new KV stores without touching core logic; understanding this pattern is essential for contributing new backend support.
- File atomicity and reload signaling — confd writes config files and optionally signals applications to reload; understanding fsnotify, atomic writes, and reload command orchestration prevents config corruption during updates.
- Distributed key-value store consistency models — Different backends (etcd, Consul, ZooKeeper) have different consistency guarantees; confd's behavior depends on backend semantics, so understanding CAP trade-offs matters for production deployments.
- TOML configuration syntax — confd's own configuration is TOML-based (BurntSushi/toml); understanding TOML structure is required to write confd.conf.d/ resource files for template-to-file mappings.
- Go struct field tagging for configuration parsing — config.go uses struct tags to map TOML/CLI flags to Go fields; understanding tag semantics is essential for extending confd's configuration surface.
🔗Related repos
coreos/etcd— Primary data source for confd; etcd is the distributed key-value store that confd watches for configuration changes.hashicorp/consul— Alternative primary data source; confd has first-class Consul backend support as a service mesh configuration store.prometheus-community/helm-charts— Common deployment pattern; confd is often used in Kubernetes clusters via Helm to manage application config files alongside Prometheus monitoring.kelseyhightower/kubernetes-the-hard-way— Educational reference by same author; demonstrates confd-like configuration management patterns in bare-metal Kubernetes setups.hashicorp/terraform— Complementary IaC tool; teams often use Terraform to provision backend services (etcd, Consul) that confd consumes for configuration 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 etcdv3 backend (matching etcd backend coverage)
The repo has integration/etcd/test.sh for the legacy etcd backend, but integration/etcdv3 directory exists without a test.sh file. Given that etcdv3 is a major backend and the README mentions etcd/etcdv3 backends are being refactored as part of Go modules migration, adding parallel integration tests would ensure the v3 client works correctly and prevent regressions during the cleanup effort.
- [ ] Create integration/etcdv3/test.sh with similar structure to integration/etcd/test.sh
- [ ] Add etcdv3-specific test cases covering basic key retrieval, watching for changes, and recursive key operations
- [ ] Update .travis.yml or CI configuration to run the new etcdv3 integration tests alongside existing backend tests
- [ ] Document any etcdv3-specific setup requirements (e.g., etcdv3 server version compatibility) in the test file comments
Add comprehensive unit tests for config_test.go covering all backend types
The repo has config_test.go but it likely doesn't cover all 10+ backend implementations (etcd, etcdv3, consul, dynamodb, redis, vault, zookeeper, ssm, env, rancher, file). With multiple backends receiving updates as part of the Go modules migration, comprehensive config parsing tests for each backend would catch breaking changes early.
- [ ] Review existing config_test.go to identify which backend configurations are tested
- [ ] Add test cases for each backend in backends/**/client.go that aren't covered (e.g., dynamodb, ssm, rancher configs)
- [ ] Include edge cases like missing credentials, malformed URLs, and timeout configurations for each backend
- [ ] Run tests with
go test -v ./...to ensure they integrate with the module structure
Complete the truncated project status in README.md and add backend migration guide
The README.md ends mid-sentence in the 'Project Status' section ('The etcd and etcdv3 backend are going to be me...'). This is critical user-facing documentation. Additionally, given the major refactoring underway with Go modules and backend cleanup, a migration guide for users upgrading between versions would be valuable.
- [ ] Complete the truncated sentence in README.md explaining the etcd/etcdv3 backend changes
- [ ] Create docs/migration-guide.md documenting breaking changes, deprecated backends (if any), and upgrade paths from pre-Go-modules version
- [ ] Add a 'Supported Backends' section to README.md listing all 10+ backends with their current stability status (stable/beta/deprecated)
- [ ] Reference the migration guide from the main README for users updating confd
🌿Good first issues
- Add unit tests for backends/env/client.go and backends/file/client.go (env and file backends have minimal test coverage visible in config_test.go). These are simpler backends perfect for learning the Client interface without external service dependencies.
- Improve docs/command-line-flags.md with concrete examples for each backend type (etcd, Consul, DynamoDB, etc.). Currently only shows flags, not how to invoke confd with each backend using realistic configuration.
- Add integration tests for the template processing pipeline in integration/ directory covering edge cases like missing keys, empty values, and special characters in template variables from different backends.
⭐Top contributors
Click to expand
Top contributors
- @okushchenko — 59 commits
- @lucastheisen — 6 commits
- @hubo1016 — 5 commits
- @AndrewChubatiuk — 3 commits
- @ttousai — 2 commits
📝Recent commits
Click to expand
Recent commits
919444e— update dependencies (Kelsey Hightower)b974b1e— confd: add support for Go 1.9+ (kelseyhightower)cccd334— add file backend to quick start guide (#727) (abtreece)3d9acde— Client insecure mode (#718) (PascalChardon)34a6ce8— Merge pull request #720 from vadimgu/master (okushchenko)387686c— Fix panic on file backend change (Vadim Gubergrits)8df7906— bump to v0.17.0-dev (okushchenko)7217b0c— bump to v0.16.0 (okushchenko)28f7260— Merge pull request #710 from okushchenko/arm-support (okushchenko)09f6676— Add arm64 arch to release task; Bump Golang version to 1.10.2 (okushchenko)
🔒Security observations
- High · Outdated AWS SDK Go v1 —
go.mod - github.com/aws/aws-sdk-go v1.48.16. The project uses aws/aws-sdk-go v1.48.16, which is the legacy AWS SDK for Go. AWS has deprecated v1 in favor of aws-sdk-go-v2, which has better security practices, improved error handling, and more frequent security updates. v1 receives minimal maintenance and security patches. Fix: Migrate to aws-sdk-go-v2. Review AWS documentation for migration guide from v1 to v2, update SSM backend integration to use the newer SDK. - High · Potentially Vulnerable etcd Client Versions —
backends/etcd/client.go and backends/etcdv3/client.go. The project supports both legacy etcd (via etcd/client) and etcdv3 (go.etcd.io/etcd/client/v3 v3.5.11). Legacy etcd clients are no longer maintained and may contain unpatched security vulnerabilities. The file structure suggests dual backend support which could lead to inconsistent security postures. Fix: Deprecate and remove legacy etcd backend support. Standardize on etcdv3 client only. Update documentation to reflect this change. - Medium · Incomplete Dependency Management —
go.sum. The go.sum file content is truncated (ends with 'github.com/niemeyer/pretty v0.0.0-202002' without version), indicating incomplete or corrupted dependency lock file. This could lead to non-reproducible builds or missing security patches. Fix: Run 'go mod tidy' to regenerate the complete go.sum file. Verify all dependencies are properly locked to specific versions. Use 'go mod verify' to ensure integrity. - Medium · Multiple Backend Credentials Exposure Risk —
backends/ directory (all client implementations). The project supports 10+ different backends (etcd, consul, dynamodb, vault, redis, zookeeper, ssm, rancher, vault, env) each requiring credentials. Without explicit analysis of the code, configuration documentation (docs/configuration-guide.md, docs/data_encryption.md) should be reviewed to ensure credentials are never logged, stored in plain text, or exposed via error messages. Fix: Audit all backend client.go files for: 1) Credential logging/debugging output, 2) Plain text storage of secrets, 3) Unsafe error messages revealing credentials. Implement centralized credential management with automatic redaction from logs. - Medium · Data Encryption Documentation Incomplete —
docs/data_encryption.md and related backend implementations. While docs/data_encryption.md exists, the incomplete file structure and lack of visible encryption implementation in provided file list suggests potential gaps in end-to-end encryption of sensitive configuration data at rest or in transit. Fix: Ensure all communication with backends (especially credentials and sensitive config) uses TLS 1.2+. Verify encryption at rest for sensitive data. Document and enforce encryption requirements in configuration guide. - Medium · Vault Kubernetes Auth Implementation —
backends/vault/client.go and docs/vault-kubernetes-auth.md. docs/vault-kubernetes-auth.md suggests Kubernetes authentication integration. This requires careful handling of service account tokens and cluster credentials to prevent privilege escalation or token theft. Fix: Review Vault Kubernetes auth implementation for proper token handling. Ensure tokens are only readable by confd process. Validate Vault JWT tokens properly. Use Vault's recommended RBAC policies. - Low · Template Injection Risk in Configuration Templates —
docs/templates.md and integration/confdir/templates/. The project uses template resources (docs/templates.md, integration/confdir/templates/) with template processing. If user-supplied data is injected into templates without proper sanitization, this could lead to template injection attacks. Fix: Audit template rendering code (confd.go, config.go) to ensure proper escaping and sandboxing. Document safe template practices. Use Go's html/template where applicable for auto-escaping. - Low · Dockerfile Security Practices — ``. Dockerfile.build.alpine exists but exact configuration not visible. Alpine images should be scanned, and build artifacts should not include debug symbols or unnecessary tools. Fix: undefined
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.