Skip to content

Commit

Permalink
add support for notifications, parsing monitored identities for input
Browse files Browse the repository at this point in the history
Signed-off-by: linus-sun <[email protected]>
  • Loading branch information
linus-sun committed Oct 30, 2024
1 parent c8635a5 commit a6fef6b
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 21 deletions.
59 changes: 47 additions & 12 deletions cmd/monitor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,58 @@
package main

import (
"context"
"fmt"
"time"

"github.com/sigstore/rekor-monitor/pkg/identity"
"github.com/sigstore/rekor-monitor/pkg/notifications"
)

type IdentityMonitorConfiguration struct {
StartIndex *int `yaml:"startIndex"`
EndIndex *int `yaml:"endIndex"`
MonitoredValues identity.MonitoredValues `yaml:"monitoredValues"`
ServerURL string `yaml:"serverURL"`
OutputIdentitiesFile string `yaml:"outputIdentities"`
LogInfoFile string `yaml:"logInfoFile"`
IdentityMetadataFile *string `yaml:"identityMetadataFile"`
GitHubIssue notifications.GitHubIssueInput `yaml:"githubIssue"`
EmailNotificationSMTP notifications.EmailNotificationInput `yaml:"emailNotificationSMTP"`
EmailNotificationMailgun notifications.MailgunNotificationInput `yaml:"emailNotificationMailgun"`
EmailNotificationSendGrid notifications.SendGridNotificationInput `yaml:"emailNotificationSendGrid"`
Interval *time.Duration `yaml:"interval"`
StartIndex *int `yaml:"startIndex"`
EndIndex *int `yaml:"endIndex"`
MonitoredValues identity.MonitoredValues `yaml:"monitoredValues"`
ServerURL string `yaml:"serverURL"`
OutputIdentitiesFile string `yaml:"outputIdentities"`
LogInfoFile string `yaml:"logInfoFile"`
IdentityMetadataFile *string `yaml:"identityMetadataFile"`
GitHubIssue *notifications.GitHubIssueInput `yaml:"githubIssue"`
EmailNotificationSMTP *notifications.EmailNotificationInput `yaml:"emailNotificationSMTP"`
EmailNotificationMailgun *notifications.MailgunNotificationInput `yaml:"emailNotificationMailgun"`
EmailNotificationSendGrid *notifications.SendGridNotificationInput `yaml:"emailNotificationSendGrid"`
Interval *time.Duration `yaml:"interval"`
}

func CreateNotificationPool(config IdentityMonitorConfiguration) []notifications.NotificationPlatform {
// update this as new notification platforms are implemented within rekor-monitor
notificationPlatforms := []notifications.NotificationPlatform{}
if config.GitHubIssue != nil {
notificationPlatforms = append(notificationPlatforms, config.GitHubIssue)
}

if config.EmailNotificationSMTP != nil {
notificationPlatforms = append(notificationPlatforms, config.EmailNotificationSMTP)
}

if config.EmailNotificationSendGrid != nil {
notificationPlatforms = append(notificationPlatforms, config.EmailNotificationSendGrid)
}

if config.EmailNotificationMailgun != nil {
notificationPlatforms = append(notificationPlatforms, config.EmailNotificationMailgun)
}

return notificationPlatforms
}

func TriggerNotifications(notificationPlatforms []notifications.NotificationPlatform, identities []identity.MonitoredIdentity) error {
// update this as new notification platforms are implemented within rekor-monitor
for _, notificationPlatform := range notificationPlatforms {
if err := notificationPlatform.Send(context.Background(), identities); err != nil {
return fmt.Errorf("error sending notification from platform: %v", err)
}
}

return nil
}
2 changes: 1 addition & 1 deletion cmd/monitor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func main() {
}

// TODO: This should subsequently read from the identity metadata file to fetch the latest index.
err := rekor.IdentitySearch(*config.StartIndex, *config.EndIndex, rekorClient, config.MonitoredValues, config.OutputIdentitiesFile, config.IdentityMetadataFile)
_, err := rekor.IdentitySearch(*config.StartIndex, *config.EndIndex, rekorClient, config.MonitoredValues, config.OutputIdentitiesFile, config.IdentityMetadataFile)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to successfully complete identity search: %v", err)
return
Expand Down
20 changes: 20 additions & 0 deletions pkg/identity/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,26 @@ func PrintMonitoredIdentities(monitoredIdentities []MonitoredIdentity) ([]byte,
return jsonBody, nil
}

// CreateIdentitiesList takes in a MonitoredValues input and returns a list of all currently monitored identities.
// It returns a list of strings.
func CreateIdentitiesList(mvs MonitoredValues) []string {
identities := []string{}

for _, certID := range mvs.CertificateIdentities {
identities = append(identities, certID.CertSubject)
identities = append(identities, certID.Issuers...)
}

identities = append(identities, mvs.Fingerprints...)
identities = append(identities, mvs.Subjects...)

for _, oidMatcher := range mvs.OIDMatchers {
identities = append(identities, oidMatcher.ExtensionValues...)
}

return identities
}

// CreateMonitoredIdentities takes in a list of IdentityEntries and groups them by
// associated identity based on an input list of identities to monitor.
// It returns a list of MonitoredIdentities.
Expand Down
16 changes: 9 additions & 7 deletions pkg/rekor/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,23 +374,23 @@ func GetCheckpointIndices(logInfo *models.LogInfo, prevCheckpoint *util.SignedCh
return startIndex, endIndex
}

func IdentitySearch(startIndex int, endIndex int, rekorClient *client.Rekor, monitoredValues identity.MonitoredValues, outputIdentitiesFile string, idMetadataFile *string) error {
func IdentitySearch(startIndex int, endIndex int, rekorClient *client.Rekor, monitoredValues identity.MonitoredValues, outputIdentitiesFile string, idMetadataFile *string) ([]identity.MonitoredIdentity, error) {

entries, err := GetEntriesByIndexRange(context.Background(), rekorClient, startIndex, endIndex)
if err != nil {
return fmt.Errorf("error getting entries by index range: %v", err)
return nil, fmt.Errorf("error getting entries by index range: %v", err)
}
idEntries, err := MatchedIndices(entries, monitoredValues)
if err != nil {
return fmt.Errorf("error finding log indices: %v", err)
return nil, fmt.Errorf("error finding log indices: %v", err)
}

if len(idEntries) > 0 {
for _, idEntry := range idEntries {
fmt.Fprintf(os.Stderr, "Found %s\n", idEntry.String())

if err := file.WriteIdentity(outputIdentitiesFile, idEntry); err != nil {
return fmt.Errorf("failed to write entry: %v", err)
return nil, fmt.Errorf("failed to write entry: %v", err)
}
}
}
Expand All @@ -403,11 +403,13 @@ func IdentitySearch(startIndex int, endIndex int, rekorClient *client.Rekor, mon
}
err = file.WriteIdentityMetadata(*idMetadataFile, idMetadata)
if err != nil {
return fmt.Errorf("failed to write id metadata: %v", err)
return nil, fmt.Errorf("failed to write id metadata: %v", err)
}
}

return nil
identities := identity.CreateIdentitiesList(monitoredValues)
monitoredIdentities := identity.CreateMonitoredIdentities(idEntries, identities)
return monitoredIdentities, nil
}

// writeIdentitiesBetweenCheckpoints monitors for given identities between two checkpoints and writes any found identities to file.
Expand All @@ -417,7 +419,7 @@ func writeIdentitiesBetweenCheckpoints(logInfo *models.LogInfo, prevCheckpoint *

// Search for identities in the log range
if identity.MonitoredValuesExist(monitoredValues) {
err := IdentitySearch(startIndex, endIndex, rekorClient, monitoredValues, outputIdentitiesFile, nil)
_, err := IdentitySearch(startIndex, endIndex, rekorClient, monitoredValues, outputIdentitiesFile, nil)
if err != nil {
return fmt.Errorf("error monitoring for identities: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/test/identity_workflow/identity_workflow_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func TestIdentitySearch(t *testing.T) {
t.Errorf("expected checkpoint size of 2, received size %d", checkpoint.Size)
}

err = rekor.IdentitySearch(0, 1, rekorClient, monitoredVals, tempOutputIdentitiesFileName, nil)
_, err = rekor.IdentitySearch(0, 1, rekorClient, monitoredVals, tempOutputIdentitiesFileName, nil)
if err != nil {
log.Fatal(err.Error())
}
Expand Down

0 comments on commit a6fef6b

Please sign in to comment.