Log every authorization decision from the authorizer
Denials were invisible in the audit trail and evaluator explainability (policy_id, reason) was discarded before reaching logs. Emit a structured authz decision line on every evaluation in evaluateMultiInTx — allow, deny, no_match, and assumption errors — using the existing authorizer logger with opaque IDs only. Add decision_log.go with DecisionRecord and logDecision. Surface PolicyID and Reason on EvaluationResult for logging. Audit log behavior is unchanged (allow-only). Document the convention in authorization.md. Signed-off-by: Ludovic Vielle <ludovic@probo.com>
This commit is contained in:
@@ -445,6 +445,17 @@ func (a *Authorizer) evaluateMultiInTx(
|
||||
|
||||
if assumptionErr != nil && !item.SkipAssumptionCheck {
|
||||
decisions[i] = assumptionErr
|
||||
a.logDecision(
|
||||
ctx,
|
||||
DecisionRecord{
|
||||
Effect: effectError,
|
||||
Action: item.Action,
|
||||
ResourceID: item.Resource,
|
||||
Principal: params.Principal,
|
||||
Reason: assumptionErr.Error(),
|
||||
},
|
||||
)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -458,7 +469,22 @@ func (a *Authorizer) evaluateMultiInTx(
|
||||
},
|
||||
}
|
||||
|
||||
if !a.evaluator.Evaluate(req, policies).IsAllowed() {
|
||||
startedAt := time.Now()
|
||||
result := a.evaluator.Evaluate(req, policies)
|
||||
|
||||
a.logDecision(
|
||||
ctx,
|
||||
newDecisionRecord(
|
||||
result,
|
||||
params.Principal,
|
||||
item.Resource,
|
||||
item.Action,
|
||||
role,
|
||||
time.Since(startedAt),
|
||||
),
|
||||
)
|
||||
|
||||
if !result.IsAllowed() {
|
||||
decisions[i] = NewInsufficientPermissionsError(params.Principal, item.Resource, item.Action)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user