audit

package module
v0.0.0-...-d59aefb Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	// AuditLogsEndpoint is the API endpoint for creating audit logs
	AuditLogsEndpoint = "/api/audit-logs"
	// DefaultHTTPTimeout is the default timeout for HTTP requests to the audit service
	DefaultHTTPTimeout = 10 * time.Second
	// MaxRetries is the maximum number of retries for sending a batch
	MaxRetries = 3
	// InitialBackoff is the initial backoff duration for retries
	InitialBackoff = 500 * time.Millisecond
)
View Source
const (
	StatusSuccess = "SUCCESS"
	StatusFailure = "FAILURE"
)

Audit log status constants

Variables

This section is empty.

Functions

func CanonicalizeRequest

func CanonicalizeRequest(event *AuditLogRequest) ([]byte, error)

CanonicalizeRequest creates a deterministic byte representation of an AuditLogRequest for cryptographic signing and verification.

IMPORTANT: This uses a pipe-delimited format instead of JSON serialization. json.Marshal output is Go-specific (spacing, key ordering of maps, encoding of special characters) and is extremely difficult to reproduce byte-for-byte in other languages like Python or Node.js. By using a simple pipe-delimited format, any language in NSW's polyglot ecosystem can trivially compute the same canonical payload.

Canonical format (fields separated by "|"):

TraceID|Timestamp|EventType|Action|Status|ActorType|ActorID|TargetType|TargetID|Message|MetadataJSON

Rules:

  • nil/empty pointer fields use the empty string ""
  • Message bytes are base64-encoded (standard encoding, no padding trimming)
  • Metadata map is serialized via json.Marshal (maps have sorted keys in Go 1.8+), but since this is a simple map[string]interface{}, most languages can reproduce it. An empty/nil map serializes as "{}"

func CurrentTimestamp

func CurrentTimestamp() string

CurrentTimestamp returns current UTC time in RFC3339 format. This provides a consistent timestamp format across all audit logs.

func InitializeGlobalAudit

func InitializeGlobalAudit(client Auditor)

InitializeGlobalAudit initializes the global audit middleware instance. This should be called once during application startup. Subsequent calls will be ignored (safe to call multiple times).

The client parameter should be an implementation of Auditor interface. When client is nil or IsEnabled() returns false, audit logging will be skipped but services will continue to function normally.

func LogAuditEvent

func LogAuditEvent(ctx context.Context, auditRequest *AuditLogRequest)

LogAuditEvent logs an audit event using global audit middleware instance This is the public function that should be called from handlers and other components

func MarshalMetadata

func MarshalMetadata(metadata map[string]interface{}) json.RawMessage

MarshalMetadata safely marshals metadata to json.RawMessage. Returns empty JSON object "{}" on error to ensure valid JSON. Returns nil if metadata is nil.

func ResetGlobalAuditMiddleware

func ResetGlobalAuditMiddleware()

ResetGlobalAuditMiddleware is a helper function for tests to reset the global audit middleware instance This should only be used in tests to reset state between test cases

func SignPayload

func SignPayload(payload []byte, signer crypto.Signer) (string, string, error)

SignPayload hashes and signs the canonical payload using the provided signer.

func VerifyPayload

func VerifyPayload(payload []byte, signatureBase64 string, alg string, publicKey crypto.PublicKey) error

VerifyPayload verifies the signature of the payload using the provided public key

Types

type AuditClient

type AuditClient = Auditor

AuditClient is an alias for Auditor to maintain backward compatibility. Deprecated: Use Auditor instead. This will be removed in a future version.

type AuditLogRequest

type AuditLogRequest struct {
	// Trace & Correlation
	TraceID *string `json:"traceId,omitempty"` // UUID string, nullable for standalone events

	// Temporal
	Timestamp string `json:"timestamp"` // ISO 8601 format, required

	// Event Classification
	EventType string `json:"eventType,omitempty"` // MANAGEMENT_EVENT, USER_MANAGEMENT
	Action    string `json:"action"`              // CREATE, READ, UPDATE, DELETE (Required by server)
	Status    string `json:"status"`              // SUCCESS, FAILURE

	// Actor Information
	ActorType string `json:"actorType"` // SERVICE, ADMIN, MEMBER, SYSTEM
	ActorID   string `json:"actorId"`   // email, uuid, or service-name

	// Target Information
	TargetType string  `json:"targetType"`         // SERVICE, RESOURCE
	TargetID   *string `json:"targetId,omitempty"` // resource_id or service_name

	// Payload & Metadata
	Message  []byte                 `json:"message"`            // Specific blob for NSW/NPQS
	Metadata map[string]interface{} `json:"metadata,omitempty"` // Consolidated metadata

	// Security & Non-Repudiation
	ShouldSign         bool   `json:"-"` // Internal flag to trigger signing
	Signature          string `json:"signature,omitempty"`
	SignatureAlgorithm string `json:"signatureAlgorithm,omitempty"`
	PublicKeyID        string `json:"publicKeyId,omitempty"`
}

AuditLogRequest represents the request payload for creating an audit log

type AuditMiddleware

type AuditMiddleware struct {
	// contains filtered or unexported fields
}

AuditMiddleware handles audit logging operations

func GetGlobalAuditMiddleware

func GetGlobalAuditMiddleware() *AuditMiddleware

GetGlobalAuditMiddleware returns the global audit middleware instance This can be used by service-specific wrappers that need access to the global instance

func NewAuditMiddleware

func NewAuditMiddleware(client Auditor) *AuditMiddleware

NewAuditMiddleware creates a new audit middleware with thread-safe global initialization This function should typically only be called once during application startup. Subsequent calls will return a new instance but won't update the global instance.

The client parameter should be an implementation of Auditor interface. When client is nil or IsEnabled() returns false, the middleware will skip all audit logging operations but services will continue to function normally.

func (*AuditMiddleware) Client

func (m *AuditMiddleware) Client() Auditor

Client returns the audit client instance This allows service-specific wrappers to access the client

func (*AuditMiddleware) LogAuditEvent

func (m *AuditMiddleware) LogAuditEvent(ctx context.Context, auditRequest *AuditLogRequest)

LogAuditEvent sends an audit event to the audit service API This function is used to log audit events using the unified audit log structure

type Auditor

type Auditor interface {
	// LogEvent queues a standard audit event for asynchronous processing.
	// Returns true if the event was accepted, false if the client is
	// shutting down, disabled, or the queue is full.
	LogEvent(ctx context.Context, event *AuditLogRequest) bool

	// SignEvent generates a digital signature for the audit request
	// using the registered SignPayloadFunc
	SignEvent(ctx context.Context, event *AuditLogRequest) error

	// LogSignedEvent queues an event that already contains a cryptographic signature
	LogSignedEvent(ctx context.Context, event *AuditLogRequest)

	// VerifyIntegrity validates a log's signature using a provided public key
	VerifyIntegrity(event *AuditLogRequest, publicKey crypto.PublicKey) (bool, error)

	// IsEnabled returns true if the auditor is configured to process events
	IsEnabled() bool

	// Close gracefully shuts down the client and flushes the queue
	Close(ctx context.Context) error
}

Auditor is the primary interface for audit logging operations. This interface provides a clean abstraction for audit capabilities, making it easy to swap implementations and integrate audit logging into any service.

Implementations should handle: - Asynchronous logging (fire-and-forget) - Graceful degradation when the audit service is unavailable - Thread-safe operations

func GetGlobalAuditClient

func GetGlobalAuditClient() Auditor

GetGlobalAuditClient returns the global audit client instance. This is a convenience function that extracts the client from the global middleware.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a client for sending audit events to the audit service

func NewClient

func NewClient(cfg Config) *Client

NewClient creates a new audit client using the provided configuration. Audit can be disabled by:

  • Setting ENABLE_AUDIT=false environment variable
  • Providing an empty baseURL in config

When disabled, all LogEvent calls will be no-ops.

func (*Client) Close

func (c *Client) Close(ctx context.Context) error

Close gracefully shuts down the client, flushing the queue. It signals workers to stop accepting new work, drains remaining events, and waits for all workers to finish (or for ctx to expire).

func (*Client) IsEnabled

func (c *Client) IsEnabled() bool

IsEnabled returns whether the audit client is enabled

func (*Client) LogEvent

func (c *Client) LogEvent(ctx context.Context, event *AuditLogRequest) bool

LogEvent sends an audit event to the audit service asynchronously via worker queue. Returns false if the client is shutting down or the queue is full.

func (*Client) LogSignedEvent

func (c *Client) LogSignedEvent(ctx context.Context, event *AuditLogRequest)

LogSignedEvent logs an audit event that has already been signed. This is an alias for LogEvent intended for semantically clearer logging of signed events.

func (*Client) SignEvent

func (c *Client) SignEvent(ctx context.Context, event *AuditLogRequest) error

SignEvent generates a cryptographic signature for the given request using the registered SignPayloadFunc.

func (*Client) VerifyIntegrity

func (c *Client) VerifyIntegrity(event *AuditLogRequest, publicKey crypto.PublicKey) (bool, error)

VerifyIntegrity verifies the signature of a log request. It uses the public key provided by the caller to verify the signature.

type Config

type Config struct {
	BaseURL            string
	Signer             SignPayloadFunc
	PublicKeyID        string
	SignatureAlgorithm string        // e.g. "RS256", "EdDSA"
	WorkerCount        int           // Number of background workers, defaults to 5
	QueueSize          int           // Size of the internal channel, defaults to 100
	BatchSize          int           // Number of logs to send in one batch, defaults to 20
	BatchInterval      time.Duration // Max time to wait before sending a batch, defaults to 1s
	HTTPTimeout        time.Duration // Defaults to 10s
	AuthToken          string        // Bearer token for authentication
	SpoolDir           string        // Directory for spooling failed batches (empty = disabled)
}

Config defines the configuration for the Audit Client

type SignPayloadFunc

type SignPayloadFunc func(ctx context.Context, payload []byte) (signature string, err error)

SignPayloadFunc is a strategy for signing payloads. It allows the client to provide its own signing logic (e.g. KMS, File-based, etc.) without exposing private keys to the audit library.

Jump to

Keyboard shortcuts

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