Documentation
¶
Overview ¶
Package contract holds the parts of the serverless endpoint contract that are not protobuf messages: header names, the upgrade signature payload, wire constants and the protojson encoding every message travels in. The messages themselves are generated from api-contracts/v1/serverless.proto into internal/services/shared/proto/v1, which is also the source of the endpoint SDK's TypeScript types.
Package contract holds the constants shared between the serverless operator core and the API server: the data ids for secrets encrypted at rest. Both sides must agree on these for ciphertext written by one to be readable by the other.
Index ¶
- Constants
- func ApplyNamespace(namespace, name string) string
- func Marshal(m proto.Message) ([]byte, error)
- func MarshalFrame(frame *v1.ServerlessDurableFrame) ([]byte, error)
- func NamespacePrefix(namespace string) string
- func Unmarshal(raw []byte, m proto.Message) error
- func UnmarshalFrame(raw []byte) (*v1.ServerlessDurableFrame, error)
- func UpgradeSigningPayload(timestamp, nonce, taskId, invocation string) string
Constants ¶
const ( SignatureHeader = "X-Hatchet-Signature" EndpointIdHeader = "X-Hatchet-Endpoint-Id" TimestampHeader = "X-Hatchet-Timestamp" )
Headers carried by every request the operator sends to an endpoint. Endpoints verify SignatureHeader by recomputing the HMAC-SHA256 hex digest of the raw body with their signing secret (internal/signature.Verify). The signed body of every POST (v1.ServerlessHealthcheckRequest, v1.ServerlessTriggerRequest) carries the operator's timestamp in Unix seconds; an endpoint rejects a body whose timestamp lies more than RequestMaxAge from its own clock in either direction, so a captured request cannot be replayed later. Within that window a delivery may be repeated: endpoints key side effects on (endpoint id, task run external id, retry count).
const ( NonceHeader = "X-Hatchet-Nonce" TaskIdHeader = "X-Hatchet-Task-Id" InvocationHeader = "X-Hatchet-Invocation" )
Headers carried only by the durable websocket upgrade, which has no body to sign. The endpoint verifies SignatureHeader against UpgradeSigningPayload with its signing secret, rejects a TimestampHeader more than UpgradeMaxAge from its clock in either direction, consumes NonceHeader from a nonce set after the signature verified so a captured upgrade cannot be replayed within the window, and checks that the first frame's task id and invocation are the ones the headers were signed for.
const ( // ErrorCodeNonDeterminism reports a replay that diverged from the log. ErrorCodeNonDeterminism = "nondeterminism" // ErrorCodeUnspecified is every other engine-side error. ErrorCodeUnspecified = "unspecified" )
Codes of v1.ServerlessErrorFrame.
const DoneStatusEvicted = "evicted"
DoneStatusEvicted is the v1.ServerlessDoneFrame status of an invocation that evicted itself.
const NamespaceSeparator = "_"
NamespaceSeparator joins an endpoint's namespace to the names it owns, the way the SDK's HATCHET_CLIENT_NAMESPACE does. The operator registers every workflow name, action service and event key an endpoint serves as <namespace><separator><name>, and the durable relay applies the same prefix to the workflow names and user event keys an endpoint references in nested requests, so the namespace is the boundary of what an endpoint can reach.
const RequestMaxAge = 5 * time.Minute
RequestMaxAge is how far a signed timestamp may lie from the endpoint's clock, in either direction, before the endpoint rejects the request. It applies to the timestamp inside every signed POST body and to the upgrade's TimestampHeader.
const SigningSecretEncryptionDataID = "v1_serverless_endpoint_signing_secret" //nolint:gosec // associated-data label for envelope encryption, not a credential
SigningSecretEncryptionDataID is the associated data used when encrypting a serverless endpoint's signing secret with pkg/encryption. It binds the ciphertext in v1_serverless_endpoint.signing_secret_enc to that column so it cannot be replayed as any other secret.
const TriggerEnvelopeVersion = 1
TriggerEnvelopeVersion is the version field of v1.ServerlessTriggerRequest.
const UpgradeMaxAge = RequestMaxAge
UpgradeMaxAge is RequestMaxAge as it applies to the durable upgrade.
Variables ¶
This section is empty.
Functions ¶
func ApplyNamespace ¶
ApplyNamespace prefixes a workflow name or event key with the namespace. A name that already carries the prefix is left alone, so applying it twice is harmless; an empty namespace applies nothing.
func MarshalFrame ¶
func MarshalFrame(frame *v1.ServerlessDurableFrame) ([]byte, error)
MarshalFrame encodes one durable websocket frame.
func NamespacePrefix ¶
NamespacePrefix is what ApplyNamespace prepends.
func UnmarshalFrame ¶
func UnmarshalFrame(raw []byte) (*v1.ServerlessDurableFrame, error)
UnmarshalFrame decodes one durable websocket frame.
func UpgradeSigningPayload ¶
UpgradeSigningPayload is the string the durable upgrade signature covers: timestamp "." nonce "." task_id "." invocation, each as it appears in its header.
Types ¶
This section is empty.