secrets

package
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2026 License: Apache-2.0 Imports: 40 Imported by: 0

README

Secrets Plugin for AuthSome

The Secrets Plugin provides enterprise-grade secrets management for AuthSome applications with encryption at rest, versioning, and Forge ConfigSource integration.

Features

  • Hierarchical Path Structure: Organize secrets with Consul-like paths (e.g., database/postgres/password)
  • Encryption at Rest: AES-256-GCM encryption with Argon2 key derivation per tenant
  • Multi-Value Type Support: Plain text, JSON, YAML, and binary values
  • JSON Schema Validation: Optional schema validation for structured secrets
  • Version History: Track changes and rollback to previous versions
  • Forge ConfigSource: Integrate secrets directly into Forge's configuration system
  • Audit Logging: Track all access to secrets for compliance
  • Dashboard UI: Full-featured web interface for managing secrets

Installation

The secrets plugin is included in AuthSome. Enable it by adding to your configuration:

auth:
  secrets:
    encryption:
      masterKey: ${AUTHSOME_SECRETS_MASTER_KEY}

Generate a master key:

# Generate a secure 32-byte key
openssl rand -base64 32

Configuration

auth:
  secrets:
    # Encryption settings
    encryption:
      masterKey: ${AUTHSOME_SECRETS_MASTER_KEY}  # Required: 32-byte base64-encoded key
      rotateKeyAfter: 8760h                       # Warn about rotation after 1 year
      testOnStartup: true                         # Test encryption on startup
    
    # Forge ConfigSource integration
    configSource:
      enabled: false                              # Enable config source integration
      prefix: ""                                  # Path prefix filter
      refreshInterval: 5m                         # Cache refresh interval
      autoRefresh: true                           # Auto-refresh on secret changes
      priority: 100                               # Config source priority
    
    # Access control
    access:
      requireAuthentication: true                 # Require auth for all access
      requireRbac: true                           # Enable RBAC checks
      allowApiAccess: true                        # Allow REST API access
      allowDashboardAccess: true                  # Allow dashboard access
      rateLimitPerMinute: 0                       # Rate limit (0 = disabled)
    
    # Versioning
    versioning:
      maxVersions: 50                             # Max versions to keep
      retentionDays: 90                           # Version retention period
      autoCleanup: true                           # Auto-cleanup old versions
    
    # Audit logging
    audit:
      enableAccessLog: true                       # Enable access logging
      logReads: false                             # Log read access (verbose)
      logWrites: true                             # Log write access
      retentionDays: 365                          # Log retention period

Quick Start

1. Initialize the Plugin
import "github.com/xraph/authsome/plugins/secrets"

// Create plugin with options
secretsPlugin := secrets.NewPlugin(
    secrets.WithConfigSourceEnabled(true),
    secrets.WithMaxVersions(100),
)

// Register with AuthSome
auth := authsome.New(
    authsome.WithPlugins(secretsPlugin),
)
2. Create a Secret
curl -X POST http://localhost:8080/api/auth/secrets \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "database/postgres/password",
    "value": "supersecret123",
    "valueType": "plain",
    "description": "PostgreSQL production password",
    "tags": ["production", "database"]
  }'
3. Retrieve a Secret
# Get metadata
curl http://localhost:8080/api/auth/secrets/path/database/postgres/password \
  -H "Authorization: Bearer $TOKEN"

# Get decrypted value
curl http://localhost:8080/api/auth/secrets/abc123/value \
  -H "Authorization: Bearer $TOKEN"

API Reference

Endpoints
Method Path Description
GET /secrets List secrets with filtering
POST /secrets Create a new secret
GET /secrets/:id Get secret metadata
GET /secrets/:id/value Get decrypted value
PUT /secrets/:id Update a secret
DELETE /secrets/:id Delete a secret
GET /secrets/:id/versions Get version history
POST /secrets/:id/rollback/:version Rollback to version
GET /secrets/path/*path Get secret by path
GET /secrets/stats Get statistics
GET /secrets/tree Get tree structure
Query Parameters

For GET /secrets:

  • prefix - Filter by path prefix
  • search - Search in path and description
  • valueType - Filter by type (plain, json, yaml, binary)
  • tags - Filter by tags (comma-separated)
  • page - Page number (default: 1)
  • pageSize - Items per page (default: 20, max: 100)
  • sortBy - Sort field (path, created_at, updated_at)
  • sortOrder - Sort order (asc, desc)
Request/Response Examples

Create Secret with JSON Value:

{
  "path": "services/stripe/config",
  "value": {
    "apiKey": "sk_live_...",
    "webhookSecret": "whsec_..."
  },
  "valueType": "json",
  "schema": {
    "type": "object",
    "required": ["apiKey", "webhookSecret"]
  },
  "description": "Stripe API configuration",
  "tags": ["payments", "production"]
}

Secret Response:

{
  "id": "cnpq7jkg3k8g00f45e40",
  "path": "services/stripe/config",
  "key": "config",
  "valueType": "json",
  "description": "Stripe API configuration",
  "tags": ["payments", "production"],
  "version": 1,
  "isActive": true,
  "hasSchema": true,
  "hasExpiry": false,
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}

Value Types

Plain Text

Simple string values. Best for passwords, API keys, tokens.

{
  "path": "api/openai/key",
  "value": "sk-proj-abc123...",
  "valueType": "plain"
}
JSON

Structured JSON objects or arrays. Supports JSON Schema validation.

{
  "path": "database/postgres/config",
  "value": {
    "host": "db.example.com",
    "port": 5432,
    "database": "myapp",
    "sslMode": "require"
  },
  "valueType": "json",
  "schema": {
    "type": "object",
    "required": ["host", "port", "database"]
  }
}
YAML

YAML documents. Useful for configuration files.

{
  "path": "kubernetes/secrets/app-config",
  "value": "database:\n  host: localhost\n  port: 5432\nredis:\n  host: cache.local",
  "valueType": "yaml"
}
Binary

Base64-encoded binary data. For certificates, keys, images.

{
  "path": "tls/server/certificate",
  "value": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...",
  "valueType": "binary"
}

Forge ConfigSource Integration

When enabled, secrets become available through Forge's configuration system:

// Secrets are accessible via dot notation
// Path: database/postgres/password
// Config key: database.postgres.password

password := configManager.GetString("database.postgres.password")
How It Works
  1. Secret paths are converted to config keys (/.)
  2. Values are cached in memory for performance
  3. Cache is refreshed periodically or on secret changes
  4. Supports hot-reload via callbacks

Security

Encryption Architecture
  1. Master Key: A 32-byte key (base64 encoded) stored securely
  2. Key Derivation: Argon2id derives unique keys per app/environment
  3. Encryption: AES-256-GCM with random nonces per operation
  4. Isolation: Different tenants cannot decrypt each other's secrets
Best Practices
  • Store master key in environment variable, not config files
  • Rotate master key periodically
  • Use RBAC to control access
  • Enable audit logging in production
  • Set appropriate expiration dates

RBAC Roles

The plugin registers two default roles:

  • secrets_admin: Full CRUD access to all secrets
  • secrets_viewer: Read-only access to secret metadata (no values)

Dashboard

Access the secrets dashboard at:

/dashboard/app/{appId}/secrets

Features:

  • List/search secrets with tree view
  • Create/edit secrets with syntax hints
  • Reveal values with auto-hide
  • Version history and rollback
  • Statistics overview

Troubleshooting

Common Issues

"secrets master key is not configured" Set the AUTHSOME_SECRETS_MASTER_KEY environment variable with a valid 32-byte base64-encoded key.

"invalid master key" Ensure the key is exactly 32 bytes when decoded from base64.

"secret not found" Check that the path is correct and normalized (lowercase, no leading/trailing slashes).

"validation failed" The value doesn't match the JSON Schema. Check the schema requirements.

Debug Mode

Enable debug logging:

logging:
  level: debug

License

Part of the AuthSome project. See main LICENSE file.

Documentation

Overview

Package secrets provides the secrets management plugin for AuthSome.

Index

Constants

View Source
const (
	// MasterKeyLength is the required length for the master key (32 bytes for AES-256)
	MasterKeyLength = 32
	// NonceLength is the length of the nonce for AES-GCM (12 bytes)
	NonceLength = 12
	// SaltLength is the length of the salt for key derivation
	SaltLength = 32
)

Encryption constants

View Source
const (
	// PluginID is the unique identifier for the secrets plugin
	PluginID = "secrets"
	// PluginName is the human-readable name
	PluginName = "Secrets Manager"
	// PluginVersion is the current version
	PluginVersion = "1.0.0"
	// PluginDescription describes the plugin
	PluginDescription = "Secure secrets and configuration management with encryption, versioning, and Forge ConfigSource integration"

	// Environment variable for master key
	EnvMasterKey = "AUTHSOME_SECRETS_MASTER_KEY"
)

Variables

This section is empty.

Functions

func FormatValue

func FormatValue(value interface{}, valueType core.SecretValueType) string

FormatValue formats a value for display based on its type

func GenerateMasterKey

func GenerateMasterKey() (string, error)

GenerateMasterKey generates a new random master key and returns it as base64-encoded string. This is a utility function for initial setup.

Types

type AccessConfig

type AccessConfig struct {
	// RequireAuthentication requires authentication for all secret access
	// Default: true
	RequireAuthentication bool `json:"requireAuthentication" yaml:"requireAuthentication"`

	// RequireRBAC enables RBAC checks for secret access
	// Default: true
	RequireRBAC bool `json:"requireRbac" yaml:"requireRbac"`

	// AllowAPIAccess allows API access to secrets
	// Default: true
	AllowAPIAccess bool `json:"allowApiAccess" yaml:"allowApiAccess"`

	// AllowDashboardAccess allows dashboard access to secrets
	// Default: true
	AllowDashboardAccess bool `json:"allowDashboardAccess" yaml:"allowDashboardAccess"`

	// RateLimitPerMinute is the rate limit for secret access per minute
	// 0 means no rate limiting
	// Default: 0
	RateLimitPerMinute int `json:"rateLimitPerMinute" yaml:"rateLimitPerMinute"`
}

AccessConfig holds access control settings

type AuditConfig

type AuditConfig struct {
	// EnableAccessLog enables access logging for secrets
	// Default: true
	EnableAccessLog bool `json:"enableAccessLog" yaml:"enableAccessLog"`

	// LogReads logs read access (can be verbose)
	// Default: false
	LogReads bool `json:"logReads" yaml:"logReads"`

	// LogWrites logs write access (create, update, delete)
	// Default: true
	LogWrites bool `json:"logWrites" yaml:"logWrites"`

	// RetentionDays is how long to keep audit logs in days
	// Default: 365
	RetentionDays int `json:"retentionDays" yaml:"retentionDays"`

	// AutoCleanup enables automatic cleanup of old audit logs
	// Default: true
	AutoCleanup bool `json:"autoCleanup" yaml:"autoCleanup"`
}

AuditConfig holds audit settings

type Config

type Config struct {
	// Encryption settings
	Encryption EncryptionConfig `json:"encryption" yaml:"encryption"`

	// ConfigSource settings for Forge integration
	ConfigSource ConfigSourceConfig `json:"configSource" yaml:"configSource"`

	// Access control settings
	Access AccessConfig `json:"access" yaml:"access"`

	// Versioning settings
	Versioning VersioningConfig `json:"versioning" yaml:"versioning"`

	// Audit settings
	Audit AuditConfig `json:"audit" yaml:"audit"`

	// Dashboard settings
	Dashboard DashboardConfig `json:"dashboard" yaml:"dashboard"`
}

Config holds the secrets plugin configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns the default configuration

func (*Config) Merge

func (c *Config) Merge(other *Config)

Merge merges another config into this one (non-zero values override)

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration

type ConfigSourceConfig

type ConfigSourceConfig struct {
	// Enabled enables the Forge ConfigSource integration
	// When enabled, secrets can be accessed via Forge's ConfigManager
	// Default: false
	Enabled bool `json:"enabled" yaml:"enabled"`

	// Prefix is the path prefix for secrets to include in config
	// Only secrets with paths starting with this prefix will be exposed
	// Empty string means all secrets are exposed
	Prefix string `json:"prefix" yaml:"prefix"`

	// RefreshInterval is how often to refresh the config cache from database
	// Default: 5 minutes
	RefreshInterval time.Duration `json:"refreshInterval" yaml:"refreshInterval"`

	// AutoRefresh enables automatic refresh on secret changes via hooks
	// Default: true
	AutoRefresh bool `json:"autoRefresh" yaml:"autoRefresh"`

	// Priority is the config source priority (higher = more important)
	// Default: 100
	Priority int `json:"priority" yaml:"priority"`
}

ConfigSourceConfig holds Forge ConfigSource integration settings

type CreateSecretRequest added in v0.0.7

type CreateSecretRequest struct {
	Path        string                 `json:"path" validate:"required"`
	Value       interface{}            `json:"value" validate:"required"`
	ValueType   string                 `json:"valueType" validate:"required"`
	Description string                 `json:"description"`
	Tags        []string               `json:"tags"`
	Metadata    map[string]interface{} `json:"metadata"`
}

type DashboardConfig

type DashboardConfig struct {
	// EnableTreeView enables the tree view in the dashboard
	// Default: true
	EnableTreeView bool `json:"enableTreeView" yaml:"enableTreeView"`

	// EnableReveal enables the reveal value feature in the dashboard
	// Default: true
	EnableReveal bool `json:"enableReveal" yaml:"enableReveal"`

	// RevealTimeout is how long to show the revealed value before auto-hiding
	// Default: 30 seconds
	RevealTimeout time.Duration `json:"revealTimeout" yaml:"revealTimeout"`

	// EnableExport enables exporting secrets (requires admin)
	// Default: false
	EnableExport bool `json:"enableExport" yaml:"enableExport"`

	// EnableImport enables importing secrets (requires admin)
	// Default: false
	EnableImport bool `json:"enableImport" yaml:"enableImport"`
}

DashboardConfig holds dashboard-specific settings

type DashboardExtension

type DashboardExtension struct {
	// contains filtered or unexported fields
}

DashboardExtension implements ui.DashboardExtension for the secrets plugin

func NewDashboardExtension

func NewDashboardExtension(plugin *Plugin) *DashboardExtension

NewDashboardExtension creates a new dashboard extension

func (*DashboardExtension) DashboardWidgets

func (e *DashboardExtension) DashboardWidgets() []ui.DashboardWidget

DashboardWidgets returns dashboard widgets

func (*DashboardExtension) ExtensionID

func (e *DashboardExtension) ExtensionID() string

ExtensionID returns the unique identifier for this extension

func (*DashboardExtension) HandleCreateSecret

func (e *DashboardExtension) HandleCreateSecret(c forge.Context) error

HandleCreateSecret handles the create secret form submission

func (*DashboardExtension) HandleDeleteSecret

func (e *DashboardExtension) HandleDeleteSecret(c forge.Context) error

HandleDeleteSecret handles the delete secret action

func (*DashboardExtension) HandleRevealValue

func (e *DashboardExtension) HandleRevealValue(c forge.Context) error

HandleRevealValue handles the reveal value AJAX request

func (*DashboardExtension) HandleRollback

func (e *DashboardExtension) HandleRollback(c forge.Context) error

HandleRollback handles the rollback action

func (*DashboardExtension) HandleUpdateSecret

func (e *DashboardExtension) HandleUpdateSecret(c forge.Context) error

HandleUpdateSecret handles the update secret form submission

func (*DashboardExtension) NavigationItems

func (e *DashboardExtension) NavigationItems() []ui.NavigationItem

NavigationItems returns navigation items for the dashboard

func (*DashboardExtension) Routes

func (e *DashboardExtension) Routes() []ui.Route

Routes returns dashboard routes

func (*DashboardExtension) ServeCreateSecretPage

func (e *DashboardExtension) ServeCreateSecretPage(c forge.Context) error

ServeCreateSecretPage serves the create secret page

func (*DashboardExtension) ServeEditSecretPage

func (e *DashboardExtension) ServeEditSecretPage(c forge.Context) error

ServeEditSecretPage serves the edit secret page

func (*DashboardExtension) ServeSecretDetailPage

func (e *DashboardExtension) ServeSecretDetailPage(c forge.Context) error

ServeSecretDetailPage serves the secret detail page

func (*DashboardExtension) ServeSecretsListPage

func (e *DashboardExtension) ServeSecretsListPage(c forge.Context) error

ServeSecretsListPage serves the secrets list page

func (*DashboardExtension) ServeVersionHistoryPage

func (e *DashboardExtension) ServeVersionHistoryPage(c forge.Context) error

ServeVersionHistoryPage serves the version history page

func (*DashboardExtension) SetRegistry

func (e *DashboardExtension) SetRegistry(registry *dashboard.ExtensionRegistry)

SetRegistry sets the extension registry reference

func (*DashboardExtension) SettingsPages

func (e *DashboardExtension) SettingsPages() []ui.SettingsPage

SettingsPages returns settings pages

func (*DashboardExtension) SettingsSections

func (e *DashboardExtension) SettingsSections() []ui.SettingsSection

SettingsSections returns settings sections (deprecated)

type DeleteSecretRequest added in v0.0.7

type DeleteSecretRequest struct {
	ID string `path:"id" validate:"required"`
}

type EncryptionConfig

type EncryptionConfig struct {
	// MasterKey is the base64-encoded 32-byte master key for encryption
	// This should be set via AUTHSOME_SECRETS_MASTER_KEY environment variable
	MasterKey string `json:"masterKey" yaml:"masterKey"`

	// RotateKeyAfter specifies the duration after which to warn about key rotation
	// Default: 365 days
	RotateKeyAfter time.Duration `json:"rotateKeyAfter" yaml:"rotateKeyAfter"`

	// TestOnStartup tests encryption on startup to verify configuration
	// Default: true
	TestOnStartup bool `json:"testOnStartup" yaml:"testOnStartup"`
}

EncryptionConfig holds encryption settings

type EncryptionService

type EncryptionService struct {
	// contains filtered or unexported fields
}

EncryptionService handles encryption and decryption of secret values using AES-256-GCM with Argon2 key derivation for per-tenant isolation.

func NewEncryptionService

func NewEncryptionService(masterKeyBase64 string) (*EncryptionService, error)

NewEncryptionService creates a new encryption service with the given master key. The master key must be a base64-encoded 32-byte key.

func (*EncryptionService) ClearKeyCache

func (e *EncryptionService) ClearKeyCache()

ClearKeyCache clears the derived key cache. This should be called when rotating the master key.

func (*EncryptionService) ClearKeyForTenant

func (e *EncryptionService) ClearKeyForTenant(appID, envID string)

ClearKeyForTenant clears the cached key for a specific tenant.

func (*EncryptionService) Decrypt

func (e *EncryptionService) Decrypt(ciphertext, nonce []byte, appID, envID string) ([]byte, error)

Decrypt decrypts ciphertext using AES-256-GCM with a key derived for the specific app/environment.

func (*EncryptionService) DeriveKey

func (e *EncryptionService) DeriveKey(appID, envID string) []byte

DeriveKey derives an encryption key for a specific app and environment using Argon2. This provides cryptographic isolation between different tenants.

func (*EncryptionService) Encrypt

func (e *EncryptionService) Encrypt(plaintext []byte, appID, envID string) (ciphertext, nonce []byte, err error)

Encrypt encrypts plaintext using AES-256-GCM with a key derived for the specific app/environment. Returns the ciphertext and nonce, which must both be stored.

func (*EncryptionService) ReEncrypt

func (e *EncryptionService) ReEncrypt(
	ciphertext, nonce []byte,
	oldAppID, oldEnvID string,
	newAppID, newEnvID string,
) (newCiphertext, newNonce []byte, err error)

ReEncrypt re-encrypts a value with a new key derivation. This is useful when rotating encryption keys or migrating secrets between environments.

func (*EncryptionService) TestEncryption

func (e *EncryptionService) TestEncryption() error

TestEncryption performs a test encryption/decryption cycle to verify the service is working.

func (*EncryptionService) ValidateMasterKey

func (e *EncryptionService) ValidateMasterKey() error

ValidateMasterKey validates that the master key is properly configured.

type ErrorResponse

type ErrorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message"`
	Code    string `json:"code,omitempty"`
}

ErrorResponse is the standard error response

type GetByPathRequest added in v0.0.7

type GetByPathRequest struct {
	Path string `query:"path" validate:"required"`
}

type GetSecretRequest added in v0.0.7

type GetSecretRequest struct {
	ID string `path:"id" validate:"required"`
}

type GetTreeRequest added in v0.0.7

type GetTreeRequest struct {
	Prefix string `query:"prefix"`
}

type GetValueRequest added in v0.0.7

type GetValueRequest struct {
	ID string `path:"id" validate:"required"`
}

type GetVersionsRequest added in v0.0.7

type GetVersionsRequest struct {
	ID       string `path:"id" validate:"required"`
	Page     int    `query:"page"`
	PageSize int    `query:"pageSize"`
}

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler handles HTTP requests for the secrets API

func NewHandler

func NewHandler(service *Service, logger forge.Logger) *Handler

NewHandler creates a new secrets handler

func (*Handler) Create

func (h *Handler) Create(c forge.Context) error

Create handles POST /secrets

func (*Handler) Delete

func (h *Handler) Delete(c forge.Context) error

Delete handles DELETE /secrets/:id

func (*Handler) Get

func (h *Handler) Get(c forge.Context) error

Get handles GET /secrets/:id

func (*Handler) GetByPath

func (h *Handler) GetByPath(c forge.Context) error

GetByPath handles GET /secrets/path/*path

func (*Handler) GetStats

func (h *Handler) GetStats(c forge.Context) error

GetStats handles GET /secrets/stats

func (*Handler) GetTree

func (h *Handler) GetTree(c forge.Context) error

GetTree handles GET /secrets/tree

func (*Handler) GetValue

func (h *Handler) GetValue(c forge.Context) error

GetValue handles GET /secrets/:id/value

func (*Handler) GetValueByPath

func (h *Handler) GetValueByPath(c forge.Context) error

GetValueByPath handles GET /secrets/path/*path/value

func (*Handler) GetVersions

func (h *Handler) GetVersions(c forge.Context) error

GetVersions handles GET /secrets/:id/versions

func (*Handler) List

func (h *Handler) List(c forge.Context) error

List handles GET /secrets

func (*Handler) Rollback

func (h *Handler) Rollback(c forge.Context) error

Rollback handles POST /secrets/:id/rollback/:version

func (*Handler) Update

func (h *Handler) Update(c forge.Context) error

Update handles PUT /secrets/:id

type ListSecretsRequest added in v0.0.7

type ListSecretsRequest struct {
	Prefix    string   `query:"prefix"`
	ValueType string   `query:"valueType"`
	Search    string   `query:"search"`
	SortBy    string   `query:"sortBy"`
	SortOrder string   `query:"sortOrder"`
	Recursive bool     `query:"recursive"`
	Page      int      `query:"page"`
	PageSize  int      `query:"pageSize"`
	Tags      []string `query:"tags"`
}

Request types

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin implements the secrets management plugin for AuthSome

func NewPlugin

func NewPlugin(opts ...PluginOption) *Plugin

NewPlugin creates a new secrets plugin instance

func (*Plugin) Config

func (p *Plugin) Config() *Config

Config returns the plugin configuration

func (*Plugin) CreateConfigSource

func (p *Plugin) CreateConfigSource(appID, envID string) (*SecretsConfigSource, error)

CreateConfigSource creates a new config source for an app/environment

func (*Plugin) DashboardExtension

func (p *Plugin) DashboardExtension() ui.DashboardExtension

DashboardExtension returns the dashboard extension for the plugin

func (*Plugin) Description

func (p *Plugin) Description() string

Description returns the plugin description

func (*Plugin) GetConfigSource

func (p *Plugin) GetConfigSource(appID, envID string) *SecretsConfigSource

GetConfigSource returns a config source for the given app/environment

func (*Plugin) ID

func (p *Plugin) ID() string

ID returns the unique plugin identifier

func (*Plugin) Init

func (p *Plugin) Init(auth core.Authsome) error

Init initializes the plugin with dependencies from the Auth instance

func (*Plugin) Logger

func (p *Plugin) Logger() forge.Logger

Logger returns the plugin logger

func (*Plugin) Migrate

func (p *Plugin) Migrate() error

Migrate runs database migrations for the plugin

func (*Plugin) Name

func (p *Plugin) Name() string

Name returns the human-readable plugin name

func (*Plugin) Priority

func (p *Plugin) Priority() int

Priority returns the plugin initialization priority Lower values = higher priority (load first) Secrets should load early to provide config values

func (*Plugin) RegisterHooks

func (p *Plugin) RegisterHooks(hookRegistry *hooks.HookRegistry) error

RegisterHooks registers the plugin's hooks

func (*Plugin) RegisterRoles

func (p *Plugin) RegisterRoles(roleRegistry rbac.RoleRegistryInterface) error

RegisterRoles registers RBAC roles for the plugin

func (*Plugin) RegisterRoutes

func (p *Plugin) RegisterRoutes(router forge.Router) error

RegisterRoutes registers the plugin's HTTP routes

func (*Plugin) RegisterServiceDecorators

func (p *Plugin) RegisterServiceDecorators(services *registry.ServiceRegistry) error

RegisterServiceDecorators allows the plugin to decorate core services

func (*Plugin) Service

func (p *Plugin) Service() *Service

Service returns the secrets service

func (*Plugin) Version

func (p *Plugin) Version() string

Version returns the plugin version

type PluginOption

type PluginOption func(*Plugin)

PluginOption is a functional option for configuring the plugin

func WithAuditEnabled

func WithAuditEnabled(enabled bool) PluginOption

WithAuditEnabled enables/disables audit logging

func WithConfigSourceEnabled

func WithConfigSourceEnabled(enabled bool) PluginOption

WithConfigSourceEnabled enables the Forge ConfigSource integration

func WithConfigSourcePrefix

func WithConfigSourcePrefix(prefix string) PluginOption

WithConfigSourcePrefix sets the config source prefix

func WithDefaultConfig

func WithDefaultConfig(cfg *Config) PluginOption

WithDefaultConfig sets the default configuration

func WithMasterKey

func WithMasterKey(key string) PluginOption

WithMasterKey sets the encryption master key

func WithMaxVersions

func WithMaxVersions(max int) PluginOption

WithMaxVersions sets the maximum versions to keep

type Repository

type Repository interface {
	// Secret CRUD operations
	Create(ctx context.Context, secret *schema.Secret) error
	FindByID(ctx context.Context, id xid.ID) (*schema.Secret, error)
	FindByPath(ctx context.Context, appID, envID xid.ID, path string) (*schema.Secret, error)
	List(ctx context.Context, appID, envID xid.ID, query *core.ListSecretsQuery) ([]*schema.Secret, int, error)
	Update(ctx context.Context, secret *schema.Secret) error
	Delete(ctx context.Context, id xid.ID) error
	HardDelete(ctx context.Context, id xid.ID) error

	// Version operations
	CreateVersion(ctx context.Context, version *schema.SecretVersion) error
	FindVersion(ctx context.Context, secretID xid.ID, version int) (*schema.SecretVersion, error)
	ListVersions(ctx context.Context, secretID xid.ID, page, pageSize int) ([]*schema.SecretVersion, int, error)
	DeleteOldVersions(ctx context.Context, secretID xid.ID, keepCount int) error

	// Access log operations
	LogAccess(ctx context.Context, log *schema.SecretAccessLog) error
	ListAccessLogs(ctx context.Context, secretID xid.ID, query *core.GetAccessLogsQuery) ([]*schema.SecretAccessLog, int, error)
	DeleteOldAccessLogs(ctx context.Context, olderThan time.Time) (int64, error)

	// Stats operations
	CountSecrets(ctx context.Context, appID, envID xid.ID) (int, error)
	CountVersions(ctx context.Context, appID, envID xid.ID) (int, error)
	GetSecretsByType(ctx context.Context, appID, envID xid.ID) (map[string]int, error)
	CountExpiringSecrets(ctx context.Context, appID, envID xid.ID, withinDays int) (int, error)
}

Repository defines the interface for secret storage operations

func NewRepository

func NewRepository(db *bun.DB) Repository

NewRepository creates a new repository instance

type RollbackRequest added in v0.0.7

type RollbackRequest struct {
	ID      string `path:"id" validate:"required"`
	Version string `path:"version" validate:"required"`
	Reason  string `json:"reason"`
}

type SchemaValidator

type SchemaValidator struct {
}

SchemaValidator validates secret values against JSON Schema and handles serialization/deserialization of different value types.

func NewSchemaValidator

func NewSchemaValidator() *SchemaValidator

NewSchemaValidator creates a new schema validator

func (*SchemaValidator) DeserializeValue

func (v *SchemaValidator) DeserializeValue(data []byte, valueType core.SecretValueType) (interface{}, error)

DeserializeValue deserializes stored bytes back to a value based on the value type

func (*SchemaValidator) DetectValueType

func (v *SchemaValidator) DetectValueType(value interface{}) core.SecretValueType

DetectValueType attempts to detect the value type from the value content

func (*SchemaValidator) ParseValue

func (v *SchemaValidator) ParseValue(raw string, valueType core.SecretValueType) (interface{}, error)

ParseValue parses a raw string value based on the value type

func (*SchemaValidator) SerializeValue

func (v *SchemaValidator) SerializeValue(value interface{}, valueType core.SecretValueType) ([]byte, error)

SerializeValue serializes a value for storage based on the value type

func (*SchemaValidator) ValidateSchema

func (v *SchemaValidator) ValidateSchema(schemaJSON string) error

ValidateSchema validates that a JSON schema is valid

func (*SchemaValidator) ValidateValue

func (v *SchemaValidator) ValidateValue(value interface{}, valueType core.SecretValueType, schemaJSON string) error

ValidateValue validates a value against an optional JSON schema. If schemaJSON is empty, only basic type validation is performed.

type SecretsConfigSource

type SecretsConfigSource struct {
	// contains filtered or unexported fields
}

SecretsConfigSource implements forge.ConfigSource to provide secrets as configuration

func NewSecretsConfigSource

func NewSecretsConfigSource(
	service *Service,
	appID, envID string,
	prefix string,
	priority int,
	logger forge.Logger,
) *SecretsConfigSource

NewSecretsConfigSource creates a new config source for an app/environment

func (*SecretsConfigSource) CacheSize

func (s *SecretsConfigSource) CacheSize() int

CacheSize returns the number of items in the cache

func (*SecretsConfigSource) ClearCache

func (s *SecretsConfigSource) ClearCache()

ClearCache clears the configuration cache

func (*SecretsConfigSource) Get

func (s *SecretsConfigSource) Get(key string) (interface{}, bool)

Get retrieves a configuration value by key from cache

func (*SecretsConfigSource) GetName

func (s *SecretsConfigSource) GetName() string

GetName returns the name (alias for Name)

func (*SecretsConfigSource) GetSecret

func (s *SecretsConfigSource) GetSecret(ctx context.Context, key string) (string, error)

GetSecret retrieves a secret value from the source

func (*SecretsConfigSource) GetString

func (s *SecretsConfigSource) GetString(key string) (string, bool)

GetString retrieves a string configuration value

func (*SecretsConfigSource) GetType

func (s *SecretsConfigSource) GetType() string

GetType returns the source type

func (*SecretsConfigSource) IsAvailable

func (s *SecretsConfigSource) IsAvailable(ctx context.Context) bool

IsAvailable checks if the source is available

func (*SecretsConfigSource) IsLoaded

func (s *SecretsConfigSource) IsLoaded() bool

IsLoaded returns whether the source has been loaded

func (*SecretsConfigSource) IsWatchable

func (s *SecretsConfigSource) IsWatchable() bool

IsWatchable returns true if the source supports watching for changes

func (*SecretsConfigSource) Keys

func (s *SecretsConfigSource) Keys() []string

Keys returns all available keys in the cache

func (*SecretsConfigSource) LastLoadTime

func (s *SecretsConfigSource) LastLoadTime() time.Time

LastLoadTime returns when the source was last loaded

func (*SecretsConfigSource) Load

func (s *SecretsConfigSource) Load(ctx context.Context) (map[string]interface{}, error)

Load loads configuration data from secrets

func (*SecretsConfigSource) Name

func (s *SecretsConfigSource) Name() string

Name returns the unique name of the configuration source

func (*SecretsConfigSource) Priority

func (s *SecretsConfigSource) Priority() int

Priority returns the priority of this source (higher = more important)

func (*SecretsConfigSource) Reload

func (s *SecretsConfigSource) Reload(ctx context.Context) error

Reload forces a reload of the configuration source

func (*SecretsConfigSource) StopWatch

func (s *SecretsConfigSource) StopWatch() error

StopWatch stops watching for configuration changes

func (*SecretsConfigSource) SupportsSecrets

func (s *SecretsConfigSource) SupportsSecrets() bool

SupportsSecrets returns true if the source supports secret management

func (*SecretsConfigSource) Watch

func (s *SecretsConfigSource) Watch(ctx context.Context, callback func(map[string]interface{})) error

Watch starts watching for configuration changes

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service provides secret management operations

func NewService

func NewService(
	repo Repository,
	encryption *EncryptionService,
	validator *SchemaValidator,
	auditSvc *audit.Service,
	config *Config,
	logger forge.Logger,
) *Service

NewService creates a new secrets service

func (*Service) Create

Create creates a new secret

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, id xid.ID) error

Delete soft-deletes a secret

func (*Service) Get

func (s *Service) Get(ctx context.Context, id xid.ID) (*core.SecretDTO, error)

Get retrieves a secret by ID (without value)

func (*Service) GetByPath

func (s *Service) GetByPath(ctx context.Context, path string) (*core.SecretDTO, error)

GetByPath retrieves a secret by path

func (*Service) GetStats

func (s *Service) GetStats(ctx context.Context) (*core.StatsDTO, error)

GetStats returns statistics about secrets

func (*Service) GetTree

func (s *Service) GetTree(ctx context.Context, prefix string) ([]*core.SecretTreeNode, error)

GetTree builds a tree structure of secrets

func (*Service) GetValue

func (s *Service) GetValue(ctx context.Context, id xid.ID) (interface{}, error)

GetValue retrieves and decrypts the secret value

func (*Service) GetValueByPath

func (s *Service) GetValueByPath(ctx context.Context, path string) (interface{}, error)

GetValueByPath retrieves and decrypts a secret by path

func (*Service) GetVersions

func (s *Service) GetVersions(ctx context.Context, id xid.ID, page, pageSize int) ([]*core.SecretVersionDTO, *pagination.Pagination, error)

GetVersions retrieves version history for a secret

func (*Service) GetWithValue

func (s *Service) GetWithValue(ctx context.Context, id xid.ID) (*core.SecretWithValueDTO, error)

GetWithValue retrieves a secret including its decrypted value

func (*Service) List

List lists secrets with filtering and pagination

func (*Service) Rollback

func (s *Service) Rollback(ctx context.Context, id xid.ID, targetVersion int, reason string) (*core.SecretDTO, error)

Rollback rolls back a secret to a previous version

func (*Service) Update

func (s *Service) Update(ctx context.Context, id xid.ID, req *core.UpdateSecretRequest) (*core.SecretDTO, error)

Update updates a secret and creates a new version

type SuccessResponse

type SuccessResponse struct {
	Success bool        `json:"success"`
	Message string      `json:"message,omitempty"`
	Data    interface{} `json:"data,omitempty"`
}

SuccessResponse is a generic success response

type UpdateSecretRequest added in v0.0.7

type UpdateSecretRequest struct {
	ID          string                 `path:"id" validate:"required"`
	Value       interface{}            `json:"value"`
	Description string                 `json:"description"`
	Tags        []string               `json:"tags"`
	Metadata    map[string]interface{} `json:"metadata"`
}

type VersioningConfig

type VersioningConfig struct {
	// MaxVersions is the maximum number of versions to keep per secret
	// When exceeded, old versions are automatically deleted
	// Default: 50
	MaxVersions int `json:"maxVersions" yaml:"maxVersions"`

	// RetentionDays is how long to keep old versions in days
	// Versions older than this are eligible for cleanup
	// Default: 90
	RetentionDays int `json:"retentionDays" yaml:"retentionDays"`

	// AutoCleanup enables automatic cleanup of old versions
	// Default: true
	AutoCleanup bool `json:"autoCleanup" yaml:"autoCleanup"`

	// CleanupInterval is how often to run version cleanup
	// Default: 24 hours
	CleanupInterval time.Duration `json:"cleanupInterval" yaml:"cleanupInterval"`
}

VersioningConfig holds versioning settings

Directories

Path Synopsis
Package core provides core types and utilities for the secrets plugin.
Package core provides core types and utilities for the secrets plugin.
Package schema defines the database schema for the secrets plugin.
Package schema defines the database schema for the secrets plugin.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL