admin

package
v0.2.6 Latest Latest
Warning

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

Go to latest
Published: Mar 26, 2026 License: Apache-2.0 Imports: 33 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MaskSensitiveHeaders added in v0.2.0

func MaskSensitiveHeaders(h http.Header) http.Header

MaskSensitiveHeaders masks common sensitive headers (e.g. Authorization/Cookie/API keys). This is used for debug capture display to avoid exposing tokens directly in the admin UI.

Types

type Admin

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

Admin handles the web UI HTTP endpoints

func New

func New(cfg *config.Manager, sess *session.Manager, ca *cert.CA, certPath, keyPath string) *Admin

New creates a new Admin handler

func (*Admin) Close added in v0.2.2

func (a *Admin) Close()

Close releases resources held by the admin component (currently only the audit DB).

func (*Admin) Debug added in v0.2.0

func (a *Admin) Debug() *DebugStore

Debug returns the debug capture store (in-memory only; not persisted).

func (*Admin) GetStats

func (a *Admin) GetStats() *StatsCollector

GetStats returns the stats collector for external incrementing

func (*Admin) Handler

func (a *Admin) Handler() http.Handler

Handler returns the HTTP handler for the admin UI

func (*Admin) RecordAudit

func (a *Admin) RecordAudit(ev AuditEvent) AuditEvent

RecordAudit records one audit event about whether redaction rules were hit.

func (*Admin) SetStartTime

func (a *Admin) SetStartTime(unix int64)

SetStartTime records when the proxy started

func (*Admin) UpdateAudit

func (a *Admin) UpdateAudit(id int64, fn func(*AuditEvent)) (AuditEvent, bool)

UpdateAudit updates a previously recorded audit event (e.g. to fill response status fields).

type AuditEvent

type AuditEvent struct {
	ID int64 `json:"id"`
	// Time is the server time (RFC3339) for sorting and debugging.
	Time time.Time `json:"time"`

	Host        string `json:"host"`
	Method      string `json:"method"`
	Path        string `json:"path"`
	ContentType string `json:"content_type"`
	// ContentEncoding is the request body's Content-Encoding (empty means uncompressed/unknown).
	ContentEncoding string `json:"content_encoding,omitempty"`

	// Attempted indicates whether this request entered the "redactable text body" scanning flow.
	Attempted bool `json:"attempted"`
	// RedactedCount is the number of replacements performed (matches may be truncated for display, but the count is accurate).
	RedactedCount int          `json:"redacted_count"`
	Matches       []AuditMatch `json:"matches"`

	// Note explains why scanning was skipped (e.g. no_body / not_text / too_large / read_error).
	Note string `json:"note,omitempty"`

	// ResponseStatus is the upstream response status code (0 if no response).
	ResponseStatus int `json:"response_status,omitempty"`
	// ResponseContentType is the upstream response Content-Type (empty means unknown/no response).
	ResponseContentType string `json:"response_content_type,omitempty"`
	// RestoreApplied indicates whether placeholder restore was attempted on the response side (text responses like JSON/SSE).
	RestoreApplied bool `json:"restore_applied,omitempty"`
	// RestoredCount is the number of placeholders restored in the response (rough count: matched placeholder tokens).
	RestoredCount int `json:"restored_count,omitempty"`
}

AuditEvent represents an audit record for a proxy request (used to visualize whether redaction rules were hit).

type AuditMatch

type AuditMatch struct {
	Category    string `json:"category"`
	Placeholder string `json:"placeholder"`
	// Value is the "display value": when privacy mode is enabled it is a preview (masked/truncated),
	// otherwise it is the original (still truncated).
	Value string `json:"value"`
	// IsPreview indicates whether Value is a preview (true in privacy mode).
	IsPreview bool `json:"is_preview"`
	// Length is the length of the original hit (before truncation), useful for validating expected matches.
	Length int `json:"length"`
	// Truncated indicates whether Value was truncated due to length.
	Truncated bool `json:"truncated"`
}

AuditMatch represents a sensitive fragment hit in a request (for admin UI display).

type AuditResponse

type AuditResponse struct {
	RedactLog bool         `json:"redact_log"`
	MaxEvents int          `json:"max_events"`
	Events    []AuditEvent `json:"events"`
}

type AuditStore

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

func NewAuditStore

func NewAuditStore(max int) *AuditStore

func (*AuditStore) Add

func (s *AuditStore) Add(ev AuditEvent) AuditEvent

func (*AuditStore) BumpNextID added in v0.2.2

func (s *AuditStore) BumpNextID(min int64)

BumpNextID raises nextID to at least min (never decreases). Used after enabling persistence so in-memory IDs continue from the persisted max ID, avoiding conflicts.

func (*AuditStore) Clear

func (s *AuditStore) Clear()

func (*AuditStore) List

func (s *AuditStore) List(limit int) []AuditEvent

func (*AuditStore) Subscribe

func (s *AuditStore) Subscribe(buf int) (ch <-chan AuditEvent, cancel func())

func (*AuditStore) Update

func (s *AuditStore) Update(id int64, fn func(*AuditEvent)) (AuditEvent, bool)

Update finds an event by ID and mutates it in-place. If updated, the updated event will be broadcast to subscribers (as an "audit_event" again), allowing the UI to merge by ID.

type AuthManager

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

func NewAuthManager

func NewAuthManager(filePath string) *AuthManager

func (*AuthManager) CreateSessionLocked

func (a *AuthManager) CreateSessionLocked() (token string, expiresAt time.Time, err error)

func (*AuthManager) DestroySession

func (a *AuthManager) DestroySession(r *http.Request)

func (*AuthManager) IsConfigured

func (a *AuthManager) IsConfigured() bool

func (*AuthManager) Require

func (a *AuthManager) Require(w http.ResponseWriter, r *http.Request) bool

func (*AuthManager) Setup

func (a *AuthManager) Setup(password string) error

func (*AuthManager) Status

func (a *AuthManager) Status(r *http.Request) (configured bool, authenticated bool, broken bool, brokenErr string)

func (*AuthManager) Verify

func (a *AuthManager) Verify(password string) error

type AuthStatusResponse

type AuthStatusResponse struct {
	Configured    bool   `json:"configured"`
	Authenticated bool   `json:"authenticated"`
	Broken        bool   `json:"broken"`
	BrokenError   string `json:"broken_error,omitempty"`
}

type CertResponse

type CertResponse struct {
	CA struct {
		Subject           string `json:"subject"`
		NotBefore         string `json:"not_before"`
		NotAfter          string `json:"not_after"`
		FingerprintSHA256 string `json:"fingerprint_sha256"`
		IsTrusted         bool   `json:"is_trusted"`
		// TrustStatus indicates trust detection result for the current runtime environment:
		// - trusted: detected as trusted
		// - untrusted: detected as not trusted
		// - unknown: cannot reliably detect (e.g. running inside a container; cannot tell if the host/browser trusts the exported ca.crt)
		TrustStatus string `json:"trust_status"`
		CertPath    string `json:"cert_path"`
	} `json:"ca"`
}

CertResponse represents the certificate API response

type DebugBody added in v0.2.0

type DebugBody struct {
	Text      string `json:"text"`
	Bytes     int    `json:"bytes"`
	Truncated bool   `json:"truncated"`
}

type DebugEvent added in v0.2.0

type DebugEvent struct {
	ID   int64     `json:"id"`
	Time time.Time `json:"time"`

	Host   string `json:"host"`
	Method string `json:"method"`
	Path   string `json:"path"`
	URL    string `json:"url,omitempty"`

	Request  DebugHTTP `json:"request"`
	Response DebugHTTP `json:"response"`
}

type DebugEventSummary added in v0.2.0

type DebugEventSummary struct {
	ID   int64     `json:"id"`
	Time time.Time `json:"time"`

	Host   string `json:"host"`
	Method string `json:"method"`
	Path   string `json:"path"`
	URL    string `json:"url,omitempty"`

	HasRequest  bool `json:"has_request"`
	HasResponse bool `json:"has_response"`

	RequestTruncated  bool `json:"request_truncated,omitempty"`
	ResponseTruncated bool `json:"response_truncated,omitempty"`

	ResponseStatus      int    `json:"response_status,omitempty"`
	ResponseContentType string `json:"response_content_type,omitempty"`
}

type DebugHTTP added in v0.2.0

type DebugHTTP struct {
	HeadersOriginal  http.Header `json:"headers_original,omitempty"`
	HeadersForwarded http.Header `json:"headers_forwarded,omitempty"`
	BodyOriginal     DebugBody   `json:"body_original,omitempty"`
	BodyForwarded    DebugBody   `json:"body_forwarded,omitempty"`
	ContentType      string      `json:"content_type,omitempty"`
	ContentEncoding  string      `json:"content_encoding,omitempty"`
	ResponseStatus   int         `json:"response_status,omitempty"`
}

type DebugRequestCapture added in v0.2.0

type DebugRequestCapture struct {
	Time   time.Time
	Host   string
	Method string
	Path   string
	URL    string

	ContentType     string
	ContentEncoding string

	HeadersOriginal  http.Header
	HeadersForwarded http.Header

	BodyOriginalText  string
	BodyOriginalBytes int
	BodyOriginalTrunc bool

	BodyForwardedText  string
	BodyForwardedBytes int
	BodyForwardedTrunc bool
}

type DebugResponseCapture added in v0.2.0

type DebugResponseCapture struct {
	ContentType string

	// Keep status/code on DebugHTTP (ResponseStatus) to avoid extra nesting.
	Status int

	HeadersOriginal  http.Header
	HeadersForwarded http.Header

	BodyUpstreamText  string
	BodyUpstreamBytes int
	BodyUpstreamTrunc bool

	BodyClientText  string
	BodyClientBytes int
	BodyClientTrunc bool
}

type DebugStatus added in v0.2.0

type DebugStatus struct {
	Enabled      bool `json:"enabled"`
	MaxBodyBytes int  `json:"max_body_bytes"`
	MaxEvents    int  `json:"max_events"`
	MaskHeaders  bool `json:"mask_headers"`
	Count        int  `json:"count"`
}

type DebugStore added in v0.2.0

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

DebugStore is used for capture-style debugging: it keeps full request/response snapshots (including before/after).

Security constraints: - in-memory only; never persisted to disk - disabled by default; must be explicitly enabled in the admin UI - local debugging only; sensitive headers are still masked (configurable)

func NewDebugStore added in v0.2.0

func NewDebugStore(maxEvents int) *DebugStore

func (*DebugStore) Clear added in v0.2.0

func (s *DebugStore) Clear()

func (*DebugStore) Enabled added in v0.2.0

func (s *DebugStore) Enabled() bool

func (*DebugStore) Get added in v0.2.0

func (s *DebugStore) Get(id int64) (DebugEvent, bool)

func (*DebugStore) List added in v0.2.0

func (s *DebugStore) List(limit int) []DebugEventSummary

func (*DebugStore) MaskHeaders added in v0.2.0

func (s *DebugStore) MaskHeaders() bool

func (*DebugStore) MaxBodyBytes added in v0.2.0

func (s *DebugStore) MaxBodyBytes() int

func (*DebugStore) Status added in v0.2.0

func (s *DebugStore) Status() DebugStatus

func (*DebugStore) Update added in v0.2.0

func (s *DebugStore) Update(enabled *bool, maxBodyBytes *int, maxEvents *int, maskHeaders *bool) DebugStatus

func (*DebugStore) UpsertRequest added in v0.2.0

func (s *DebugStore) UpsertRequest(id int64, c DebugRequestCapture)

func (*DebugStore) UpsertResponse added in v0.2.0

func (s *DebugStore) UpsertResponse(id int64, c DebugResponseCapture)

type LogsResponse

type LogsResponse struct {
	ConfiguredPath string   `json:"configured_path"`
	EffectivePath  string   `json:"effective_path"`
	Exists         bool     `json:"exists"`
	Lines          []string `json:"lines"`
	Warning        string   `json:"warning,omitempty"`
}

type NERSettings added in v0.2.2

type NERSettings struct {
	Enabled     bool     `json:"enabled"`
	PresidioURL string   `json:"presidio_url"`
	Language    string   `json:"language"`
	Entities    []string `json:"entities"`
	MinScore    float64  `json:"min_score"`
}

type PatternsResponse

type PatternsResponse struct {
	Keywords    []config.KeywordPattern   `json:"keywords"`
	Exclude     []string                  `json:"exclude"`
	SecretFiles []config.SecretFileConfig `json:"secret_files"`
}

PatternsResponse represents the patterns API response

type RuleListItem added in v0.2.0

type RuleListItem struct {
	ID       string `json:"id"`
	Name     string `json:"name"`
	Path     string `json:"path,omitempty"`
	URL      string `json:"url,omitempty"`
	Kind     string `json:"kind"` // local|subscription
	Enabled  bool   `json:"enabled"`
	Priority int    `json:"priority"`
	Exists   bool   `json:"exists"`

	// Subscription-only fields (for displaying subscription health in the admin UI).
	Verified  bool   `json:"verified,omitempty"`
	LastError string `json:"last_error,omitempty"`
	CheckedAt int64  `json:"checked_at,omitempty"`
	UpdatedAt int64  `json:"updated_at,omitempty"`
}

type RuleListsResponse added in v0.2.0

type RuleListsResponse struct {
	RuleLists []RuleListItem `json:"rule_lists"`
}

type SessionMapping

type SessionMapping struct {
	Placeholder string `json:"placeholder"`
	Category    string `json:"category"`
	CreatedAt   string `json:"created_at,omitempty"`
	ExpiresAt   string `json:"expires_at,omitempty"`
}

SessionMapping represents a single session mapping (without original value)

type SessionsResponse

type SessionsResponse struct {
	Total                     int              `json:"total"`
	Mappings                  []SessionMapping `json:"mappings"`
	DeterministicPlaceholders bool             `json:"deterministic_placeholders"`
}

SessionsResponse represents the sessions API response

type SettingsProxyPayload added in v0.2.5

type SettingsProxyPayload struct {
	WebSocketRedactionBeta bool `json:"websocket_redaction_beta"`
}

type SettingsResponse

type SettingsResponse struct {
	Lang  string               `json:"lang"`
	Proxy SettingsProxyPayload `json:"proxy"`
}

type StatsCollector

type StatsCollector struct {
	TotalRequests    atomic.Int64
	RedactedRequests atomic.Int64
	RestoredRequests atomic.Int64
	Errors           atomic.Int64
}

StatsCollector tracks request statistics

type StatsResponse

type StatsResponse struct {
	Proxy struct {
		Status        string `json:"status"`
		UptimeSeconds int64  `json:"uptime_seconds"`
		ListenAddress string `json:"listen_address"`
	} `json:"proxy"`
	Session struct {
		ActiveMappings int `json:"active_mappings"`
		MaxMappings    int `json:"max_mappings"`
		TTLSeconds     int `json:"ttl_seconds"`
	} `json:"session"`
	Requests struct {
		Total    int64 `json:"total"`
		Redacted int64 `json:"redacted"`
		Restored int64 `json:"restored"`
		Errors   int64 `json:"errors"`
	} `json:"requests"`
}

StatsResponse represents the stats API response

Jump to

Keyboard shortcuts

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