Skip to content

Commit 5691c1e

Browse files
committed
refactor: make bundle resource limits configurable
Makes payload size and signature count limits configurable via environment variables instead of hardcoded constants. This allows operators to tune limits based on their deployment requirements. Changes: - pkg/config/config.go: Add ARCHIVISTA_MAX_PAYLOAD_SIZE_MB and ARCHIVISTA_MAX_SIGNATURES_PER_BUNDLE config options - pkg/sigstorebundle/store.go: Add BundleLimits struct with defaults - pkg/sigstorebundle/store.go: Update MapBundleToDSSE to accept optional limits parameter (maintains backward compatibility) - pkg/metadatastorage/sqlstore/store.go: Accept and use BundleLimits - pkg/server/services.go: Pass config values to Store constructor Defaults remain the same: - Max payload size: 100MB - Max signatures per bundle: 100 Example configuration: ```bash export ARCHIVISTA_MAX_PAYLOAD_SIZE_MB=200 export ARCHIVISTA_MAX_SIGNATURES_PER_BUNDLE=50 ``` All tests pass with backward-compatible defaults. Related: #651 Signed-off-by: Cole Kennedy <cole@testifysec.com>
1 parent 4dc04e4 commit 5691c1e

4 files changed

Lines changed: 53 additions & 14 deletions

File tree

pkg/config/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ type Config struct {
6969
PublisherDaprComponentName string `default:"archivista" desc:"Dapr pubsub component name" split_words:"true"`
7070
PublisherDaprTopic string `default:"attestations" desc:"Dapr pubsub topic" split_words:"true"`
7171
PublisherRstufHost string `default:"http://127.0.0.1" desc:"Host for RSTUF" split_words:"true"`
72+
73+
MaxPayloadSizeMB int `default:"100" desc:"Maximum payload size in megabytes for Sigstore bundles" split_words:"true"`
74+
MaxSignaturesPerBundle int `default:"100" desc:"Maximum number of signatures per Sigstore bundle" split_words:"true"`
7275
}
7376

7477
// Process reads config from env

pkg/metadatastorage/sqlstore/store.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,18 @@ const subjectDigestBatchSize = 20000
4747
const policyPayloadType = "https://witness.testifysec.com/policy/"
4848

4949
type Store struct {
50-
client *ent.Client
50+
client *ent.Client
51+
bundleLimits *sigstorebundle.BundleLimits
5152
}
5253

53-
func New(ctx context.Context, client *ent.Client) (*Store, <-chan error, error) {
54+
func New(ctx context.Context, client *ent.Client, bundleLimits ...*sigstorebundle.BundleLimits) (*Store, <-chan error, error) {
55+
// Use default limits if not provided
56+
var limits *sigstorebundle.BundleLimits
57+
if len(bundleLimits) > 0 && bundleLimits[0] != nil {
58+
limits = bundleLimits[0]
59+
} else {
60+
limits = sigstorebundle.DefaultBundleLimits()
61+
}
5462
errCh := make(chan error)
5563

5664
go func() {
@@ -67,7 +75,8 @@ func New(ctx context.Context, client *ent.Client) (*Store, <-chan error, error)
6775
}
6876

6977
return &Store{
70-
client: client,
78+
client: client,
79+
bundleLimits: limits,
7180
}, errCh, nil
7281
}
7382

@@ -374,7 +383,7 @@ func (s *Store) Store(ctx context.Context, gitoid string, obj []byte) error {
374383
// Handle DSSE bundles (convert to DSSE envelope for storage)
375384
if bundle.DsseEnvelope != nil {
376385
logrus.Infof("processing DSSE bundle: %s", gitoid)
377-
envelope, err := sigstorebundle.MapBundleToDSSE(bundle)
386+
envelope, err := sigstorebundle.MapBundleToDSSE(bundle, s.bundleLimits)
378387
if err != nil {
379388
return fmt.Errorf("failed to convert bundle to DSSE: %w", err)
380389
}

pkg/server/services.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/in-toto/archivista/pkg/objectstorage/blobstore"
3232
"github.com/in-toto/archivista/pkg/objectstorage/filestore"
3333
"github.com/in-toto/archivista/pkg/publisherstore"
34+
"github.com/in-toto/archivista/pkg/sigstorebundle"
3435
"github.com/minio/minio-go/v7/pkg/credentials"
3536
"github.com/sirupsen/logrus"
3637
)
@@ -110,7 +111,11 @@ func (a *ArchivistaService) Setup() (*Server, error) {
110111
}
111112

112113
// Continue with the existing setup code for the SQLStore
113-
sqlStore, a.sqlStoreCh, err = sqlstore.New(context.Background(), entClient)
114+
bundleLimits := &sigstorebundle.BundleLimits{
115+
MaxPayloadSizeMB: a.Cfg.MaxPayloadSizeMB,
116+
MaxSignaturesPerBundle: a.Cfg.MaxSignaturesPerBundle,
117+
}
118+
sqlStore, a.sqlStoreCh, err = sqlstore.New(context.Background(), entClient, bundleLimits)
114119
if err != nil {
115120
logrus.Fatalf("error initializing new SQLStore: %+v", err)
116121
}

pkg/sigstorebundle/store.go

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,26 @@ import (
2727
"github.com/in-toto/go-witness/dsse"
2828
)
2929

30+
// Default limits for bundle validation
3031
const (
31-
// maxPayloadSize is the maximum size of a decoded payload in bytes (100MB)
32-
maxPayloadSize = 100 * 1024 * 1024
33-
// maxSignaturesPerBundle is the maximum number of signatures allowed per bundle
34-
maxSignaturesPerBundle = 100
32+
DefaultMaxPayloadSizeMB = 100
33+
DefaultMaxSignaturesPerBundle = 100
3534
)
3635

36+
// BundleLimits defines resource limits for bundle processing
37+
type BundleLimits struct {
38+
MaxPayloadSizeMB int
39+
MaxSignaturesPerBundle int
40+
}
41+
42+
// DefaultBundleLimits returns the default resource limits
43+
func DefaultBundleLimits() *BundleLimits {
44+
return &BundleLimits{
45+
MaxPayloadSizeMB: DefaultMaxPayloadSizeMB,
46+
MaxSignaturesPerBundle: DefaultMaxSignaturesPerBundle,
47+
}
48+
}
49+
3750
// gitoidSHA256 computes gitoid v1 SHA256 hash (blob header + content)
3851
// Note: Currently unused but kept for future gitoid calculation needs
3952
// nolint:unused
@@ -54,7 +67,15 @@ func ParseBundle(raw []byte) (*Bundle, error) {
5467
}
5568

5669
// MapBundleToDSSE converts a Sigstore bundle to a go-witness DSSE envelope
57-
func MapBundleToDSSE(bundle *Bundle) (*dsse.Envelope, error) {
70+
// Optional limits parameter can be provided to customize resource limits
71+
func MapBundleToDSSE(bundle *Bundle, limits ...*BundleLimits) (*dsse.Envelope, error) {
72+
// Use default limits if not provided
73+
var bundleLimits *BundleLimits
74+
if len(limits) > 0 && limits[0] != nil {
75+
bundleLimits = limits[0]
76+
} else {
77+
bundleLimits = DefaultBundleLimits()
78+
}
5879
if bundle == nil {
5980
return nil, fmt.Errorf("bundle is nil")
6081
}
@@ -69,8 +90,9 @@ func MapBundleToDSSE(bundle *Bundle) (*dsse.Envelope, error) {
6990

7091
// Check payload size before decoding (base64 encoded size * 3/4 ≈ decoded size)
7192
estimatedSize := len(bundle.DsseEnvelope.Payload) * 3 / 4
72-
if estimatedSize > maxPayloadSize {
73-
return nil, fmt.Errorf("payload size (%d bytes) exceeds maximum allowed size (%d bytes)", estimatedSize, maxPayloadSize)
93+
maxPayloadSizeBytes := bundleLimits.MaxPayloadSizeMB * 1024 * 1024
94+
if estimatedSize > maxPayloadSizeBytes {
95+
return nil, fmt.Errorf("payload size (%d bytes) exceeds maximum allowed size (%d MB)", estimatedSize, bundleLimits.MaxPayloadSizeMB)
7496
}
7597

7698
// Decode payload
@@ -93,8 +115,8 @@ func MapBundleToDSSE(bundle *Bundle) (*dsse.Envelope, error) {
93115
}
94116

95117
// Check signature count limit to prevent resource exhaustion
96-
if len(bundle.DsseEnvelope.Signatures) > maxSignaturesPerBundle {
97-
return nil, fmt.Errorf("bundle has %d signatures, exceeds maximum allowed (%d)", len(bundle.DsseEnvelope.Signatures), maxSignaturesPerBundle)
118+
if len(bundle.DsseEnvelope.Signatures) > bundleLimits.MaxSignaturesPerBundle {
119+
return nil, fmt.Errorf("bundle has %d signatures, exceeds maximum allowed (%d)", len(bundle.DsseEnvelope.Signatures), bundleLimits.MaxSignaturesPerBundle)
98120
}
99121

100122
// Map signatures with VerificationMaterial

0 commit comments

Comments
 (0)