Watch
1
0
Fork
You've already forked RedFlag
0

supply chain consumer: refinements + test coverage

This commit is contained in:
Fimeg 2026-06-11 13:37:58 -04:00
commit ea9fbc1d7b
2 changed files with 58 additions and 4 deletions

View file

@ -253,12 +253,16 @@ func (c *Consumer) ProcessToken(ctx context.Context, token *capability.Token) (*
if token.AgentID != c.agentID.String() {
log.Printf("[SECURITY] [agent] [supplychain] bind_check_failed token_id=%s token_agent_id=%s host_agent_id=%s",
token.TokenID, token.AgentID, c.agentID)
return nil, fmt.Errorf("token not bound to this host")
err := fmt.Errorf("token not bound to this host")
c.reportTokenProcessFailure(token, err)
return nil, err
}
if !allowedCapabilityPackageType(token.PackageType) {
log.Printf("[SECURITY] [agent] [supplychain] package_type_refused token_id=%s package_type=%s",
token.TokenID, token.PackageType)
return nil, fmt.Errorf("package_type %q not in allowlist", token.PackageType)
err := fmt.Errorf("package_type %q not in allowlist", token.PackageType)
c.reportTokenProcessFailure(token, err)
return nil, err
}
var (
@ -278,6 +282,7 @@ func (c *Consumer) ProcessToken(ctx context.Context, token *capability.Token) (*
if err != nil {
log.Printf("[ERROR] [agent] [supplychain] token_process_failed token_id=%s package_type=%s error=%v",
token.TokenID, token.PackageType, err)
c.reportTokenProcessFailure(token, err)
return nil, err
}
@ -293,6 +298,19 @@ func (c *Consumer) ProcessToken(ctx context.Context, token *capability.Token) (*
return result, nil
}
func (c *Consumer) reportTokenProcessFailure(token *capability.Token, cause error) {
if c.reporter == nil || token == nil {
return
}
reason := "token_process_failed"
if cause != nil {
reason = cause.Error()
}
if err := c.reporter.ReportCapabilityResult(c.agentID, token.TokenID, "failed", reason, 1); err != nil {
log.Printf("[WARNING] [agent] [supplychain] failure_result_report_failed token_id=%s error=%v", token.TokenID, err)
}
}
// ProcessTokens runs ProcessToken for each token, continuing past individual
// failures so one bad token does not strand the rest.
func (c *Consumer) ProcessTokens(ctx context.Context, tokens []*capability.Token) {

View file

@ -11,6 +11,25 @@ import (
"github.com/gofrs/uuid/v5"
)
type recordingReporter struct {
agentID uuid.UUID
tokenID string
decision string
reason string
exitCode int
calls int
}
func (r *recordingReporter) ReportCapabilityResult(agentID uuid.UUID, tokenID string, decision, reason string, exitCode int) error {
r.agentID = agentID
r.tokenID = tokenID
r.decision = decision
r.reason = reason
r.exitCode = exitCode
r.calls++
return nil
}
func TestSafeTokenFilename(t *testing.T) {
tests := []struct {
name string
@ -162,7 +181,8 @@ func TestInstallDesktopBinaryBacksUpAndReplaces(t *testing.T) {
func TestConsumerProcessTokenRejectsWrongAgentID(t *testing.T) {
agentID := uuid.Must(uuid.NewV4())
executor := NewExecutor("/nonexistent/helper")
consumer := NewConsumer(agentID, executor, nil)
reporter := &recordingReporter{}
consumer := NewConsumer(agentID, executor, reporter)
wrongID := uuid.Must(uuid.NewV4())
tok := &capability.Token{
@ -179,12 +199,22 @@ func TestConsumerProcessTokenRejectsWrongAgentID(t *testing.T) {
if got := err.Error(); got != "token not bound to this host" {
t.Errorf("unexpected error: %v", got)
}
if reporter.calls != 1 {
t.Fatalf("reporter calls = %d, want 1", reporter.calls)
}
if reporter.agentID != agentID || reporter.tokenID != "tok-1" || reporter.decision != "failed" || reporter.exitCode != 1 {
t.Fatalf("reported result = %#v", reporter)
}
if reporter.reason != "token not bound to this host" {
t.Fatalf("reported reason = %q", reporter.reason)
}
}
func TestConsumerProcessTokenRejectsDisallowedPackageType(t *testing.T) {
agentID := uuid.Must(uuid.NewV4())
executor := NewExecutor("/nonexistent/helper")
consumer := NewConsumer(agentID, executor, nil)
reporter := &recordingReporter{}
consumer := NewConsumer(agentID, executor, reporter)
tok := &capability.Token{
TokenID: "tok-2",
@ -197,6 +227,12 @@ func TestConsumerProcessTokenRejectsDisallowedPackageType(t *testing.T) {
if err == nil {
t.Fatal("expected error for disallowed package type, got nil")
}
if reporter.calls != 1 {
t.Fatalf("reporter calls = %d, want 1", reporter.calls)
}
if reporter.tokenID != "tok-2" || reporter.decision != "failed" || reporter.reason != "package_type \"cargo\" not in allowlist" {
t.Fatalf("reported result = %#v", reporter)
}
}
func TestConsumerProcessTokensSummary(t *testing.T) {