ADR-0019: Plugin-Based Storage Backend Architecture
- Status: proposed
- Date: 2024-02-20
- Tags: Persistence, Storage, Plugins, Architecture
- Related: ADR-0014: Maintaining SQLite as SPIKE’s Primary Storage Backend
Context
Following ADR-0014’s decision to maintain SQLite as SPIKE’s primary storage backend, we recognize the need for flexibility in storage solutions for different deployment scenarios. Some deployments may require:
- Alternative storage backends for enterprise environments
- Specialized storage solutions for specific use cases
- Custom implementations for unique requirements
- In-memory storage for development and testing
Decision
We will implement a plugin-based architecture for storage backends while maintaining SQLite as the default implementation. This architecture will:
- Define a clear storage interface that all backends must implement
- Provide official plugins for common use cases
- Enable third-party plugin development
- Maintain backward compatibility with existing SQLite implementations
Rationale
Plugin System Benefits
1. Extensibility:
- Users can implement custom storage solutions
- Third-party developers can contribute new backends
- Specialized solutions can be developed without modifying core code
2. Maintainability:
- Core codebase remains focused on primary functionality
- Plugins can be maintained independently
- Testing and validation can be scoped to specific implementations
3. Deployment Flexibility:
- Different environments can use appropriate storage solutions
- Migration between backends becomes possible
- Development and testing can use simplified implementations
Official Plugin Scope
1. Core Implementation:
- SQLite (default backend, ships with core)
- In-memory (for development and testing)
2. Additional Official Plugins:
- PostgreSQL
- S3/MinIO compatible storage
Interface Requirements
Storage plugins must implement:
1. Core Operations:
- CRUD operations for secrets
- Atomic transactions
- Concurrent access handling
- Error handling and recovery
2. Security Features:
- Access control integration
- Audit logging support
3. Management Functions:
- Health checks
- Backup/restore capabilities
- Migration tools
Implementation
Plugin Architecture
Here is a sample structure for the plugin architecture. Note that this is a starting point and it will likely be subject to change.
// Interface
type StorageBackend interface {
// Core operations
Create(ctx context.Context, secret *Secret) error
Read(ctx context.Context, id string) (*Secret, error)
Update(ctx context.Context, secret *Secret) error
Delete(ctx context.Context, id string) error
// Management
Initialize(ctx context.Context, config *Config) error
Healthcheck(ctx context.Context) error
// Transaction support
BeginTx(ctx context.Context) (Transaction, error)
}
// Registration
type PluginRegistry interface {
Register(name string, factory StorageFactory) error
Get(name string) (StorageFactory, error)
}
Consequences
Positive
- Increased flexibility for different deployment scenarios
- Clear path for community contributions
- Simplified testing with in-memory implementation
- Better separation of concerns
Negative
- Additional complexity in plugin management
- Need for plugin validation and security review
- Potential for incompatible plugin implementations
- Documentation overhead for multiple backends
Mitigations
- Plugin Validation:
- Provide comprehensive test suites
- Implement plugin verification tools
- Document security requirements
- Compatibility:
- Version plugin interface explicitly
- Provide migration tools between backends
- Maintain compatibility tests
- Documentation:
- Clear plugin development guidelines
- Example implementations
- Best practices documentation
Related Documents
- ADR-0014: Maintaining SQLite as SPIKE’s Primary Storage Backend
- Plugin Development Guide (To be created)
- Storage Interface Specification (To be created)
- ADR-0021: SPIKE Keeper as a Stateless Shard Holder
- ADR-0020: Switch to Zola for Documentation System
- ADR-0019: Plugin-Based Storage Backend Architecture
- ADR-0018: Administrative Access to SPIKE
- ADR-0017: Synchronous Persistence for SPIKE Secrets Store
- ADR-0016: Memory-First Secrets Store
- ADR-0015: Use Singular Form for File and Package Naming
- ADR-0014: Maintaining SQLite as SPIKE’s Primary Storage Backend
- ADR-0013: S3-Compatible Storage as SPIKE’s Backing Store
- ADR-0012: HTTP Methods for SPIKE API
- ADR-0011: PostgreSQL as SPIKE’s Backing Store
- ADR-0010: Session Token Storage Strategy for SPIKE Nexus
- ADR-0009: Multi-Administrator Support System
- ADR-0008: Administrative Access Control System
- ADR-0007: Root Key Lifecycle and Management Strategy
- ADR-0006: Trust Boundary Definition and Security Assumptions
- ADR-0005: Use SPIFFE mTLS for Inter-Component Authentication and Communication
- ADR-0004: SPIKE Keeper Minimalist Design Approach
- ADR-0003: Root Key Management and Storage Strategy
- ADR-0002: Use Docsify for Documentation System
- ADR-0001: Display Secrets in Plain Text in SPIKE Pilot Admin CLI