secrets

package
v0.0.16 Latest Latest
Warning

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

Go to latest
Published: Feb 11, 2026 License: Apache-2.0 Imports: 41 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"

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

Variables

This section is empty.

Functions

func FormatValue

func FormatValue(value any, 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 CreateSecretInput added in v0.0.15

type CreateSecretInput struct {
	AppID       string   `json:"appId"`
	Path        string   `json:"path"`
	Value       any      `json:"value"`
	Description string   `json:"description"`
	ValueType   string   `json:"valueType"`
	Tags        []string `json:"tags"`
}

CreateSecretInput is the input for creating a secret.

type CreateSecretOutput added in v0.0.15

type CreateSecretOutput struct {
	Secret SecretItem `json:"secret"`
}

CreateSecretOutput is the output for creating a secret.

type CreateSecretRequest added in v0.0.7

type CreateSecretRequest struct {
	Path        string         `json:"path"        validate:"required"`
	Value       any            `json:"value"       validate:"required"`
	ValueType   string         `json:"valueType"   validate:"required"`
	Description string         `json:"description"`
	Tags        []string       `json:"tags"`
	Metadata    map[string]any `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) BridgeFunctions added in v0.0.15

func (e *DashboardExtension) BridgeFunctions() []ui.BridgeFunction

BridgeFunctions returns bridge functions for the secrets plugin.

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(ctx *router.PageContext) (g.Node, error)

HandleCreateSecret handles the create secret form submission.

func (*DashboardExtension) HandleDeleteSecret

func (e *DashboardExtension) HandleDeleteSecret(ctx *router.PageContext) (g.Node, error)

HandleDeleteSecret handles the delete secret action.

func (*DashboardExtension) HandleRevealValue

func (e *DashboardExtension) HandleRevealValue(ctx *router.PageContext) (g.Node, error)

HandleRevealValue handles the reveal value AJAX request.

func (*DashboardExtension) HandleRollback

func (e *DashboardExtension) HandleRollback(ctx *router.PageContext) (g.Node, error)

HandleRollback handles the rollback action.

func (*DashboardExtension) HandleUpdateSecret

func (e *DashboardExtension) HandleUpdateSecret(ctx *router.PageContext) (g.Node, 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 Note: All secrets routes use /secrets/ prefix (not /settings/secrets/) to ensure they get the dashboard layout instead of settings layout.

func (*DashboardExtension) ServeCreateSecretPage

func (e *DashboardExtension) ServeCreateSecretPage(ctx *router.PageContext) (g.Node, error)

ServeCreateSecretPage serves the create secret page.

func (*DashboardExtension) ServeEditSecretPage

func (e *DashboardExtension) ServeEditSecretPage(ctx *router.PageContext) (g.Node, error)

ServeEditSecretPage serves the edit secret page.

func (*DashboardExtension) ServeSecretDetailPage

func (e *DashboardExtension) ServeSecretDetailPage(ctx *router.PageContext) (g.Node, error)

ServeSecretDetailPage serves the secret detail page.

func (*DashboardExtension) ServeSecretsListPage

func (e *DashboardExtension) ServeSecretsListPage(ctx *router.PageContext) (g.Node, error)

ServeSecretsListPage serves the secrets list page.

func (*DashboardExtension) ServeVersionHistoryPage

func (e *DashboardExtension) ServeVersionHistoryPage(ctx *router.PageContext) (g.Node, error)

ServeVersionHistoryPage serves the version history page.

func (*DashboardExtension) SettingsPages

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

SettingsPages returns settings pages Note: Secrets is a main navigation item (not a settings page), so we return nil here.

func (*DashboardExtension) SettingsSections

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

SettingsSections returns settings sections (deprecated).

type DeleteSecretInput added in v0.0.15

type DeleteSecretInput struct {
	AppID    string `json:"appId"`
	SecretID string `json:"secretId"`
}

DeleteSecretInput is the input for deleting a secret.

type DeleteSecretOutput added in v0.0.15

type DeleteSecretOutput struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
}

DeleteSecretOutput is the output for deleting a secret.

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 GetSecretInput added in v0.0.15

type GetSecretInput struct {
	AppID    string `json:"appId"`
	SecretID string `json:"secretId"`
}

GetSecretInput is the input for getting a secret.

type GetSecretOutput added in v0.0.15

type GetSecretOutput struct {
	Secret SecretItem `json:"secret"`
}

GetSecretOutput is the output for getting a secret.

type GetSecretRequest added in v0.0.7

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

type GetSecretsInput added in v0.0.15

type GetSecretsInput struct {
	AppID    string `json:"appId"`
	Page     int    `json:"page"`
	PageSize int    `json:"pageSize"`
	Search   string `json:"search"`
}

GetSecretsInput is the input for listing secrets.

type GetSecretsOutput added in v0.0.15

type GetSecretsOutput struct {
	Secrets    []SecretItem `json:"secrets"`
	Total      int64        `json:"total"`
	Page       int          `json:"page"`
	PageSize   int          `json:"pageSize"`
	TotalPages int          `json:"totalPages"`
}

GetSecretsOutput is the output for listing secrets.

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"`
}

ListSecretsRequest represents 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) Priority 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 RevealSecretInput added in v0.0.15

type RevealSecretInput struct {
	AppID    string `json:"appId"`
	SecretID string `json:"secretId"`
}

RevealSecretInput is the input for revealing a secret.

type RevealSecretOutput added in v0.0.15

type RevealSecretOutput struct {
	Value     any    `json:"value"`
	ValueType string `json:"valueType"`
}

RevealSecretOutput is the output for revealing a secret.

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) (any, error)

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

func (*SchemaValidator) DetectValueType

func (v *SchemaValidator) DetectValueType(value any) 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) (any, error)

ParseValue parses a raw string value based on the value type.

func (*SchemaValidator) SerializeValue

func (v *SchemaValidator) SerializeValue(value any, 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 any, 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 SecretItem added in v0.0.15

type SecretItem struct {
	ID          string   `json:"id"`
	Path        string   `json:"path"`
	Key         string   `json:"key"`
	Description string   `json:"description"`
	ValueType   string   `json:"valueType"`
	Tags        []string `json:"tags"`
	Version     int      `json:"version"`
	CreatedAt   string   `json:"createdAt"`
	UpdatedAt   string   `json:"updatedAt"`
}

SecretItem represents a secret in the list.

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) (any, 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]any, 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]any)) 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) (any, error)

GetValue retrieves and decrypts the secret value.

func (*Service) GetValueByPath

func (s *Service) GetValueByPath(ctx context.Context, path string) (any, 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    any    `json:"data,omitempty"`
}

SuccessResponse is a generic success response.

type UpdateSecretInput added in v0.0.15

type UpdateSecretInput struct {
	AppID        string   `json:"appId"`
	SecretID     string   `json:"secretId"`
	Value        any      `json:"value"`
	Description  string   `json:"description"`
	Tags         []string `json:"tags"`
	ChangeReason string   `json:"changeReason"`
}

UpdateSecretInput is the input for updating a secret.

type UpdateSecretOutput added in v0.0.15

type UpdateSecretOutput struct {
	Secret SecretItem `json:"secret"`
}

UpdateSecretOutput is the output for updating a secret.

type UpdateSecretRequest added in v0.0.7

type UpdateSecretRequest struct {
	ID          string         `path:"id"          validate:"required"`
	Value       any            `json:"value"`
	Description string         `json:"description"`
	Tags        []string       `json:"tags"`
	Metadata    map[string]any `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