Skip to content

fix: harden key-bearing export defaults to prevent key disclosure #89

@danielewood

Description

@danielewood

Summary

Several export paths that include private key material are insecure by default and can leak keys to local users or downstream systems.

Underlying problems covered by this issue:

  1. YAML bundle export includes private key material but is written as non-sensitive mode (0644) instead of 0600.
  2. Key-bearing output formats (.p12, .jks) silently default to password changeit when no password is provided.

Why this matters

These defaults can expose private keys and create a false sense of protection in automated workflows.

Evidence

  • YAML export embeds key field: internal/certstore/export.go:268
  • YAML output is not marked sensitive: internal/certstore/export.go:156
  • Non-sensitive files are written with 0644: internal/exporter.go:36
  • Sensitive-mode behavior exists (0600) but is not applied to YAML: internal/exporter.go:32, internal/exporter_test.go:120
  • changeit default in bundle command: cmd/certkit/bundle.go:199, cmd/certkit/bundle.go:207
  • changeit default in export path: internal/certstore/export.go:50, internal/certstore/export.go:113
  • User-facing docs mention default password: README.md:338

Acceptance criteria

  • YAML outputs that include private keys are treated as sensitive and written with restrictive permissions.
  • Key-bearing output formats require an explicit password or an explicit insecure override flag.
  • CLI help and README clearly describe safe defaults and any override behavior.
  • Tests cover file mode behavior and password requirement behavior.

Suggested approach

  • Mark YAML files as sensitive when private key fields are present.
  • Replace implicit changeit fallback with explicit user-provided password requirement (or a strongly signaled opt-in fallback flag).
  • Add table-driven tests for permissions and password handling.

Dedupe notes

Checked existing issues before creating:

  • gh issue list --state open --limit 200 --json number,title,url,labels -> no open issues
  • gh search issues "is:open repo:sensiblebit/certkit" --limit 100 --json number,title,url,state -> no matches
    Classified as: new.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggoPull requests that update go code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions