Documentation
¶
Index ¶
- Constants
- func CanonicalizeRequest(event *AuditLogRequest) ([]byte, error)
- func CurrentTimestamp() string
- func InitializeGlobalAudit(client Auditor)
- func LogAuditEvent(ctx context.Context, auditRequest *AuditLogRequest)
- func MarshalMetadata(metadata map[string]interface{}) json.RawMessage
- func ResetGlobalAuditMiddleware()
- func SignPayload(payload []byte, signer crypto.Signer) (string, string, error)
- func VerifyPayload(payload []byte, signatureBase64 string, alg string, publicKey crypto.PublicKey) error
- type AuditClient
- type AuditLogRequest
- type AuditMiddleware
- type Auditor
- type Client
- func (c *Client) Close(ctx context.Context) error
- func (c *Client) IsEnabled() bool
- func (c *Client) LogEvent(ctx context.Context, event *AuditLogRequest) bool
- func (c *Client) LogSignedEvent(ctx context.Context, event *AuditLogRequest)
- func (c *Client) SignEvent(ctx context.Context, event *AuditLogRequest) error
- func (c *Client) VerifyIntegrity(event *AuditLogRequest, publicKey crypto.PublicKey) (bool, error)
- type Config
- type SignPayloadFunc
Constants ¶
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 )
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 ¶
SignPayload hashes and signs the canonical payload using the provided signer.
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 ¶
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 ¶
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) 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 ¶
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 ¶
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.