Files
query-orchestration/cmd/cognito_test/user.creation.tool/audit.go
T
Jay Brown daf4d4b94b Merged in feature/permit-io-demo (pull request #144)
draft pr for the test demo harness for permit.io

* harness working

for permit.io demo

* user is const

* aws profile

* permit import code

for research

* cleanup

* create user tool poc

* Merge branch 'main' of bitbucket.org:aarete/query-orchestration into feature/permit-io-demo

* tests for user creation

* add audit logs

and dry-run

* add tests

sanity check the requested roles

* update docs for delete

* disable/enable users

and test

* more tests

and make user name required only for create operations

* clean up

* add docs

* aws tag tests

* audit -> slog

* attempt build fix devbox

* edit

* just devbox

* remove lock change for merge

* Merge branch 'main' of bitbucket.org:aarete/query-orchestration into feature/permit-io-demo
2025-06-13 19:42:24 +00:00

142 lines
4.0 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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 -> humanreadable text (default)
// LOG_FORMAT=json -> JSON
//
// The public API (type AuditLogger and all its methods) is unchanged, so no callsites
// (e.g. cognito-permit-sync.go) need to be modified.
package main
import (
"context"
"log/slog"
"os"
)
const envLogFormat = "LOG_FORMAT"
// AuditLogger handles audittrail 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 dryrun execution.
func (a *AuditLogger) LogDryRunStart() {
a.logger.InfoContext(context.TODO(), "dry_run_start")
}
// LogDryRunEnd marks the completion of a dryrun execution.
func (a *AuditLogger) LogDryRunEnd() {
a.logger.InfoContext(context.TODO(), "dry_run_end")
}