Skip to content

Commit

Permalink
added istrumentation for webhooks
Browse files Browse the repository at this point in the history
  • Loading branch information
azazeal committed Jan 22, 2024
1 parent 230be9b commit 264caad
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 44 deletions.
16 changes: 12 additions & 4 deletions authority/authority.go
Original file line number Diff line number Diff line change
Expand Up @@ -971,11 +971,19 @@ func (a *Authority) startCRLGenerator() error {
//nolint:gocritic // used in defered statements
func (a *Authority) incrProvisionerCounter(p *provisioner.Interface, err *error, count func(Meter, string, bool)) {
var name string
if p != nil {
if prov := *p; prov != nil {
name = prov.GetName()
}
if prov := *p; prov != nil {
name = prov.GetName()
}

count(a.meter, name, err == nil || *err == nil)
}

//nolint:gocritic // used in defered statements
func (a *Authority) incrWebhookCounter(prov provisioner.Interface, err error, count func(Meter, string, bool)) {
var name string
if prov != nil {
name = prov.GetName()
}

count(a.meter, name, err == nil)
}
28 changes: 22 additions & 6 deletions authority/meter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ type Meter interface {
// X509Rekeyed is called whenever a X509 certificate is rekeyed.
X509Rekeyed(provisioner string, success bool)

// X509Authorized is called whenever a X509 authoring webhook is called.
X509Authorized(provisioner string, success bool)

// X509Enriched is called whenever a X509 enriching webhook is called.
X509Enriched(provisioner string, success bool)

// SSHSigned is called whenever a SSH CSR is signed.
SSHSigned(provisioner string, success bool)

Expand All @@ -19,14 +25,24 @@ type Meter interface {

// SSHRekeyed is called whenever a SSH certificate is rekeyed.
SSHRekeyed(provisioner string, success bool)

// SSHAuthorized is called whenever a SSH authoring webhook is called.
SSHAuthorized(provisioner string, success bool)

// SSHEnriched is called whenever a SSH enriching webhook is called.
SSHEnriched(provisioner string, success bool)
}

// noopMeter implements a noop [Meter].
type noopMeter struct{}

func (noopMeter) SSHRekeyed(string, bool) {}
func (noopMeter) SSHRenewed(string, bool) {}
func (noopMeter) SSHSigned(string, bool) {}
func (noopMeter) X509Rekeyed(string, bool) {}
func (noopMeter) X509Renewed(string, bool) {}
func (noopMeter) X509Signed(string, bool) {}
func (noopMeter) SSHRekeyed(string, bool) {}
func (noopMeter) SSHRenewed(string, bool) {}
func (noopMeter) SSHSigned(string, bool) {}
func (noopMeter) SSHAuthorized(string, bool) {}
func (noopMeter) SSHEnriched(string, bool) {}
func (noopMeter) X509Rekeyed(string, bool) {}
func (noopMeter) X509Renewed(string, bool) {}
func (noopMeter) X509Signed(string, bool) {}
func (noopMeter) X509Authorized(string, bool) {}
func (noopMeter) X509Enriched(string, bool) {}
38 changes: 23 additions & 15 deletions authority/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func (a *Authority) SignSSH(_ context.Context, key ssh.PublicKey, opts provision
}

// Call enriching webhooks
if err = callEnrichingWebhooksSSH(webhookCtl, cr); err != nil {
if err = a.callEnrichingWebhooksSSH(prov, webhookCtl, cr); err != nil {
err = errs.ApplyOptions(
errs.ForbiddenErr(err, err.Error()),
errs.WithKeyVal("signOptions", signOpts),
Expand Down Expand Up @@ -301,7 +301,7 @@ func (a *Authority) SignSSH(_ context.Context, key ssh.PublicKey, opts provision
}

// Send certificate to webhooks for authorization
if err = callAuthorizingWebhooksSSH(webhookCtl, certificate, certTpl); err != nil {
if err = a.callAuthorizingWebhooksSSH(prov, webhookCtl, certificate, certTpl); err != nil {
err = errs.ApplyOptions(
errs.ForbiddenErr(err, "authority.SignSSH: error signing certificate"),
)
Expand Down Expand Up @@ -719,28 +719,36 @@ func (a *Authority) getAddUserCommand(principal string) string {
return strings.ReplaceAll(cmd, "<principal>", principal)
}

func callEnrichingWebhooksSSH(webhookCtl webhookController, cr sshutil.CertificateRequest) error {
func (a *Authority) callEnrichingWebhooksSSH(prov provisioner.Interface, webhookCtl webhookController, cr sshutil.CertificateRequest) (err error) {
if webhookCtl == nil {
return nil
}
whEnrichReq, err := webhook.NewRequestBody(

var whEnrichReq *webhook.RequestBody
if whEnrichReq, err = webhook.NewRequestBody(
webhook.WithSSHCertificateRequest(cr),
)
if err != nil {
return err
); err == nil {
err = webhookCtl.Enrich(whEnrichReq)

a.incrWebhookCounter(prov, err, Meter.SSHEnriched)
}
return webhookCtl.Enrich(whEnrichReq)

return
}

func callAuthorizingWebhooksSSH(webhookCtl webhookController, cert *sshutil.Certificate, certTpl *ssh.Certificate) error {
func (a *Authority) callAuthorizingWebhooksSSH(prov provisioner.Interface, webhookCtl webhookController, cert *sshutil.Certificate, certTpl *ssh.Certificate) (err error) {
if webhookCtl == nil {
return nil
return
}
whAuthBody, err := webhook.NewRequestBody(

var whAuthBody *webhook.RequestBody
if whAuthBody, err = webhook.NewRequestBody(
webhook.WithSSHCertificate(cert, certTpl),
)
if err != nil {
return err
); err == nil {
err = webhookCtl.Authorize(whAuthBody)

a.incrWebhookCounter(prov, err, Meter.SSHAuthorized)
}
return webhookCtl.Authorize(whAuthBody)

return
}
42 changes: 26 additions & 16 deletions authority/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Sign
}
}

if err = callEnrichingWebhooksX509(webhookCtl, attData, csr); err != nil {
if err = a.callEnrichingWebhooksX509(prov, webhookCtl, attData, csr); err != nil {
err = errs.ApplyOptions(
errs.ForbiddenErr(err, err.Error()),
errs.WithKeyVal("csr", csr),
Expand Down Expand Up @@ -283,7 +283,7 @@ func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Sign
}

// Send certificate to webhooks for authorization
if err = callAuthorizingWebhooksX509(webhookCtl, crt, leaf, attData); err != nil {
if err = a.callAuthorizingWebhooksX509(prov, webhookCtl, crt, leaf, attData); err != nil {
err = errs.ApplyOptions(
errs.ForbiddenErr(err, "error creating certificate"),
opts...,
Expand Down Expand Up @@ -1004,42 +1004,52 @@ func templatingError(err error) error {
return errors.Wrap(cause, "error applying certificate template")
}

func callEnrichingWebhooksX509(webhookCtl webhookController, attData *provisioner.AttestationData, csr *x509.CertificateRequest) error {
func (a *Authority) callEnrichingWebhooksX509(prov provisioner.Interface, webhookCtl webhookController, attData *provisioner.AttestationData, csr *x509.CertificateRequest) (err error) {
if webhookCtl == nil {
return nil
return
}

var attested *webhook.AttestationData
if attData != nil {
attested = &webhook.AttestationData{
PermanentIdentifier: attData.PermanentIdentifier,
}
}
whEnrichReq, err := webhook.NewRequestBody(

var whEnrichReq *webhook.RequestBody
if whEnrichReq, err = webhook.NewRequestBody(
webhook.WithX509CertificateRequest(csr),
webhook.WithAttestationData(attested),
)
if err != nil {
return err
); err == nil {
err = webhookCtl.Enrich(whEnrichReq)

a.incrWebhookCounter(prov, err, Meter.X509Enriched)
}
return webhookCtl.Enrich(whEnrichReq)

return
}

func callAuthorizingWebhooksX509(webhookCtl webhookController, cert *x509util.Certificate, leaf *x509.Certificate, attData *provisioner.AttestationData) error {
func (a *Authority) callAuthorizingWebhooksX509(prov provisioner.Interface, webhookCtl webhookController, cert *x509util.Certificate, leaf *x509.Certificate, attData *provisioner.AttestationData) (err error) {
if webhookCtl == nil {
return nil
return
}

var attested *webhook.AttestationData
if attData != nil {
attested = &webhook.AttestationData{
PermanentIdentifier: attData.PermanentIdentifier,
}
}
whAuthBody, err := webhook.NewRequestBody(

var whAuthBody *webhook.RequestBody
if whAuthBody, err = webhook.NewRequestBody(
webhook.WithX509Certificate(cert, leaf),
webhook.WithAttestationData(attested),
)
if err != nil {
return err
); err == nil {
err = webhookCtl.Authorize(whAuthBody)

a.incrWebhookCounter(prov, err, Meter.X509Authorized)
}
return webhookCtl.Authorize(whAuthBody)

return
}
37 changes: 34 additions & 3 deletions internal/metrix/meter.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ func (m *Meter) SSHSigned(provisioner string, success bool) {
count(m.ssh.signed, provisioner, success)
}

// SSHAuthorized implements [authority.Meter] for [Meter].
func (m *Meter) SSHAuthorized(provisioner string, success bool) {
count(m.ssh.authorized, provisioner, success)
}

// SSHEnriched implements [authority.Meter] for [Meter].
func (m *Meter) SSHEnriched(provisioner string, success bool) {
count(m.ssh.enriched, provisioner, success)
}

// X509Rekeyed implements [authority.Meter] for [Meter].
func (m *Meter) X509Rekeyed(provisioner string, success bool) {
count(m.x509.rekeyed, provisioner, success)
Expand All @@ -94,6 +104,16 @@ func (m *Meter) X509Signed(provisioner string, success bool) {
count(m.x509.signed, provisioner, success)
}

// X509Authorized implements [authority.Meter] for [Meter].
func (m *Meter) X509Authorized(provisioner string, success bool) {
count(m.x509.authorized, provisioner, success)
}

// X509Enriched implements [authority.Meter] for [Meter].
func (m *Meter) X509Enriched(provisioner string, success bool) {
count(m.x509.enriched, provisioner, success)
}

func count(cv *prometheus.CounterVec, provisioner string, success bool) {
cv.WithLabelValues(provisioner, strconv.FormatBool(success)).Inc()
}
Expand All @@ -103,19 +123,30 @@ type provisioner struct {
rekeyed *prometheus.CounterVec
renewed *prometheus.CounterVec
signed *prometheus.CounterVec

authorized *prometheus.CounterVec
enriched *prometheus.CounterVec
}

func newProvisioner(subsystem string) *provisioner {
return &provisioner{
rekeyed: newCounterVec(subsystem, "rekeyed_total", "Number of X509 certificates rekeyed",
rekeyed: newCounterVec(subsystem, "rekeyed_total", "Number of certificates rekeyed",
"provisioner",
"success",
),
renewed: newCounterVec(subsystem, "renewed_total", "Number of certificates renewed",
"provisioner",
"success",
),
signed: newCounterVec(subsystem, "signed_total", "Number of CSRs signed",
"provisioner",
"success",
),
renewed: newCounterVec(subsystem, "renewed_total", "Number of X509 certificates renewed",
authorized: newCounterVec(subsystem, "authorized_total", "Number of authorizing webhooks called",
"provisioner",
"success",
),
signed: newCounterVec(subsystem, "signed_total", "Number of X509 CSRs signed",
enriched: newCounterVec(subsystem, "enriched_total", "Number of enriching webhooks called",
"provisioner",
"success",
),
Expand Down

0 comments on commit 264caad

Please sign in to comment.