Documentation
¶
Overview ¶
Package admission implements the Fleetsweeper ValidatingAdmissionWebhook. It compares pod specs presented to the API server against a baseline derived from the fleet's most recent scan and either warns (advisory mode) or denies (enforce mode) when a pod deviates from the fleet norm.
Index ¶
Constants ¶
const Threshold = 0.70
Threshold is the minimum baseline fraction that activates a check. Above this fraction, a violation is meaningful; below it, the fleet itself is inconsistent and the check stays quiet.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Baseline ¶
type Baseline struct {
// SamplePods is the number of pods analyzed.
SamplePods int `json:"sample_pods" yaml:"sample_pods"`
// SampleContainers is the number of containers analyzed.
SampleContainers int `json:"sample_containers" yaml:"sample_containers"`
// DigestPinFraction is the share of containers using @sha256: digest pins.
DigestPinFraction float64 `json:"digest_pin_fraction" yaml:"digest_pin_fraction"`
// NonRootFraction is the share of containers not declared to run as UID 0.
NonRootFraction float64 `json:"non_root_fraction" yaml:"non_root_fraction"`
// NoPrivilegeEscalationFraction is the share of containers with
// allowPrivilegeEscalation set false (the PSS-restricted check).
NoPrivilegeEscalationFraction float64 `json:"no_privilege_escalation_fraction" yaml:"no_privilege_escalation_fraction"`
// NamedServiceAccountFraction is the share of pods using a named
// ServiceAccount (not "default").
NamedServiceAccountFraction float64 `json:"named_service_account_fraction" yaml:"named_service_account_fraction"`
// ReadOnlyRootFSFraction is the share of containers with
// readOnlyRootFilesystem=true.
ReadOnlyRootFSFraction float64 `json:"read_only_root_fs_fraction" yaml:"read_only_root_fs_fraction"`
// SourceScanID is the scan the baseline was derived from.
SourceScanID string `json:"source_scan_id,omitempty" yaml:"source_scan_id,omitempty"`
}
Baseline is the fleet-derived norm the webhook checks against. The numbers express the fraction of containers across the fleet's most recent scan that satisfy each property; values close to 1 mean almost every container is doing the safe thing.
func (Baseline) Sufficient ¶
Sufficient reports whether the baseline has enough data to make a confident comparison. The webhook short-circuits to allow when the baseline is too thin so a freshly-installed Fleetsweeper does not block every admission against an empty norm.
type BaselineProvider ¶
type BaselineProvider interface {
// Current returns the latest Baseline. Implementations may return a
// zero-value Baseline with Sufficient()==false when the store has no
// usable data yet; callers should treat that as "allow without
// comment."
Current(ctx context.Context) Baseline
}
BaselineProvider supplies a current Baseline. The webhook handler caches the result for cacheTTL so a high-throughput admission rate does not rebuild the baseline on every request.
type CertSource ¶
type CertSource struct {
// contains filtered or unexported fields
}
CertSource supplies the admission server's serving certificate and keeps it fresh. File-backed certificates are reloaded from disk when the files change, which supports cert-manager rotating a mounted secret. Generated certificates are issued from an in-memory CA and reissued before expiry, so the caBundle handed to the apiserver stays valid for the CA's lifetime.
func NewCertSource ¶
func NewCertSource(certPath, keyPath string, dnsNames []string) (*CertSource, error)
NewCertSource loads the file-backed keypair when both paths are set, or generates a CA and serving certificate covering dnsNames when either path is empty. The error covers unreadable files and generation failures.
func (*CertSource) CABundle ¶
func (s *CertSource) CABundle() []byte
CABundle returns the PEM-encoded bundle the apiserver should trust: the file contents for file-backed certs, or the generated CA otherwise. Stable across leaf rotations.
func (*CertSource) GetCertificate ¶
func (s *CertSource) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error)
GetCertificate implements the tls.Config hook. It refreshes the certificate at most once per certCheckInterval: file-backed certs reload when the files' modification times change, generated certs reissue when the leaf is within selfSignedRotateBefore of expiry. Refresh failures fall back to the cached certificate so a transient filesystem error does not break handshakes.
type Check ¶
type Check interface {
// Name identifies the check in log lines and metrics.
Name() string
// Evaluate returns warnings and (when applicable) a deny message.
// An empty warnings slice means the pod is consistent with the fleet.
Evaluate(pod *corev1.Pod, baseline Baseline) (warnings []string, denyReason string)
}
Check is one fleet-norm comparator. The webhook runs every registered Check against the incoming pod, aggregates the warnings, and (in enforce mode) denies admission when at least one check fires.
func DefaultChecks ¶
func DefaultChecks() []Check
DefaultChecks returns the built-in fleet-norm checks. They lean on the image-audit and workload-sec scanners' aggregate outputs, which the baseline provider converts into per-property fractions.
type Decision ¶
type Decision struct {
// Allowed mirrors the AdmissionResponse.Allowed semantic. Always true
// when mode is advisory.
Allowed bool
// Reason is a short message returned to the client when Allowed is false.
Reason string
// Warnings are the per-check messages surfaced as Kubernetes warnings.
Warnings []string
}
Decision is the outcome of evaluating a pod against the baseline.
type Handler ¶
type Handler struct {
// Provider supplies the fleet baseline.
Provider BaselineProvider
// Checks is the ordered list of fleet-norm checks to evaluate.
Checks []Check
// Mode selects advisory vs enforce semantics.
Mode Mode
// Log is the structured logger.
Log *zap.Logger
// MaxBytes caps the request body the handler will read. Defaults to
// 1 MiB which matches the apiserver's default.
MaxBytes int64
}
Handler serves the /admission/validate endpoint. One instance per process. Safe for concurrent use; the underlying baseline cache is guarded internally.
type Mode ¶
type Mode string
Mode selects whether the webhook warns or denies on baseline deviations.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server runs the admission webhook HTTP server. Lifecycle mirrors the main fleetsweeper server: ListenAndServeTLS until the supplied context cancels, then Shutdown.
func NewServer ¶
func NewServer(cfg ServerConfig) (*Server, error)
NewServer prepares the admission server's TLS material and HTTP wiring. Call Run to start serving.
type ServerConfig ¶
type ServerConfig struct {
// Addr is the listen address (typically ":8443").
Addr string
// CertPath is an optional path to a PEM-encoded TLS certificate. When
// empty a fresh self-signed cert is generated.
CertPath string
// KeyPath is the matching private key path.
KeyPath string
// DNSNames are the SANs to include on a generated certificate. The
// ValidatingWebhookConfiguration must address the service via one of
// these names.
DNSNames []string
// Handler is the admission handler.
Handler *Handler
// Log is the structured logger.
Log *zap.Logger
}
ServerConfig configures the admission HTTP server.
type StoreBaselineProvider ¶
type StoreBaselineProvider struct {
// contains filtered or unexported fields
}
StoreBaselineProvider derives the Baseline from the most recent scan stored in the Fleetsweeper database. The provider caches the result so admission traffic does not re-derive the baseline more than once per cacheTTL window.
func NewStoreBaselineProvider ¶
func NewStoreBaselineProvider(s store.Store, ttl time.Duration) *StoreBaselineProvider
NewStoreBaselineProvider returns a provider against the given store with the specified cache lifetime. ttl <= 0 defaults to 60 seconds.