Documentation
¶
Overview ¶
Package audit holds the audit-row primitives shared by the Connect interceptors and any other writer of audit records.
Index ¶
- Constants
- func BoundAuditString(value string) string
- func BoundAuditStruct(payload *structpb.Struct) *structpb.Struct
- func BuildAuditStatus(err error) *storepb.AuditLogStatus
- func BuildRequestMetadata(header http.Header, peerAddr string, trustedProxies []string) *storepb.AuditRequestMetadata
- func ClientAddress(header http.Header, peerAddr string, trustedProxies []string) string
- func Context(ctx context.Context) (context.Context, context.CancelFunc)
- func ErrorForHTTPStatus(status int) error
- func GetNestedString(raw map[string]any, keys ...string) string
- func HostFromAddr(addr string) string
- func IsSensitiveAuditField(key string) bool
- func IsTrustedProxy(host string, trustedProxies []string) bool
- func MapSeverity(err error) storepb.AuditLogSeverity
- func MarshalAuditMessage(message proto.Message) (*structpb.Struct, map[string]any)
- func ResolveActor(ctx context.Context, requestMap, responseMap map[string]any) string
- func ResolveParent(defaultParent string, requestMap, responseMap map[string]any) string
- func ResolveResource(requestMap, responseMap map[string]any) string
- func SanitizeAuditStruct(payload *structpb.Struct) *structpb.Struct
- func SanitizeAuditValue(value any)
- func StampGatewayPeer(header http.Header, peerAddr string)
Constants ¶
const AuditWriteTimeout = 10 * time.Second
AuditWriteTimeout bounds an audit write that runs detached from the request, so a hung database cannot pile up audit goroutines.
const GatewayPeerHeader = "Metaxisdata-Client-Peer"
GatewayPeerHeader is the metadata key the REST gateway carries the outer request's peer address on. The gateway reaches the Connect handler over a loopback self-connection, so without it every REST request would be recorded as 127.0.0.1. Only a request that also carries GatewayProofHeader, a MAC over this value with a per-process secret, is believed (see StampGatewayPeer).
const GatewayProofHeader = "Metaxisdata-Gateway-Proof"
GatewayProofHeader is the metadata key carrying that MAC.
const MaxAuditFieldBytes = 8 << 10
MaxAuditFieldBytes bounds one string inside an audit payload. Audited methods include ones reachable without a credential, and the ledger is never pruned, so no single field may carry a request body. The value matches the MCP server's per-argument bound, which used to be the only place this cap existed.
const MaxAuditPayloadBytes = 256 << 10
MaxAuditPayloadBytes bounds one serialized audit payload (request or response). Truncating fields is not enough on its own: a repeated field or a nested object can carry an unbounded number of bounded strings, and a List response would otherwise copy the ledger into the ledger. A payload over the cap is replaced by a marker instead of being stored.
const MaxIPBytes = 64
MaxIPBytes bounds the recorded address. A real one is at most 45 bytes; the value still comes from request text on a misconfigured deployment, and it is echoed into the ledger and used as a rate-limit key.
const MaxUserAgentBytes = 256
MaxUserAgentBytes bounds the recorded User-Agent. The header is chosen by the client and is only limited by the HTTP server's header limit, so an anonymous request could otherwise append a megabyte to a permanent row.
const RedactedValue = "[REDACTED]"
Variables ¶
This section is empty.
Functions ¶
func BoundAuditString ¶
BoundAuditString bounds one free-standing string a caller writes into a row outside a payload of its own, such as a status message.
func BoundAuditStruct ¶
BoundAuditStruct applies the field and whole-payload bounds to a payload built outside MarshalAuditMessage — the MCP server renders tool arguments itself. Callers that also need redaction call SanitizeAuditStruct first. A payload that cannot be rebuilt is dropped for a marker rather than stored unbounded.
func BuildAuditStatus ¶
func BuildAuditStatus(err error) *storepb.AuditLogStatus
func BuildRequestMetadata ¶
func BuildRequestMetadata(header http.Header, peerAddr string, trustedProxies []string) *storepb.AuditRequestMetadata
BuildRequestMetadata records where a request came from. Forwarding headers are only believed when the connection itself comes from a configured trusted proxy: otherwise any client could pick its own audit IP by sending X-Forwarded-For.
func ClientAddress ¶
ClientAddress resolves the address a request should be attributed to. The forwarding chain is believed only when the connection itself comes from a configured trusted proxy; otherwise any client could pick its own audit IP or reset its rate-limit bucket with X-Forwarded-For.
The chain is read from the right: each hop appends the address it saw, so the rightmost entry is what the nearest trusted proxy observed and the leftmost is the least trustworthy. Walking right to left and stopping at the first address that is not a configured proxy therefore yields the client, and a value an attacker prepended to the header is never reached.
func Context ¶
Context detaches an audit write from the request: a client disconnect must not cancel the record of what that client did.
func ErrorForHTTPStatus ¶
ErrorForHTTPStatus maps an ingestion response status onto the error shape MapSeverity/BuildAuditStatus understand.
func HostFromAddr ¶
func IsSensitiveAuditField ¶
func IsTrustedProxy ¶
IsTrustedProxy matches the peer against an exact IP or a CIDR entry.
func MapSeverity ¶
func MapSeverity(err error) storepb.AuditLogSeverity
func MarshalAuditMessage ¶
MarshalAuditMessage renders a message for the ledger. It always returns a payload and never an error: an audit row must survive a message the encoder cannot render — the binary protocol accepts string fields that are not UTF-8 — because a dropped row is worse than a row whose detail was replaced by a marker. A nil message yields a nil payload.
func ResolveActor ¶
func ResolveParent ¶
func ResolveResource ¶
func SanitizeAuditStruct ¶
SanitizeAuditStruct re-runs redaction over a stored payload. Rows written before the redaction list was complete may still hold plaintext credentials, so the read path must not hand them back.
func SanitizeAuditValue ¶
func SanitizeAuditValue(value any)
func StampGatewayPeer ¶
StampGatewayPeer records the outer peer address for a request the REST gateway is about to forward over its loopback self-connection, together with the proof that this process wrote it. Both headers are deleted first, so a caller cannot keep a value of its own.
Types ¶
This section is empty.