audit

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package audit is the gateway's durable security log: one JSON record per request decision, administrator action and log event, appended to rotating files and synced to disk.

An admitted request is acknowledged only after its record is on disk; a record that cannot be written fails the log and protected admission stops, and records refused meanwhile are counted, never dropped silently. Records never hold credentials. The writer never deletes a file: when the file limit is reached it fails instead. It imports only fault. The request pipeline, the controller and the operator commands write to it.

Index

Constants

View Source
const (
	AuditQueueSize = 1024

	MaxLoggedPath = 256
	// MaxRecordBytes bounds one record, so an incomplete last record is
	// always found within this many bytes of the end of the file.
	MaxRecordBytes = 64 << 10
	// AuditDrainWait bounds how long a graceful stop waits for the writer to
	// write what was queued before the log closed.
	AuditDrainWait = 5 * time.Second
)
View Source
const (
	StageIngress = iota
	StageCapture
	StageCanonical
	StageRoute
	StageAccess
	StageJWT
	StageRBAC
	StageRate
	StageBody
	StageValidation
	StageAudit
	StageBind
	StageForward
)

Request stages in evaluation order. BODY covers framing, size, media type and JSON decoding; VALIDATION covers the header and body schemas.

View Source
const (
	StagePass          = "PASS"
	StageReject        = "REJECT"
	StageFail          = "FAIL"
	StageNotRun        = "NE"
	StageNotApplicable = "NA"
)

Stage results. A stage without a result was not evaluated; a stage the operation does not require, such as authentication of a public operation, is not applicable.

View Source
const (
	DefaultAuditBytes = 64 << 20
	DefaultAuditFiles = 8
)

Default size of the active audit file and number of files kept.

View Source
const EventSchema = 7

EventSchema is the version of the event envelope below.

Variables

View Source
var StageNames = [stageCount]string{
	"INGRESS", "CAPTURE", "CANONICAL", "ROUTE", "ACCESS", "JWT", "RBAC",
	"RATE", "BODY", "VALIDATION", "AUDIT", "BIND", "FORWARD",
}

Functions

func NewRequestID

func NewRequestID() string

Types

type AuditLog

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

AuditLog appends events to a local file. Events that gate a decision wait until the batch containing them has been synced to disk; other events are queued without blocking and counted when they cannot be queued.

An event is accepted when enqueue puts it in the queue. Every accepted event is written in order by the one writer, which ends only once close has closed the queue and every event in it has been written; so a close that returns nil means every accepted event, and the count of every refused one, is in the file and synced.

The active file is rotated to "<path>.<n>" before it would exceed maxBytes. The writer never deletes records: once maxFiles files exist it fails, and protected admission stops until an operator archives files and restarts.

func OpenAudit

func OpenAudit(path string, maxBytes int64, maxFiles int) *AuditLog

OpenAudit never fails: an unusable file yields a log in the failed state, which refuses every acknowledgement and therefore every admission.

func (*AuditLog) Close

func (a *AuditLog) Close(ctx context.Context) error

Close ends the log. From the moment it begins no event can be queued: Record counts it as lost and Commit refuses it. It then waits, until ctx is done, for the writer to write every event queued before, then the pending loss count, and to close the file. It returns nil only when all of that was written and synced; otherwise it reports what is not confirmed written. A writer blocked in the file system cannot be interrupted: when ctx ends first, the writer keeps the file and may still finish. Each later call reports the state it then finds.

func (*AuditLog) Closed

func (a *AuditLog) Closed() bool

Closed reports whether the writer has ended; it closes its file first.

func (*AuditLog) Commit

func (a *AuditLog) Commit(ctx context.Context, e Event) error

Commit records an event and waits for durable acknowledgement. A failed or closing log, or a full queue, refuses it at once.

func (*AuditLog) Fail

func (a *AuditLog) Fail(err error)

func (*AuditLog) Failed

func (a *AuditLog) Failed() bool

Failed reports whether the log has failed and refuses new records.

func (*AuditLog) Lost

func (a *AuditLog) Lost() uint64

Lost is the number of refused events not yet counted in the file.

func (*AuditLog) OpenErr

func (a *AuditLog) OpenErr() error

OpenErr is why the log could not open its file, or nil.

func (*AuditLog) Path

func (a *AuditLog) Path() string

Path is the active audit file's path.

func (*AuditLog) Record

func (a *AuditLog) Record(e Event)

Record queues an event without waiting. An event that cannot be queued, because the log has failed, its queue is full or it is closing, is counted; the writer writes the count with its next batch, or as it ends.

func (*AuditLog) Unconfirmed

func (a *AuditLog) Unconfirmed() (events, lost uint64)

Unconfirmed returns the number of accepted events not yet written and synced, and the count of refused events not yet in the file.

func (*AuditLog) Usage

func (a *AuditLog) Usage() (activeBytes, activeLimit, files, filesLimit int64)

Usage reports the active file's size and the number of files, each with its limit, as last stored by the writer.

type Event

type Event struct {
	Schema    int       `json:"schema"`
	ID        string    `json:"event_id"`
	Time      time.Time `json:"time"`
	Seq       uint64    `json:"seq"`
	Kind      string    `json:"kind"`
	RequestID string    `json:"request_id,omitempty"`
	Stage     string    `json:"stage,omitempty"` // terminal stage of a request event
	Stages    stages    `json:"stages,omitzero"`
	// Modules holds the result of each compiled-in module other than the
	// built-ins, keyed by module ID, with the stage result values.
	Modules       map[string]string `json:"modules,omitempty"`
	Decision      string            `json:"decision,omitempty"`
	Status        int               `json:"status,omitempty"`
	Error         string            `json:"error,omitempty"`
	Method        string            `json:"method,omitempty"`
	Path          string            `json:"path,omitempty"`
	Truncated     bool              `json:"path_truncated,omitempty"` // Path or ForwardedPath was cut to MaxLoggedPath
	ForwardedPath string            `json:"forwarded_path,omitempty"` // set only when the forward rule changed the path
	Operation     string            `json:"operation,omitempty"`
	API           string            `json:"api,omitempty"`
	Subject       string            `json:"subject,omitempty"`
	Roles         []string          `json:"roles,omitempty"`
	IgnoredRoles  []string          `json:"ignored_roles,omitempty"`
	ClientAddress string            `json:"client_address,omitempty"`
	DurationMS    float64           `json:"duration_ms,omitempty"`
	Actor         string            `json:"actor,omitempty"`
	Session       string            `json:"session,omitempty"`
	Generation    string            `json:"generation,omitempty"`
	Profile       string            `json:"profile,omitempty"`
	Upstream      string            `json:"upstream,omitempty"`
	Transition    string            `json:"transition,omitempty"`
	Revision      int64             `json:"revision,omitempty"`
	Candidate     int64             `json:"candidate,omitempty"`
	// A provisional base's events name its revision, the confirmed revision
	// it returns to on rollback and its deadline.
	Provisional    int64     `json:"provisional,omitempty"`
	RollbackTarget int64     `json:"rollback_target,omitempty"`
	Deadline       time.Time `json:"deadline,omitzero"`
	// A temporary override's events name it, the control and target it
	// governs and its expiry time.
	Override int64     `json:"override,omitempty"`
	Target   string    `json:"target,omitempty"`
	Expires  time.Time `json:"expires_at,omitzero"`
	Reason   string    `json:"reason,omitempty"`
	Lost     uint64    `json:"lost,omitempty"`
	File     string    `json:"file,omitempty"`   // audit file named by audit.* events
	Offset   int64     `json:"offset,omitempty"` // start of an incomplete record
	// contains filtered or unexported fields
}

Event is one security record. Client-controlled strings are bounded and JSON-encoded, so they cannot forge additional records. Credentials, bodies and query strings are never recorded. Subject is set only once a token has been verified; Actor only once an administrator has been authenticated, and Session is a non-secret reference to that administrator's session.

func (*Event) IdentityKnown

func (e *Event) IdentityKnown() bool

IdentityKnown reports whether the request's identity is known.

func (*Event) SetIdentityKnown

func (e *Event) SetIdentityKnown(known bool)

SetIdentityKnown records whether the request's identity is known.

Jump to

Keyboard shortcuts

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