Documentation
¶
Overview ¶
Package idutil provides shared ID validation and generation for observability-safe identifiers across kernel/ and runtime/ layers.
ref: go.opentelemetry.io/otel/trace — IsValid() bool hot-path pattern ref: k8s.io/apimachinery/pkg/util/validation — exported length constants
Index ¶
Constants ¶
const ( // MaxHTTPIDLen is the maximum length for HTTP-borne correlation IDs // (RequestID, CorrelationID, et al). Length enforcement happens at the // HTTP boundary (handler/middleware) alongside IsSafeID; pkg/redaction // only masks values, it does not validate length. MaxHTTPIDLen = 128 // MaxMetadataIDLen is the maximum length for broker metadata IDs // (observability metadata restored from async messages). MaxMetadataIDLen = 256 )
Variables ¶
This section is empty.
Functions ¶
func IsSafeID ¶
IsSafeID reports whether s is non-empty and every byte is in the safe set for observability IDs: ASCII letters, digits, and the separators ._:/-
Length checking is intentionally excluded — callers enforce their own limits via MaxHTTPIDLen or MaxMetadataIDLen.
Typical usage:
if len(id) > idutil.MaxHTTPIDLen || !idutil.IsSafeID(id) { /* reject */ }
func NewUUID ¶
NewUUID generates a UUID v4 string from crypto/rand.Reader via io.ReadFull. In Go 1.24+ crypto/rand.Reader.Read calls runtime.fatal on OS entropy failure rather than returning an error, so the error return is unreachable for the production path; keeping it surfaces a future stdlib contract change rather than swallowing it.
Types ¶
type SafeID ¶
type SafeID string
SafeID is a metadata identifier whose non-empty value is guaranteed to pass IsSafeID + MaxMetadataIDLen. The zero value (empty string) is the "absent" representation for optional fields; required-empty semantics live at the caller.
The Hard funnel claim: every wire-decode path that lands in a SafeID field goes through UnmarshalJSON, which fail-closes on unsafe input. json.Unmarshal is the single decode entry point for outbox envelopes (kernel/outbox.UnmarshalEnvelope is the only caller across all transports), so a SafeID-typed field cannot accept unsafe bytes from the wire by construction.
In-memory construction (SafeID(s), &SafeID{}) bypasses validation — it is permitted in trusted paths (MustNewEntryID, tests). The CWE-117 log injection threat addressed by this type lives strictly at the wire boundary; in-memory state is server-trusted.
ref: pkg/idutil.IsSafeID — character set source (ASCII letters, digits, `._:/-`); pkg/idutil.MaxMetadataIDLen — length cap.
Bypass boundary: SafeID(untrustedInput) in tests that construct wire bytes bypasses UnmarshalJSON validation. Such usage is only safe when the test also asserts that the downstream decoder (e.g. UnmarshalEnvelope) rejects the resulting bytes. Do not treat SafeID(untrustedInput) as a general pattern for trusting external data.
func ParseSafeID ¶
ParseSafeID validates s and returns a SafeID. Empty input returns the zero value with no error.
func (SafeID) MarshalJSON ¶
MarshalJSON emits s as a JSON string. Implements encoding/json.Marshaler.
func (*SafeID) UnmarshalJSON ¶
UnmarshalJSON decodes data into s, returning an error if the JSON value is not a string OR if the decoded string fails Validate. Empty string is allowed (zero/absent semantic). Implements encoding/json.Unmarshaler.