Fail closed on Go SDK idempotency entropy errors

This commit is contained in:
Codex
2026-06-17 13:07:18 +02:00
parent ecf8106c56
commit b4f47fb17a
2 changed files with 104 additions and 22 deletions
+65
View File
@@ -3,6 +3,7 @@ package attesto
import (
"context"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"strings"
@@ -135,3 +136,67 @@ func TestRelayLocalVaultEventReturnsMarshalError(t *testing.T) {
t.Fatalf("request was sent after marshal failure")
}
}
func TestGeneratedIdempotencyKeyFailsClosedOnEntropyError(t *testing.T) {
originalRead := secureRandomRead
secureRandomRead = func([]byte) (int, error) {
return 0, errors.New("entropy unavailable")
}
t.Cleanup(func() { secureRandomRead = originalRead })
called := false
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
called = true
t.Fatalf("request should not be sent when idempotency key generation fails")
}))
defer server.Close()
client, err := NewClient(testAPIKey, WithBaseURL(server.URL), WithMaxRetries(1))
if err != nil {
t.Fatalf("client: %v", err)
}
_, err = client.CreateStream(context.Background(), StreamCreateInput{UseCase: "ai-governance", PolicyID: "policy-main"})
if err == nil || !strings.Contains(err.Error(), "generate idempotency key") {
t.Fatalf("expected idempotency entropy error, got %v", err)
}
if called {
t.Fatalf("request was sent after idempotency generation failure")
}
}
func TestExplicitIdempotencyKeyBypassesEntropyGeneration(t *testing.T) {
originalRead := secureRandomRead
secureRandomRead = func([]byte) (int, error) {
return 0, errors.New("entropy unavailable")
}
t.Cleanup(func() { secureRandomRead = originalRead })
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Idempotency-Key") != "fixed-key" {
t.Fatalf("explicit idempotency key missing: %q", r.Header.Get("Idempotency-Key"))
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(Stream{
StreamID: "str_fixed", SystemID: "sys_fixed", UseCase: "ai-governance", PolicyID: "policy-main", Status: "active", Created: true,
})
}))
defer server.Close()
client, err := NewClient(testAPIKey, WithBaseURL(server.URL), WithMaxRetries(1))
if err != nil {
t.Fatalf("client: %v", err)
}
stream, err := client.CreateStream(
context.Background(),
StreamCreateInput{UseCase: "ai-governance", PolicyID: "policy-main"},
RequestOptions{IdempotencyKey: "fixed-key"},
)
if err != nil {
t.Fatalf("create stream with explicit idempotency key: %v", err)
}
if stream.StreamID != "str_fixed" {
t.Fatalf("unexpected stream: %#v", stream)
}
}