6dccf494f8
cleanup permit policies and correct documentation * docs * policy cleanup * refactor * Merge remote-tracking branch 'origin/feature/permit-policy-cleanup' into feature/permit-policy-cleanup * docs and edits
142 lines
4.0 KiB
Go
142 lines
4.0 KiB
Go
// audit.go provides comprehensive audit trail logging functionality for compliance and monitoring.
|
||
// This file now uses the `log/slog` structured logging package introduced in Go 1.21.
|
||
// A single environment variable LOG_FORMAT controls the output format:
|
||
//
|
||
// LOG_FORMAT=text -> human‑readable text (default)
|
||
// LOG_FORMAT=json -> JSON
|
||
//
|
||
// The public API (type AuditLogger and all its methods) is unchanged, so no call‑sites
|
||
// (e.g. cognito-permit-sync.go) need to be modified.
|
||
package main
|
||
|
||
import (
|
||
"context"
|
||
"log/slog"
|
||
"os"
|
||
)
|
||
|
||
const envLogFormat = "LOG_FORMAT"
|
||
|
||
// AuditLogger handles audit‑trail logging for compliance.
|
||
type AuditLogger struct {
|
||
logger *slog.Logger
|
||
file *os.File
|
||
}
|
||
|
||
// NewAuditLogger initializes the audit logger.
|
||
// The signature is unchanged: pass isDryRun=true to write to dry-run-audit.log;
|
||
// otherwise logs are appended to audit.log in the working directory.
|
||
func NewAuditLogger(isDryRun bool) (*AuditLogger, error) {
|
||
filename := "audit.log"
|
||
if isDryRun {
|
||
filename = "dry-run-audit.log"
|
||
}
|
||
|
||
file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// Choose handler based on LOG_FORMAT
|
||
var handler slog.Handler
|
||
switch os.Getenv(envLogFormat) {
|
||
case "json":
|
||
handler = slog.NewJSONHandler(file, &slog.HandlerOptions{AddSource: false})
|
||
default: // "text" or unset
|
||
handler = slog.NewTextHandler(file, &slog.HandlerOptions{AddSource: false})
|
||
}
|
||
|
||
logger := slog.New(handler)
|
||
|
||
return &AuditLogger{
|
||
logger: logger,
|
||
file: file,
|
||
}, nil
|
||
}
|
||
|
||
// Close closes the underlying audit file.
|
||
func (a *AuditLogger) Close() error {
|
||
if a.file != nil {
|
||
return a.file.Close()
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// ----- Public logging helpers ------------------------------------------------
|
||
|
||
// ActionType represents the type of action being logged.
|
||
type ActionType string
|
||
|
||
const (
|
||
ActionCreate ActionType = "CREATE"
|
||
ActionDelete ActionType = "DELETE"
|
||
ActionDisable ActionType = "DISABLE"
|
||
ActionEnable ActionType = "ENABLE"
|
||
ActionAssignRole ActionType = "ASSIGN_ROLE"
|
||
ActionUnassignRole ActionType = "UNASSIGN_ROLE"
|
||
ActionUpdate ActionType = "UPDATE"
|
||
ActionSkip ActionType = "SKIP"
|
||
)
|
||
|
||
// SystemType represents the system where the action occurred.
|
||
type SystemType string
|
||
|
||
const (
|
||
SystemCognito SystemType = "COGNITO"
|
||
SystemPermit SystemType = "PERMIT"
|
||
)
|
||
|
||
// ResultType represents the outcome of the action.
|
||
type ResultType string
|
||
|
||
const (
|
||
ResultSuccess ResultType = "SUCCESS"
|
||
ResultFailure ResultType = "FAILURE"
|
||
ResultSkipped ResultType = "SKIPPED"
|
||
)
|
||
|
||
// LogAction logs a generic action (without subjectID or role).
|
||
func (a *AuditLogger) LogAction(action ActionType, system SystemType, userEmail string, result ResultType, details string) {
|
||
a.logger.InfoContext(context.TODO(), "audit_event",
|
||
"action", action,
|
||
"system", system,
|
||
"userEmail", userEmail,
|
||
"result", result,
|
||
"details", details,
|
||
)
|
||
}
|
||
|
||
// LogActionWithSubjectID logs an action involving a specific subject identifier.
|
||
func (a *AuditLogger) LogActionWithSubjectID(action ActionType, system SystemType, userEmail, subjectID string, result ResultType, details string) {
|
||
a.logger.InfoContext(context.TODO(), "audit_event",
|
||
"action", action,
|
||
"system", system,
|
||
"userEmail", userEmail,
|
||
"subjectID", subjectID,
|
||
"result", result,
|
||
"details", details,
|
||
)
|
||
}
|
||
|
||
// LogRoleAction logs role assignment/unassignment activities.
|
||
func (a *AuditLogger) LogRoleAction(action ActionType, userEmail, role string, result ResultType, details string) {
|
||
a.logger.InfoContext(context.TODO(), "audit_event",
|
||
"action", action,
|
||
"system", SystemPermit,
|
||
"userEmail", userEmail,
|
||
"role", role,
|
||
"result", result,
|
||
"details", details,
|
||
)
|
||
}
|
||
|
||
// LogDryRunStart marks the beginning of a dry‑run execution.
|
||
func (a *AuditLogger) LogDryRunStart() {
|
||
a.logger.InfoContext(context.TODO(), "dry_run_start")
|
||
}
|
||
|
||
// LogDryRunEnd marks the completion of a dry‑run execution.
|
||
func (a *AuditLogger) LogDryRunEnd() {
|
||
a.logger.InfoContext(context.TODO(), "dry_run_end")
|
||
}
|