Skip to content

Feat/keepass provider#3

Merged
mikeboiko merged 8 commits into
mikeboiko:mainfrom
gregoftheweb:feat/keepass-provider
May 27, 2026
Merged

Feat/keepass provider#3
mikeboiko merged 8 commits into
mikeboiko:mainfrom
gregoftheweb:feat/keepass-provider

Conversation

@gregoftheweb

Copy link
Copy Markdown
Contributor

Add KeePass provider support via keepassxc-cli
Adds KeePass as a second secret provider alongside Bitwarden. Default behaviour is unchanged — existing Bitwarden users see no difference.
What's new:

provider: keepass option in .envsync.yaml
Single master password prompt per ds invocation (no daemon required)
ds scaffold — seeds a KeePass vault with blank entries for all provider-managed keys in .env.example (dev lead tool)
ds init first-run setup — interactive provider selection with live vault validation before writing config
ds doctor updated to report keepass ready
Full test coverage for the new provider package
*.kdbx added to .gitignore

KeePass config:
yamlprovider: keepass
keepass_database: secrets.kdbx
keepass_group: dotenv
Requires: keepassxc-cli (ships with KeePassXC)

@mikeboiko mikeboiko left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution! The core KeePass provider implementation is solid — clean architecture, good test coverage with stub scripts, secure password handling (stdin, not CLI args), and proper caching.

However, there are several issues that need to be addressed before this can be merged.

Must fix before merge

  1. test-secrets.kdbx committed to the repo — A real KeePass database is tracked in git. The *.kdbx gitignore rule only prevents future untracked files — since this is already committed, it lives in history forever. The tests don't use it (they use shell script stubs), so please git rm it.

  2. .envsync.yaml and .env.example committed to the project root — These are developer-local artifacts that would override config for every contributor. Please remove (or move to testdata/ if needed for tests).

  3. go 1.22go 1.25.0 version bumpgolang.org/x/term v0.43.0 supports Go 1.22+, so this bump appears unnecessary and will break users on older Go.

  4. ensureConfig errors silently swallowed — In init.go and scaffold.go, errors return nil instead of the error, meaning failures are invisible to the user.

  5. ds push silently falls through to Bitwarden when configured with provider: keepass — should error clearly instead.

  6. Missing trailing newlines at EOF in root.go, doctor.go, init.go.

  7. Orphaned doc comment at adapter.go:178.

See inline comments for details on each.

Comment thread .envsync.yaml
provider: keepass
schema_file: .env.example
env_file: .env
keepass_database: test-secrets.kdbx

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This config file should not be committed to the project root — it hardcodes provider: keepass and points at test-secrets.kdbx, which would override the config for every contributor who clones the repo.

If you need this for test fixtures, place it under testdata/. Otherwise please remove it.

Comment thread .env.example
@@ -0,0 +1,4 @@
# Database
DATABASE_URL=

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern — this appears to be a demo/test artifact rather than something that belongs in the project root. The project generates .env.example via ds init; committing a sample one here may confuse contributors or conflict with the actual project schema.

Please remove, or move to testdata/ if needed for tests.

Comment thread go.mod

go 1.22
go 1.25.0

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bumps the minimum Go version from 1.22 to 1.25.0 — a significant breaking change for anyone on an older Go.

golang.org/x/term v0.43.0 and golang.org/x/sys v0.44.0 both support Go 1.22+, so this bump appears unnecessary. Please revert to go 1.22.

}
return a.client.CreateEntry(ctx, a.cfg.KeePassDatabase, a.cfg.KeePassGroup, key, "")
}
// per process run. Subsequent calls return immediately because the password is

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc comment fragment ("per process run. Subsequent calls return immediately...") is orphaned from its function — it's separated from ensurePassword by CreateEntry's closing brace on the line above.

Please merge this into the comment block at line 183, or restructure so the full doc comment is directly above func (a *Adapter) ensurePassword(...).

Comment thread internal/cli/scaffold.go Outdated
RunE: func(cmd *cobra.Command, args []string) error {
_, cfg, setupPassword, err := ensureConfig(s, opts)
if err != nil {
return nil

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When ensureConfig returns an error, this silently returns nil — meaning the command reports success (exit 0) even when setup failed. The user gets no indication anything went wrong.

Should this be return err instead?

Comment thread internal/cli/init.go Outdated
setupRan, cfg, _, err := ensureConfig(s, opts)
if err != nil {
return err
return nil

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same silent-error issue: the original init.go on main correctly returned err from loadConfig. This change swallows the error. If ensureConfig already prints its own message, at minimum the exit code should still be non-zero — please return the error.

Comment thread internal/cli/root.go

var pushProviderFactory = func(cfg config.Config) provider.PushProvider {
// KeePass does not yet implement PushProvider (ds push is Bitwarden-only for now).
// All push operations fall through to Bitwarden regardless of config.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ds push with provider: keepass will silently use Bitwarden here, which is confusing and potentially dangerous — the user thinks they're pushing to their configured provider but they're actually interacting with a different one.

Please add a guard in the push command (or here) that returns a clear error like "push is not supported for the keepass provider" when cfg.Provider == "keepass".

@gregoftheweb

Copy link
Copy Markdown
Contributor Author

Hi Mike,
Thanks for the thorough review — all issues addressed in the latest push:

Test artifacts removed — test-secrets.kdbx, .envsync.yaml, and .env.example removed from git tracking via git rm --cached
go.mod reverted — back to go 1.22, go mod tidy run to clean up
Swallowed errors fixed — scaffold.go and init.go now return err instead of nil
ds push guard added — returns a clear error when provider: keepass is configured
Orphaned doc comment fixed — moved directly above ensurePassword
Trailing newlines added — root.go, doctor.go, init.go

Let me know if anything else needs attention.

@gregoftheweb
gregoftheweb requested a review from mikeboiko May 27, 2026 13:51
@mikeboiko

Copy link
Copy Markdown
Owner

Hey Greg — thanks for the fixes! I addressed the remaining items myself since I'll be squash-merging this shortly:

  1. Removed .envsync.yaml and .env.example from the repo — these were developer-local test artifacts that would override every contributor's config.
  2. Reverted Go version back to 1.22 — downgraded golang.org/x/term from v0.43.0 to v0.28.0 (and x/sys from v0.44.0 to v0.29.0). The API surface we use (ReadPassword, IsTerminal) exists in the older version, and this avoids forcing contributors to run Go 1.25+.
  3. Fixed missing trailing newlines in init.go, push.go, and scaffold.go.
  4. Ran gofmt across the project for consistency.

All tests pass. Merging now — nice work on the KeePass provider! 🎉

@mikeboiko
mikeboiko merged commit 3b1f60c into mikeboiko:main May 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants