sdk

package module
v0.0.2-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2024 License: Apache-2.0 Imports: 0 Imported by: 0

README

SDK

Smithy's SDK.

Component

The component package can be used to write Smithy components that represents Vulnerability Findings data in OCSF format.

OCSF is a standard for representing vulnerability reports that can be understood by a variety of security tools.

This package allows you to focus on writing the business logic for your component while taking care of the boring things for you:

  • running the components steps in a predictable and reliable way
  • deal with persisting and updating findings data in an underlying storage
  • handle intricacies like cancellations and graceful shutdown
  • taking care of logging and panic handling
  • reporting common metrics to track what your component is doing

You can customise a component using the following environment variables:

Environment Variable Type Required Default Possible Values
SMITHY_COMPONENT_NAME string yes - -
SMITHY_BACKEND_STORE_TYPE string yes - local, test, *remote
SSMITHY_BACKEND_STORE_DSN string no smithy.db *
SMITHY_LOG_LEVEL string false info, debug, warn, error

For local development, an SQLite Backend Store Type will be used.

Runners can be supplied with RunnerConfigOptions to customise how a component runs. In the following example you can see how we change the component name:

component.RunTarget(
	ctx, 
	sampleTarget{}, 
	component.RunnerWithComponentName("sample-target"),
)
Components
Target

A Target component should be used to prepare a target for scanning.

For example, cloning a repository and make it available for a Scanner to scan. A git-clone component is an example of a Target.

You can create a new Target component like follows:

package main

import (
	"context"
	"log"
	"time"

	"github.com/smithy-security/smithy/sdk/component"
)

type sampleTarget struct{}

func (s sampleTarget) Prepare(ctx context.Context) error {
	// Prepare the target here!
	// This is the main execution method of the Target component type. 
	// Here you need to implement your logic.
	// For example for a target component that clones a repository here is where you 
	// setup your arguments and call git clone.
	return nil
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
	defer cancel()

	if err := component.RunTarget(ctx, sampleTarget{}); err != nil {
		log.Fatalf("unexpected run error: %v", err)
	}
}
Scanner

A Scanner scans a Target to find vulnerabilities.

Go-Sec component is an example of a scanner component.

You can create a new Scanner component like follows:

package main

import (
	"context"
	"log"
	"time"

	"github.com/smithy-security/smithy/sdk/component"
	ocsf "github.com/smithy-security/smithy/sdk/gen/com/github/ocsf/ocsf_schema/v1"
)

type sampleScanner struct{}

func (s sampleScanner) Transform(ctx context.Context) ([]*ocsf.VulnerabilityFinding, error) {
	// Transform your payload to ocsf format here!
	// Read raw findings prepared by a Target and transform them to a format that makes sense!
	return make([]*ocsf.VulnerabilityFinding, 0, 10), nil
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
	defer cancel()

	if err := component.RunScanner(ctx, sampleScanner{}); err != nil {
		log.Fatalf("unexpected run error: %v", err)
	}
}
Enricher

An Enricher annotates vulnerability findings with extra information.

Deduplication component is an example Enricher.

You can create a new Enricher component like follows:

package main

import (
	"context"
	"log"
	"time"

	"github.com/smithy-security/smithy/sdk/component"
	ocsf "github.com/smithy-security/smithy/sdk/gen/com/github/ocsf/ocsf_schema/v1"
)

type sampleEnricher struct{}

func (s sampleEnricher) Annotate(ctx context.Context, findings []*ocsf.VulnerabilityFinding) ([]*ocsf.VulnerabilityFinding, error) {
	// Enrich your vulnerability findings here!
	// Make sense of you vulnerability data and add enriching annotations to take smarter decisions.
	return make([]*ocsf.VulnerabilityFinding, 0, 10), nil
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
	defer cancel()

	if err := component.RunEnricher(ctx, sampleEnricher{}); err != nil {
		log.Fatalf("unexpected run error: %v", err)
	}
}
Filter

A Filter component allows to filter out some vulnerability findings based on arbitrary criteria.

For example, you might want to filter out vulnerabilities on a specific path in a repository.

You can create a new Filter component like follows:

package main

import (
	"context"
	"log"
	"time"

	"github.com/smithy-security/smithy/sdk/component"
	ocsf "github.com/smithy-security/smithy/sdk/gen/com/github/ocsf/ocsf_schema/v1"
)

type sampleFilter struct{}

func (s sampleFilter) Filter(ctx context.Context, findings []*ocsf.VulnerabilityFinding) ([]*ocsf.VulnerabilityFinding, bool, error) {
	// Filter out your vulnerability findings here!
	// Remove the noise from your pipeline and ignore findings based on a supplied criteria.
	return make([]*ocsf.VulnerabilityFinding, 0, 80), true, nil
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
	defer cancel()

	if err := component.RunFilter(ctx, sampleFilter{}); err != nil {
		log.Fatalf("unexpected run error: %v", err)
	}
}
Reporter

A Reporter component allows you to report vulnerabilities on your favourite destination.

For example, report each one of them as ticket on a ticketing system or dump them into a data lake. Slack is an example Reporter.

You can create a new Reporter component like follows:

package main

import (
	"context"
	"log"
	"time"

	"github.com/smithy-security/smithy/sdk/component"
	ocsf "github.com/smithy-security/smithy/sdk/gen/com/github/ocsf/ocsf_schema/v1"
)

type sampleReporter struct{}

func (s sampleReporter) Report(ctx context.Context, findings []*ocsf.VulnerabilityFinding) error {
	// Report your vulnerability findings here.
	// Raise them as tickets on Jira or post a message on Slack here!
	return nil
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
	defer cancel()

	if err := component.RunReporter(ctx, sampleReporter{}); err != nil {
		log.Fatalf("unexpected run error: %v", err)
	}
}
Utilities
Logging

component makes it easy for you to leverage the default logger in your business logic.

You can access the logger anytime using component.LoggerFromContext(ctx).

For example:

func (s sampleEnricher) Update(ctx context.Context, findings []*ocsf.VulnerabilityFinding) error {
	component.LoggerFromContext(ctx).Info("Preparing to update findings")
	return nil
}

You can also customise the logger if you wish:

type noopLogger struct {}

func (n *noopLogger) Debug(msg string, keyvals ...any) {}
func (n *noopLogger) Info(msg string, keyvals ...any)  {}
func (n *noopLogger) Warn(msg string, keyvals ...any)  {}
func (n *noopLogger) Error(msg string, keyvals ...any) {}
func (n *noopLogger) With(args ...any) Logger {
    return &noopLogger{}
}

...

logger := noopLogger{}

if err := component.RunReporter(
	ctx, 
	sampleReporter{}, 
	component.RunnerWithLogger(logger),
); err != nil {
    log.Fatalf("unexpected run error: %v", err)
}

Documentation

Index

Constants

View Source
const Version = "0.0.2-alpha"

Variables

This section is empty.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
internal/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
gen

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL