Documentation
¶
Index ¶
- func NewChallengeRenewHandler(cfg ChallengeRenewConfig) http.Handler
- func NewEnrollHandler(cfg EnrollConfig) http.Handler
- func NewRenewHandler(cfg RenewConfig) http.Handler
- func RequireMTLS(store Store, next http.Handler) http.Handler
- func RequireMTLSWithLogger(store Store, next http.Handler, logger *slog.Logger) http.Handler
- func ServerIdentity(ctx context.Context) *imprint.Enrollment
- type CA
- type CAConfig
- type ChallengeRenewConfig
- type EnrollConfig
- type ListFilter
- type MemStore
- func (s *MemStore) Delete(_ context.Context, serverID string) error
- func (s *MemStore) EnrollDevice(_ context.Context, fingerprint string, newEnrollment *imprint.Enrollment) (*imprint.Enrollment, bool, error)
- func (s *MemStore) GetByFingerprint(_ context.Context, fingerprint string) (*imprint.Enrollment, error)
- func (s *MemStore) GetByServerID(_ context.Context, serverID string) (*imprint.Enrollment, error)
- func (s *MemStore) IsRevoked(_ context.Context, serialNumber string) (bool, error)
- func (s *MemStore) List(_ context.Context, filter ListFilter) ([]*imprint.Enrollment, error)
- func (s *MemStore) Revoke(_ context.Context, serverID string) error
- func (s *MemStore) SaveEnrollment(_ context.Context, e *imprint.Enrollment) error
- func (s *MemStore) UpdateLastSeen(_ context.Context, serverID string, ip string) error
- type RenewConfig
- type Store
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewChallengeRenewHandler ¶
func NewChallengeRenewHandler(cfg ChallengeRenewConfig) http.Handler
NewChallengeRenewHandler returns an http.Handler that processes Tier 2 challenge-based renewal. This endpoint is public (no mTLS) and requires proof of possession of the old private key via a signature.
All validation failures return a generic 401 to prevent oracle attacks. Specific failure reasons are logged server-side only.
func NewEnrollHandler ¶
func NewEnrollHandler(cfg EnrollConfig) http.Handler
NewEnrollHandler returns an http.Handler that processes device enrollment requests.
func NewRenewHandler ¶
func NewRenewHandler(cfg RenewConfig) http.Handler
NewRenewHandler returns an http.Handler that processes Tier 1 mTLS certificate renewal requests. The client must present a valid (not expired) client certificate via mTLS. Identity is extracted from the certificate CN.
func RequireMTLS ¶
RequireMTLS returns middleware that enforces a valid client certificate on every request. The enrollment must exist, be active, and the certificate serial must match the enrollment record (preventing use of superseded certs after renewal). The enrollment is injected into the request context.
func RequireMTLSWithLogger ¶
RequireMTLSWithLogger is like RequireMTLS but accepts a custom logger.
func ServerIdentity ¶
func ServerIdentity(ctx context.Context) *imprint.Enrollment
ServerIdentity extracts the enrollment record from the request context. Returns nil if the request was not authenticated via mTLS.
Types ¶
type CA ¶
type CA struct {
// contains filtered or unexported fields
}
CA manages an internal certificate authority for signing client enrollment CSRs.
func (*CA) CertPool ¶
CertPool returns an x509.CertPool containing the CA certificate, suitable for use in tls.Config.ClientCAs.
func (*CA) ServerTLSConfig ¶
ServerTLSConfig returns a tls.Config that verifies client certificates signed by this CA. ClientAuth is set to VerifyClientCertIfGiven so that unauthenticated routes (enrollment, health) still work.
func (*CA) SignCSR ¶
func (ca *CA) SignCSR(csr *x509.CertificateRequest, serverID string) (certPEM []byte, serialHex string, err error)
SignCSR signs a PKCS#10 CSR and returns a PEM-encoded client certificate. The certificate CN is set to the given serverID, and a SAN URI of imprint://server/<serverID> is added.
type CAConfig ¶
type CAConfig struct {
CertDir string // directory to store/load CA cert and key
Organization string // organization name in the CA certificate subject
Validity time.Duration // client certificate validity; 0 = default (1 year)
}
CAConfig controls CA initialization.
type ChallengeRenewConfig ¶
type ChallengeRenewConfig struct {
CA *CA
Store Store
ChallengeWindow time.Duration // max time after cert expiry to allow challenge renewal; 0 disables
Logger *slog.Logger
}
ChallengeRenewConfig configures the challenge-based renewal handler (Tier 2).
type EnrollConfig ¶
type EnrollConfig struct {
CA *CA
Store Store
BuildSecrets []string // allowlist of valid build secrets
Mode imprint.EnrollMode // ModeAuto, ModeToken, ModeApproval
Logger *slog.Logger
}
EnrollConfig configures the enrollment handler.
type ListFilter ¶
type ListFilter struct {
Status string // if non-empty, only return enrollments with this status
Limit int // max results; 0 means no limit
Offset int // for pagination
}
ListFilter controls which enrollments are returned by List.
type MemStore ¶
type MemStore struct {
// contains filtered or unexported fields
}
MemStore is an in-memory Store implementation for testing.
func (*MemStore) EnrollDevice ¶
func (s *MemStore) EnrollDevice(_ context.Context, fingerprint string, newEnrollment *imprint.Enrollment) (*imprint.Enrollment, bool, error)
EnrollDevice atomically checks for an existing enrollment by fingerprint. If found, it returns the existing record. Otherwise it persists newEnrollment. The write lock is held across the entire check-and-save to prevent races.
func (*MemStore) GetByFingerprint ¶
func (s *MemStore) GetByFingerprint(_ context.Context, fingerprint string) (*imprint.Enrollment, error)
GetByFingerprint returns the first enrollment matching the fingerprint, or nil.
func (*MemStore) GetByServerID ¶
GetByServerID returns the enrollment for the given server ID, or nil.
func (*MemStore) IsRevoked ¶
IsRevoked reports whether the given certificate serial belongs to a revoked enrollment.
func (*MemStore) List ¶
func (s *MemStore) List(_ context.Context, filter ListFilter) ([]*imprint.Enrollment, error)
func (*MemStore) SaveEnrollment ¶
SaveEnrollment stores a copy of the enrollment keyed by ServerID.
type RenewConfig ¶
RenewConfig configures the mTLS renewal handler (Tier 1).
type Store ¶
type Store interface {
// SaveEnrollment persists an enrollment record, inserting or updating by ServerID.
SaveEnrollment(ctx context.Context, e *imprint.Enrollment) error
// GetByFingerprint returns the enrollment matching the given fingerprint, or nil if none exists.
GetByFingerprint(ctx context.Context, fingerprint string) (*imprint.Enrollment, error)
// GetByServerID returns the enrollment matching the given server ID, or nil if none exists.
GetByServerID(ctx context.Context, serverID string) (*imprint.Enrollment, error)
// EnrollDevice atomically looks up an existing enrollment by fingerprint,
// or persists newEnrollment if none exists. Returns the enrollment and
// whether it was newly created. Implementations must ensure that concurrent
// calls with the same fingerprint never create duplicate records.
EnrollDevice(ctx context.Context, fingerprint string, newEnrollment *imprint.Enrollment) (enrolled *imprint.Enrollment, created bool, err error)
// List returns enrollments matching the given filter criteria.
List(ctx context.Context, filter ListFilter) ([]*imprint.Enrollment, error)
// Revoke marks the enrollment for the given server ID as revoked.
Revoke(ctx context.Context, serverID string) error
// IsRevoked checks whether a certificate serial number belongs to a revoked
// enrollment. Note: RequireMTLS does not call this method (it checks enrollment
// status and serial match directly via GetByServerID). This method remains
// available for direct consumer use.
IsRevoked(ctx context.Context, serialNumber string) (bool, error)
// UpdateLastSeen records the current time and remote IP for the given server ID.
UpdateLastSeen(ctx context.Context, serverID string, ip string) error
// Delete removes the enrollment record for the given server ID.
Delete(ctx context.Context, serverID string) error
}
Store persists enrollment records. Consumers provide their own implementation (SQLite, Postgres, etc.). An in-memory implementation is provided for testing.