Skip to content

Encrypt secret metadata at rest (currently only secret values are encrypted) #251

@v0lkan

Description

@v0lkan

SPIKE currently encrypts secret values but stores secret metadata in plaintext.

In contrast HashiCorp Vault encrypts all secret metadata, leaving only the path for indexing.

SPIKE should follow the same approach for defense in depth, and also to provide similar UX for people who are accustomed to Vault.

Current Behavior

In the SQLite backing store:

  • Encrypted: Secret values
  • Plaintext: Secret metadata (created time, updated time, version info, etc.)

Proposed Behavior

Encrypt all secret metadata at rest, similar to how policies are handled:

  • Encrypted: Secret values AND metadata
  • Plaintext: Only the path (required for indexing/lookup)

Rationale

  1. Defense in depth: If an attacker gains access to the database file, metadata exposure reveals:
  • When secrets were created/modified (operational patterns)
  • How frequently secrets rotate (security posture hints)
  • Number of versions retained (retention policy details)
  1. Vault parity: Vault encrypts metadata; users migrating from Vault expect equivalent protection
  2. Consistency: SPIKE already encrypts policy metadata (spiffeid pattern, path pattern, permissions). Secret metadata should receive the same treatment
  3. Compliance: Some security frameworks require encryption of all sensitive operational data, not just the secrets themselves

Implementation Notes

  • The path must remain in plaintext for indexing and lookup operations
  • Follow the same encryption pattern used for policies in app/nexus/internal/state/backend/sqlite/persist/policy.go
  • Schema change required in app/nexus/internal/state/backend/sqlite/ddl/statement.go

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions