Adds payload_commitment / metadata_commitment / verify_payload_commitment and assert_commitment_safe_numbers to the Python, TypeScript, and Go SDKs, each building on the frozen canonical_json/domain_hash primitives (no change to their byte output). The number preflight is a byte-for-byte port of the backend assert_commitment_safe_numbers (floats rejected, |int| > 2^53-1 rejected, bool exempt) and is wired into the v2 log_event / log_events send path, raising a typed AttestoUnsafeNumberError with the JSON path so the rule fails at dev time rather than as a production 422; preflight=False / SkipPreflight defers to the server. New shared corpus golden-vectors/sdk-parity/canonical-numbers.json (15 accept + 8 reject), accept-hashes generated from the backend _commitment. Proven: Python = TypeScript = Go = backend produce byte-identical commitment hashes for every accept vector and identical reject paths (the Go float64-vs-Python- int serialization parity holds). READMEs updated per SDK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
288 lines
9.5 KiB
Go
288 lines
9.5 KiB
Go
package attesto
|
|
|
|
import "encoding/json"
|
|
|
|
type M map[string]any
|
|
|
|
type RequestOptions struct {
|
|
IdempotencyKey string
|
|
// SkipPreflight disables the client-side commitment number preflight, which
|
|
// rejects non-integer / out-of-range numbers locally before LogEvent /
|
|
// LogEvents sends them. Default false: the preflight runs.
|
|
SkipPreflight bool
|
|
}
|
|
|
|
type StreamCreateInput struct {
|
|
UseCase string `json:"useCase"`
|
|
PolicyID string `json:"policyId"`
|
|
Metadata M `json:"metadata,omitempty"`
|
|
}
|
|
|
|
type Stream struct {
|
|
StreamID string `json:"streamId"`
|
|
SystemID string `json:"systemId"`
|
|
UseCase string `json:"useCase"`
|
|
PolicyID string `json:"policyId"`
|
|
Status string `json:"status"`
|
|
LastSeqNo int64 `json:"lastSeqNo"`
|
|
LastEventHash string `json:"lastEventHash,omitempty"`
|
|
LastStreamHeadHash string `json:"lastStreamHeadHash,omitempty"`
|
|
Created bool `json:"created"`
|
|
}
|
|
|
|
type TenantStream struct {
|
|
StreamID string `json:"streamId"`
|
|
SystemID string `json:"systemId"`
|
|
SystemName string `json:"systemName,omitempty"`
|
|
UseCase string `json:"useCase"`
|
|
PolicyID string `json:"policyId"`
|
|
Status string `json:"status"`
|
|
LastSeqNo int64 `json:"lastSeqNo"`
|
|
LastEventHash string `json:"lastEventHash,omitempty"`
|
|
LastStreamHeadHash string `json:"lastStreamHeadHash,omitempty"`
|
|
OpenedAt string `json:"openedAt"`
|
|
UpdatedAt string `json:"updatedAt"`
|
|
}
|
|
|
|
type StreamHead struct {
|
|
StreamID string `json:"streamId"`
|
|
SystemID string `json:"systemId"`
|
|
Status string `json:"status"`
|
|
LastSeqNo int64 `json:"lastSeqNo"`
|
|
LastEventHash string `json:"lastEventHash,omitempty"`
|
|
LastStreamHeadHash string `json:"lastStreamHeadHash,omitempty"`
|
|
}
|
|
|
|
type EventInput struct {
|
|
EventType string `json:"eventType,omitempty"`
|
|
OccurredAt string `json:"occurredAt,omitempty"`
|
|
SourceKind string `json:"sourceKind,omitempty"`
|
|
SourceRef string `json:"sourceRef"`
|
|
Payload M `json:"payload,omitempty"`
|
|
Metadata M `json:"metadata,omitempty"`
|
|
}
|
|
|
|
type ReceiptSignature struct {
|
|
Alg string `json:"alg"`
|
|
KID string `json:"kid"`
|
|
KeyEpoch string `json:"keyEpoch,omitempty"`
|
|
SignatureHex string `json:"signatureHex,omitempty"`
|
|
}
|
|
|
|
type SignedReceipt struct {
|
|
Payload M `json:"payload"`
|
|
ReceiptHash string `json:"receiptHash"`
|
|
Signature ReceiptSignature `json:"signature"`
|
|
}
|
|
|
|
func (s *ReceiptSignature) UnmarshalJSON(raw []byte) error {
|
|
var data map[string]any
|
|
if err := json.Unmarshal(raw, &data); err != nil {
|
|
return err
|
|
}
|
|
s.Alg, _ = data["alg"].(string)
|
|
s.KID, _ = data["kid"].(string)
|
|
if value, ok := data["keyEpoch"].(string); ok {
|
|
s.KeyEpoch = value
|
|
} else if value, ok := data["key_epoch"].(string); ok {
|
|
s.KeyEpoch = value
|
|
}
|
|
if value, ok := data["signatureHex"].(string); ok {
|
|
s.SignatureHex = value
|
|
} else if value, ok := data["signature_hex"].(string); ok {
|
|
s.SignatureHex = value
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *SignedReceipt) UnmarshalJSON(raw []byte) error {
|
|
var data map[string]json.RawMessage
|
|
if err := json.Unmarshal(raw, &data); err != nil {
|
|
return err
|
|
}
|
|
if payload, ok := data["payload"]; ok {
|
|
if err := json.Unmarshal(payload, &r.Payload); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if receiptHash, ok := data["receiptHash"]; ok {
|
|
if err := json.Unmarshal(receiptHash, &r.ReceiptHash); err != nil {
|
|
return err
|
|
}
|
|
} else if receiptHash, ok := data["receipt_hash"]; ok {
|
|
if err := json.Unmarshal(receiptHash, &r.ReceiptHash); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if signature, ok := data["signature"]; ok {
|
|
if err := json.Unmarshal(signature, &r.Signature); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type EventReceipt struct {
|
|
StreamID string `json:"streamId"`
|
|
StreamEventID string `json:"streamEventId"`
|
|
SeqNo int64 `json:"seqNo"`
|
|
EventHash string `json:"eventHash"`
|
|
PrevEventHash string `json:"prevEventHash,omitempty"`
|
|
StreamHeadHash string `json:"streamHeadHash"`
|
|
Receipt SignedReceipt `json:"receipt"`
|
|
LocalVaultAck M `json:"localVaultAck,omitempty"`
|
|
}
|
|
|
|
type EventBatchResponse struct {
|
|
Accepted int `json:"accepted"`
|
|
Receipts []EventReceipt `json:"receipts"`
|
|
}
|
|
|
|
type VerifyKind string
|
|
|
|
const (
|
|
VerifyReceipt VerifyKind = "receipt"
|
|
VerifyStream VerifyKind = "stream"
|
|
VerifyWindow VerifyKind = "window"
|
|
VerifyCheckpoint VerifyKind = "checkpoint"
|
|
VerifyConsistency VerifyKind = "consistency"
|
|
VerifyAnchor VerifyKind = "anchor"
|
|
VerifyIVC VerifyKind = "ivc"
|
|
VerifyBundle VerifyKind = "bundle"
|
|
)
|
|
|
|
type ReceiptVerifyInput struct {
|
|
Receipt any `json:"receipt"`
|
|
PublicKeyHex string `json:"publicKeyHex"`
|
|
StreamEventID string `json:"streamEventId,omitempty"`
|
|
}
|
|
|
|
type OfflineVerifyInput struct {
|
|
Kind VerifyKind `json:"kind"`
|
|
Object M `json:"object"`
|
|
PublicKeyHex string `json:"publicKeyHex,omitempty"`
|
|
}
|
|
|
|
type VerificationCheck struct {
|
|
Name string `json:"name"`
|
|
Result string `json:"result"`
|
|
Details M `json:"details,omitempty"`
|
|
}
|
|
|
|
type VerifyReport struct {
|
|
Kind VerifyKind `json:"kind,omitempty"`
|
|
OK bool `json:"ok"`
|
|
ReceiptHash string `json:"receiptHash,omitempty"`
|
|
EventHash string `json:"eventHash,omitempty"`
|
|
Problems []string `json:"problems"`
|
|
Protocol string `json:"protocol,omitempty"`
|
|
ProtocolVersion string `json:"protocolVersion,omitempty"`
|
|
VerifiedAt string `json:"verifiedAt,omitempty"`
|
|
Subject M `json:"subject,omitempty"`
|
|
Result string `json:"result,omitempty"`
|
|
Checks []VerificationCheck `json:"checks,omitempty"`
|
|
Evidence []M `json:"evidence,omitempty"`
|
|
}
|
|
|
|
type WitnessPolicy struct {
|
|
PolicyID string `json:"policyId"`
|
|
TenantID string `json:"tenantId"`
|
|
Mode string `json:"mode"`
|
|
Status string `json:"status"`
|
|
Enforced bool `json:"enforced"`
|
|
ManagedOnly bool `json:"managedOnly"`
|
|
QuorumThreshold int `json:"quorumThreshold"`
|
|
WitnessKeys []string `json:"witnessKeys"`
|
|
Payload M `json:"payload"`
|
|
PolicyHash string `json:"policyHash"`
|
|
}
|
|
|
|
type VerifierBundle struct {
|
|
BundleID string `json:"bundleId"`
|
|
BundleHash string `json:"bundleHash"`
|
|
Payload M `json:"payload"`
|
|
}
|
|
|
|
type ConnectorCreateInput struct {
|
|
StreamID string `json:"streamId"`
|
|
Label string `json:"label"`
|
|
Metadata M `json:"metadata,omitempty"`
|
|
}
|
|
|
|
type S3ConnectorCreateInput struct {
|
|
StreamID string `json:"streamId"`
|
|
Label string `json:"label"`
|
|
Bucket string `json:"bucket"`
|
|
AccessKeyID string `json:"accessKeyId"`
|
|
SecretAccessKey string `json:"secretAccessKey"`
|
|
Region string `json:"region,omitempty"`
|
|
EndpointURL string `json:"endpointUrl,omitempty"`
|
|
Provider string `json:"provider,omitempty"`
|
|
AddressingStyle string `json:"addressingStyle,omitempty"`
|
|
Metadata M `json:"metadata,omitempty"`
|
|
}
|
|
|
|
type RepositoryConnectorCreateInput struct {
|
|
StreamID string `json:"streamId"`
|
|
Label string `json:"label"`
|
|
Provider string `json:"provider"`
|
|
RepositoryURL string `json:"repositoryUrl,omitempty"`
|
|
Metadata M `json:"metadata,omitempty"`
|
|
}
|
|
|
|
type Connector struct {
|
|
ConnectorID string `json:"connectorId"`
|
|
StreamID string `json:"streamId"`
|
|
SystemID string `json:"systemId"`
|
|
ConnectorType string `json:"connectorType"`
|
|
Label string `json:"label"`
|
|
Status string `json:"status"`
|
|
EndpointPath string `json:"endpointPath,omitempty"`
|
|
CommitEndpointPath string `json:"commitEndpointPath,omitempty"`
|
|
Provider string `json:"provider,omitempty"`
|
|
RepositoryURL string `json:"repositoryUrl,omitempty"`
|
|
Bucket string `json:"bucket,omitempty"`
|
|
Region string `json:"region,omitempty"`
|
|
EndpointURL string `json:"endpointUrl,omitempty"`
|
|
AddressingStyle string `json:"addressingStyle,omitempty"`
|
|
AccessKeyIDMasked string `json:"accessKeyIdMasked,omitempty"`
|
|
LastEventAt string `json:"lastEventAt,omitempty"`
|
|
CreatedAt string `json:"createdAt,omitempty"`
|
|
UpdatedAt string `json:"updatedAt,omitempty"`
|
|
Secret string `json:"secret,omitempty"`
|
|
}
|
|
|
|
type LocalVaultInstallationCreateInput struct {
|
|
StreamID string `json:"streamId"`
|
|
Label string `json:"label"`
|
|
KeyID string `json:"keyId"`
|
|
PublicKeyHex string `json:"publicKeyHex"`
|
|
Metadata M `json:"metadata,omitempty"`
|
|
}
|
|
|
|
type LocalVaultInstallation struct {
|
|
InstallationID string `json:"installationId"`
|
|
StreamID string `json:"streamId"`
|
|
SystemID string `json:"systemId"`
|
|
Label string `json:"label"`
|
|
Status string `json:"status"`
|
|
KeyID string `json:"keyId"`
|
|
PublicKeyHex string `json:"publicKeyHex"`
|
|
EndpointPath string `json:"endpointPath"`
|
|
LastEventAt string `json:"lastEventAt,omitempty"`
|
|
CreatedAt string `json:"createdAt"`
|
|
UpdatedAt string `json:"updatedAt"`
|
|
}
|
|
|
|
type MarketplaceAssetSubmitInput struct {
|
|
Manifest M `json:"manifest"`
|
|
SourceRef string `json:"sourceRef"`
|
|
Visibility string `json:"visibility"`
|
|
PricingModel string `json:"pricingModel"`
|
|
PriceCents *int `json:"priceCents,omitempty"`
|
|
}
|
|
|
|
type MarketplaceReviewInput struct {
|
|
Reason string `json:"reason"`
|
|
}
|