Skip to content

Conversation

@carlosmonastyrski
Copy link
Contributor

Description 📣

This PR introduces certificate management capabilities to the Infisical Agent. It adds support for:

  • Issuing certificates, either by manually specifying all fields or by supplying a CSR
  • Automatically renewing certificates that were not issued via CSR
  • Executing post-event hooks
  • Storing all generated certificate files in the configured destination directory

Type ✨

  • Bug fix
  • New feature
  • Improvement
  • Breaking change
  • Documentation

Tests 🛠️

# Here's some code block to paste some code snippets

@greptile-apps
Copy link

greptile-apps bot commented Dec 6, 2025

Greptile Overview

Greptile Summary

This PR extends the Infisical Agent from a secrets management tool to also handle PKI certificate lifecycle management. The changes introduce comprehensive certificate management capabilities including automated issuance, renewal, and file management. The implementation adds new API models for certificate operations (IssueCertificateRequest, CertificateAttributes, etc.) and corresponding API client functions for issuing, retrieving, and renewing certificates. The core functionality is integrated into the agent's main monitoring loop, providing concurrent certificate lifecycle management alongside existing secrets operations.

The certificate management engine supports both manual certificate specification and CSR-based workflows, implements configurable renewal policies to prevent expiration, and includes post-event hooks for downstream system integration (like reloading web servers). A new configuration file demonstrates practical usage with nginx integration, and the implementation follows the agent's existing architectural patterns of concurrent goroutines, unified configuration management, and graceful shutdown handling.

Important Files Changed

Filename Score Overview
packages/api/model.go 5/5 Adds comprehensive certificate management data structures and API models
packages/api/api.go 4/5 Implements certificate management API client functions for PKI operations
certificate-agent-config.yaml 4/5 New configuration file demonstrating certificate management setup with post-hooks
packages/cmd/agent.go 4/5 Integrates certificate lifecycle management into the main agent workflow

Confidence score: 3/5

  • This PR introduces complex certificate management functionality but may have potential security and operational risks that need careful review
  • Score reflects concerns about command execution security in post-hooks, missing input validation on certificate parameters, and lack of comprehensive testing documentation
  • Pay close attention to the post-hooks command execution in certificate-agent-config.yaml and certificate validation logic in packages/cmd/agent.go

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

CertificateRequestID string `json:"certificateRequestId,omitempty"`
}

type GetCertificateRequestResponse struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it seems there is a lint issue here

} `yaml:"config"`
}

type Certificate struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to name this as AgentCertificateConfig likewise appending everything with agent

}

return tm.infisicalClient.Auth().UniversalAuthLogin(clientID, clientSecret)
log.Debug().Msgf("calling UniversalAuthLogin with clientID: %s", clientID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

log.Error().Msgf("UniversalAuthLogin failed: %v", err)
return infisicalSdk.MachineIdentityCredential{}, err
}
log.Debug().Msg("UniversalAuthLogin succeeded")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise here

return

case "failed":
log.Error().Msgf("certificate %s renewal failed", displayName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to add additional context on which certificate this error corresponds to like certificateId, commonName Like a standardize format for all the logs shown here. This is because as user can setup multiple certs, they may not understand the source of this error

}

func (tm *AgentManager) PollCertificateRequest(certificateId int, certificate *Certificate) {
displayName := tm.getCertificateDisplayName(certificateId, certificate)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing mutex hold

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh I saw it below. Same comment. It's better move it here

return true
}

if renewBefore, err := parseDurationWithDays(cert.RenewBeforeExpiry); err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling for invalid days

}

func (tm *AgentManager) ExecutePostHook(command string, timeoutSecs int64, hookType string, certificateId int, certificate *Certificate) {
if command == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing mutex

func (tm *AgentManager) ShouldRenewCertificate(certificateId int) bool {
state := tm.certificateStates[certificateId]

if state.Status != "active" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we show an error message incase the certificate is revoked or expired?

}

func (tm *AgentManager) WriteCertificateFiles(certificate *Certificate, response *api.CertificateResponse) error {
destPath := certificate.DestinationPath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing mutex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants