audit

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package audit holds the audit-row primitives shared by the Connect interceptors and any other writer of audit records.

Index

Constants

View Source
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.

View Source
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).

View Source
const GatewayProofHeader = "Metaxisdata-Gateway-Proof"

GatewayProofHeader is the metadata key carrying that MAC.

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
const RedactedValue = "[REDACTED]"

Variables

This section is empty.

Functions

func BoundAuditString

func BoundAuditString(value string) string

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

func BoundAuditStruct(payload *structpb.Struct) *structpb.Struct

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

func ClientAddress(header http.Header, peerAddr string, trustedProxies []string) string

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

func ErrorForHTTPStatus(status int) error

ErrorForHTTPStatus maps an ingestion response status onto the error shape MapSeverity/BuildAuditStatus understand.

func GetNestedString

func GetNestedString(raw map[string]any, keys ...string) string

func HostFromAddr

func HostFromAddr(addr string) string

func IsSensitiveAuditField

func IsSensitiveAuditField(key string) bool

func IsTrustedProxy

func IsTrustedProxy(host string, trustedProxies []string) bool

IsTrustedProxy matches the peer against an exact IP or a CIDR entry.

func MapSeverity

func MapSeverity(err error) storepb.AuditLogSeverity

func MarshalAuditMessage

func MarshalAuditMessage(message proto.Message) (*structpb.Struct, map[string]any)

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 ResolveActor(ctx context.Context, requestMap, responseMap map[string]any) string

func ResolveParent

func ResolveParent(defaultParent string, requestMap, responseMap map[string]any) string

func ResolveResource

func ResolveResource(requestMap, responseMap map[string]any) string

func SanitizeAuditStruct

func SanitizeAuditStruct(payload *structpb.Struct) *structpb.Struct

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

func StampGatewayPeer(header http.Header, peerAddr string)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL