serve

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: AGPL-3.0 Imports: 59 Imported by: 0

Documentation

Index

Constants

View Source
const (
	GrantTypeJWTBearer     = "urn:ietf:params:oauth:grant-type:jwt-bearer"
	GrantTypeAuthCode      = "authorization_code"
	GrantTypeTokenExchange = "urn:ietf:params:oauth:grant-type:token-exchange"
	AssertionTypeJWT       = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
	TokenTypeAIC           = "urn:ietf:params:oauth:token-type:aic+jwt"
	TokenTypeAccessToken   = "urn:ietf:params:oauth:token-type:access_token"
	TokenTypeBearer        = "Bearer"
)

OAuth grant and token type identifiers (RFC 6749 §3.2, RFC 7523, RFC 8693, RFC 9068).

View Source
const (
	PermCACreate = auth.PermCACreate
	PermCADelete = auth.PermCADelete
	PermCAList   = auth.PermCAList
	PermCAInfo   = auth.PermCAInfo

	PermCertIssue  = auth.PermCertIssue
	PermCertRevoke = auth.PermCertRevoke
	PermCertRenew  = auth.PermCertRenew
	PermCertList   = auth.PermCertList
	PermCertExport = auth.PermCertExport
	PermCertBatch  = auth.PermCertBatch

	PermCRLGenerate = auth.PermCRLGenerate

	PermUserManage = auth.PermUserManage
	PermUserList   = auth.PermUserList

	PermLogRead   = auth.PermLogRead
	PermLogExport = auth.PermLogExport

	PermReportView     = auth.PermReportView
	PermReportExport   = auth.PermReportExport
	PermReportGenerate = auth.PermReportGenerate

	PermConfigRead  = auth.PermConfigRead
	PermConfigWrite = auth.PermConfigWrite

	PermRAApprove = auth.PermRAApprove
	PermRAReject  = auth.PermRAReject

	PermCrossIssue  = auth.PermCrossIssue
	PermCrossRevoke = auth.PermCrossRevoke

	PermWebhookManage = auth.PermWebhookManage

	PermKeyRecover = auth.PermKeyRecover

	PermDNSManage = auth.PermDNSManage

	PermTrustImport = auth.PermTrustImport
	PermTrustList   = auth.PermTrustList
	PermTrustDelete = auth.PermTrustDelete

	PermAgentManage   = auth.PermAgentManage
	PermUserRevokeAll = auth.PermUserRevokeAll

	PermSwaggerView = auth.PermSwaggerView
	PermWebView     = auth.PermWebView
)

All 32 permission constants re-exported

Variables

View Source
var RolePermissions = auth.RolePermissions

RolePermissions re-exports auth.RolePermissions

Functions

func BasicAuthCacheKey

func BasicAuthCacheKey(username, salt, passwordHash string) string

BasicAuthCacheKey builds the cache key for a credential verification. Embedding the stored password hash means any password change invalidates the entry automatically. Exported so the provisioner path (cmd/pki TokenResolver) shares the same cache as the legacy authByBasic fallback.

func BasicAuthVerified

func BasicAuthVerified(cacheKey string) bool

BasicAuthVerified reports whether the credential encoded in cacheKey was successfully verified within basicAuthCacheTTL.

func BearerTokenOK

func BearerTokenOK(r *http.Request, expected string) bool

BearerTokenOK is a constant-time check of the request's bearer token against the expected value.

func HasPerm

func HasPerm(role string, perm Permission) bool

HasPerm re-exports auth.HasPerm

func LoadDefaultRouteRules

func LoadDefaultRouteRules() *routing.RouteRules

func NewMetricsHandler

func NewMetricsHandler(getEngine func() *engine.Engine, getDB func() *db.DB) http.Handler

NewMetricsHandler returns a standalone Prometheus exposition handler bound to the given engine and DB sources, for a dedicated internal scrape listener (serve.metrics_addr). getEngine and getDB may be nil (DB-only / CRL-only nodes keep the engine part absent; the DB source powers the inventory gauges).

func RecordOCSPResponse

func RecordOCSPResponse(caName, status string)

RecordOCSPResponse records a produced OCSP response with CA and status dimensions. Exported so the OCSP handler (constructed in cmd/pki) can wire its MetricsHook into the serve metrics registry.

func RememberBasicAuth

func RememberBasicAuth(cacheKey string)

RememberBasicAuth records that the credential encoded in cacheKey passed Argon2id verification. Expired entries are dropped opportunistically when the cache reaches basicAuthCacheMaxEntries; live entries are never evicted early.

func RequireMetricsToken

func RequireMetricsToken(h http.Handler, token func() string) http.Handler

RequireMetricsToken wraps h to demand `Authorization: Bearer <token>` on every request (constant-time compare) when the token is non-empty. The token is resolved per request via the given getter so SIGHUP hot-reloads of serve.metrics_token take effect without restarting the dedicated listener.

func Roles

func Roles() []string

Roles re-exports auth.RoleNames

func WrapHandler

func WrapHandler(s *Server) http.Handler

WrapHandler wraps the Server with access logging middleware.

func WrapHandlerWithMetrics

func WrapHandlerWithMetrics(s *Server) http.Handler

WrapHandlerWithMetrics wraps the Server with access logging and Prometheus metrics middleware.

Types

type AuthUser

type AuthUser struct {
	Username    string
	Role        string
	Permissions []Permission
	CAScopes    []string
	// CertIdentity records the client certificate identity bound to the current session.
	// nil means this authentication did not carry a certificate (e.g. token/Basic login),
	// and only the username can serve as an identity anchor.
	CertIdentity *provisioner.CertIdentity
}

AuthUser represents an authenticated user.

func (*AuthUser) HasPerm

func (u *AuthUser) HasPerm(perm Permission) bool

type CAStats

type CAStats struct {
	Name       string `json:"name"`
	Certs      int    `json:"certs"`
	Revoked    int    `json:"revoked"`
	Expiring30 int    `json:"expiring_30d"`
	Subject    string `json:"subject"`
	NotAfter   string `json:"not_after"`
	Algorithm  string `json:"algorithm"`
}

type DashboardStats

type DashboardStats struct {
	Summary       SummaryStats   `json:"summary"`
	PerCA         []CAStats      `json:"per_ca,omitempty"`
	Expiry        ExpiryBuckets  `json:"expiry"`
	Trends        TrendStats     `json:"trends,omitempty"`
	KeyTypes      map[string]int `json:"key_types,omitempty"`
	Profiles      map[string]int `json:"profiles,omitempty"`
	NearestExpiry *NearestExpiry `json:"nearest_expiry,omitempty"`
	UpdatedAt     string         `json:"updated_at"`
}

DashboardStats is the complete PKI statistics response.

type ExpiryBuckets

type ExpiryBuckets struct {
	Within30d  int `json:"within_30d"`
	Within60d  int `json:"within_60d"`
	Within90d  int `json:"within_90d"`
	Within180d int `json:"within_180d"`
	Within365d int `json:"within_365d"`
	Over365d   int `json:"over_365d"`
}

type NearestExpiry

type NearestExpiry struct {
	CommonName   string `json:"common_name"`
	SerialNumber string `json:"serial_number"`
	CAName       string `json:"ca_name"`
	NotAfter     string `json:"not_after"`
	DaysLeft     int    `json:"days_left"`
}

NearestExpiry holds the certificate closest to expiration.

type Permission

type Permission = auth.Permission

Permission re-exports auth.Permission

type RateLimiter

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

func NewRateLimiter

func NewRateLimiter(rps float64, burst int) *RateLimiter

NewRateLimiter creates a per-IP rate limiter with the given requests-per-second and burst size. Stale visitors are cleaned up every minute.

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(ip string) bool

func (*RateLimiter) AllowCA

func (rl *RateLimiter) AllowCA(ip, ca string) bool

AllowCA is like Allow but scopes the limiter per (ip, ca) so that a single CA cannot be flooded through one source IP independently of other CAs.

type RecordBuffer

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

RecordBuffer batches certificate records, flushing to DB after reaching threshold records or maxLatency. Features WAL write-ahead logging (crash safe), MaxPending hard limit (backpressure), and MaxLatency (maximum delay).

func NewRecordBuffer

func NewRecordBuffer(getDB func() *db.DB, threshold int, maxPending int32, maxLatency time.Duration, walPath string) (*RecordBuffer, error)

NewRecordBuffer creates a record buffer. getDB: retrieves the current DB pointer (supports hot reload) threshold: record count that triggers a flush (recommended 100) maxPending: hard limit on pending records, Add returns false when exceeded (recommended 5000) maxLatency: maximum wait time before forced flush (recommended 500ms) walPath: WAL file path, empty string = WAL disabled (crash unsafe)

func (*RecordBuffer) Add

func (rb *RecordBuffer) Add(rec *db.CertRecord) bool

Add adds a certificate record to the buffer. Returns false when the buffer is full; the caller should return HTTP 503. maxPending<=0 disables backpressure, always returns true.

func (*RecordBuffer) IsFull

func (rb *RecordBuffer) IsFull() bool

IsFull returns whether the buffer is full (for pre-check backpressure). maxPending<=0 means backpressure is disabled (never returns true).

func (*RecordBuffer) Stop

func (rb *RecordBuffer) Stop()

Stop stops the background goroutine, flushes remaining records, and closes the WAL. It blocks until run() has fully drained and closed the WAL, so callers can be certain the previous goroutine is no longer touching the file before a reload creates a new RecordBuffer over the same WAL (H4 fix).

type Server

type Server struct {
	Version string
	// contains filtered or unexported fields
}

func NewFull

func NewFull(cfg *internal.Config, database *db.DB, b *i18n.Bundle, tsaH, ocspH http.Handler) *Server

NewFull creates a full Server with TSA and OCSP handlers, async job queue, and rate limiter support. Used by the main serve command.

func NewPublic

func NewPublic(cfg *internal.Config, database *db.DB, b *i18n.Bundle) *Server

NewPublic creates a Server restricted to public-only routes (health, cert distribution, static files). Used by modular serve mode.

func (*Server) CapRegistry

func (s *Server) CapRegistry() *capregistry.CapabilityRegistry

CapRegistry returns the current capability registry (may be nil).

func (*Server) Config

func (s *Server) Config() *internal.Config

Engine returns the resident memory engine, or nil when disabled. Exported for wiring read-side lookups (OCSP, metrics) outside the package.

func (*Server) Database

func (s *Server) Database() *db.DB

func (*Server) EnableEngine

func (s *Server) EnableEngine(cfg *internal.Config) error

EnableEngine builds the resident memory engine over the current DB and starts its background janitor. Idempotent: a second call stops the previous engine first. Returns the build error; the server keeps working with DB-only reads/writes when the engine cannot be rebuilt.

func (*Server) EnableRecordBuffer

func (s *Server) EnableRecordBuffer(cfg *internal.Config) error

EnableRecordBuffer creates the RecordBuffer for this server from cfg and starts its background flusher. Idempotent: a second call replaces the existing buffer (flushing it first). Returns the creation error; the server keeps working with synchronous writes when this fails.

func (*Server) Engine

func (s *Server) Engine() *engine.Engine

func (*Server) EngineEnabled

func (s *Server) EngineEnabled() bool

EngineEnabled reports whether the resident memory engine is currently active.

func (*Server) FlushRecordBuffer

func (s *Server) FlushRecordBuffer()

FlushRecordBuffer synchronously flushes all buffered records to the DB. Used before read-modify-write operations (e.g. revocation) so that recently issued-but-unflushed certificates are visible to the DB, avoiding the ≤500ms visibility window between issue and bulk insert. When the memory engine owns the write pipeline its pending writes are flushed instead.

func (*Server) GetTSAConfig

func (s *Server) GetTSAConfig() *tsa.RuntimeConfig

GetTSAConfig returns the TSA RuntimeConfig, or nil if not set.

func (*Server) KeepEngine

func (s *Server) KeepEngine(newDB *db.DB)

KeepEngine repoints a running memory engine at a new DB handle without rebuilding its in-memory index. It is used on config reload when the underlying store has not changed (same DB DSN): reads keep being served from the resident index and writes converge through the new handle, avoiding the multi-second full-rebuild read cliff on large stores. No-op when the engine is not enabled.

func (*Server) Reload

func (s *Server) Reload(cfg *internal.Config, database *db.DB, tsaH, ocspH http.Handler)

Reload refreshes runtime state (route rules, identity source) after config changes. The route rule set is re-read from the (possibly updated) config, honoring routes_file.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*Server) SetCapRegistry

func (s *Server) SetCapRegistry(cr *capregistry.CapabilityRegistry)

SetCapRegistry sets the capability registry (single source of truth). Passing nil disables capability registration validation.

func (*Server) SetConfigPath

func (s *Server) SetConfigPath(path string)

func (*Server) SetProvisioners

func (s *Server) SetProvisioners(reg *provisioner.Registry)

func (*Server) SetRateLimiter

func (s *Server) SetRateLimiter(rl *RateLimiter)

func (*Server) SetRouteRules

func (s *Server) SetRouteRules(rr *routing.RouteRules)

func (*Server) SetTSAConfig

func (s *Server) SetTSAConfig(rc *tsa.RuntimeConfig)

SetTSAConfig stores the TSA RuntimeConfig for management API access.

func (*Server) StartCARotationMonitor

func (s *Server) StartCARotationMonitor(interval time.Duration) func()

StartCARotationMonitor periodically checks every configured CA's active certificate for approaching expiry and logs a warning, so operators rotate the CA master key before it lapses (rotation itself is performed via the POST /api/v1/ca/{name}/rotate API). Returns a stop function.

func (*Server) StopEngine

func (s *Server) StopEngine()

StopEngine flushes pending engine writes and shuts down the memory engine. No-op when the engine was never enabled.

func (*Server) StopRecordBuffer

func (s *Server) StopRecordBuffer()

StopRecordBuffer flushes buffered records and stops the background flusher. No-op when the buffer was never enabled.

type Stats

type Stats struct {
	TotalCerts   int            `json:"total_certs"`
	ByStatus     map[string]int `json:"by_status"`
	Expiring30d  int            `json:"expiring_30d"`
	TotalCAs     int            `json:"total_cas"`
	RevokedRatio float64        `json:"revoked_ratio"`
	UpdatedAt    string         `json:"updated_at"`
}

---- Legacy Stats (backward compat) ----

type SummaryStats

type SummaryStats struct {
	TotalCerts   int     `json:"total_certs"`
	TotalCAs     int     `json:"total_cas"`
	Valid        int     `json:"valid"`
	Revoked      int     `json:"revoked"`
	Expired      int     `json:"expired"`
	Expiring30d  int     `json:"expiring_30d"`
	RevokedRatio float64 `json:"revoked_ratio"`
}

type TrendStats

type TrendStats struct {
	IssuedToday     int `json:"issued_today"`
	IssuedThisWeek  int `json:"issued_this_week"`
	IssuedThisMonth int `json:"issued_this_month"`
	RevokedToday    int `json:"revoked_today"`
}

Jump to

Keyboard shortcuts

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