Your OPA decision logs are rate-limited and an auditor wants proof one request was evaluated last Tuesday — what can you show?
answer
- the stream is best-effort
- absence is not evidence
- rate limits discard events silently
- the buffer lives in memory
- sample by policy, not by rate
basics
~20 sA rate-limited or sampled OPA decision log is telemetry, not a ledger. You can show the entries that survived, but rate-limited, dropped and buffer-lost decisions leave no trace at all, so a missing entry proves nothing about whether the policy ran.
solid answer
~50 sHonestly: only the entries that survived, plus which bundle revision was active around that window. Three mechanisms silently remove events. `max_decisions_per_second` discards decisions above the configured rate. A `drop` policy used to sample throws events away by design. And the plugin's buffer is in memory and bounded — it drops events when full, and anything unflushed when OPA restarts is gone with no gap marker in the sink. So absence of an entry is consistent with a dropped, rate-limited, lost or never-uploaded decision, and does not mean the decision was not made. The fix is to stop sampling blindly: sample in the drop policy so it is deterministic — keep every deny and every decision on the paths the control covers, shed the high-volume allows — size the buffer for the burst rate, and alert on OPA's own warnings that events were discarded.
go deeper
Know that the decision log can be rate-limited and buffered in memory, so it is not guaranteed to contain every decision. Do not describe it as a complete record.
Be able to name the three ways an event vanishes — a rate limit, a drop policy, and a bounded in-memory buffer emptied by a restart — and explain why none of them leaves a marker behind.
Show judgment under pressure: state exactly what the surviving entries and bundle revisions support, refuse to reconstruct a missing entry from elsewhere, and redesign sampling as a policy that names which decisions are always kept.
Own the decision of what per-decision assurance the organisation commits to before anyone asks for it, and accept that a path carrying such a commitment cannot be blind-sampled for cost.
## The question behind the question An auditor is not asking about your logging pipeline. They are asking whether a control was in force on a given day, and they have been pointed at your decision log as the evidence. The interview is testing whether you understand what that stream can and cannot support — and the correct senior answer starts by narrowing the claim rather than by promising more than the data holds. ## Three ways an entry disappears **Rate limiting.** The plugin can be configured with `max_decisions_per_second`. Above that rate, decisions are discarded. This is not a queue — the events are gone. It is a perfectly sensible protection for a hot admission or authorization path, and it means your log is a sample whose selection criterion is "whatever arrived when the engine was not already busy logging". That is the worst possible sampling rule for evidence: it correlates with traffic bursts, which is exactly when interesting things happen. **A drop policy.** Sampling is often implemented deliberately, as a Rego rule at the drop decision path that suppresses events you have decided not to keep. Done thoughtlessly — drop nine in ten — it produces a stream that cannot answer for any specific decision. Done well it is the right tool, because it is *deterministic and explainable*: you can state which decisions are always kept. **Buffering.** Events for an HTTP service sink are held in memory, batched, and uploaded. The buffer is bounded; when it fills, events are discarded. And it is memory: if the OPA process restarts — a rollout, an OOM kill, a node drain — anything not yet uploaded is lost. OPA does not persist the buffer and cannot replay it. Watch OPA's own logs for warnings that events were dropped; that is your only signal that the stream has holes. ## Why absence proves nothing All three failure modes share a property that is easy to state and easy to forget: **the sink contains no marker where an event should have been**. A decision that was rate-limited, dropped by policy, evicted from a full buffer, or lost in a restart looks identical in the log to a decision that never happened. So the argument "there is no deny for that request, therefore it was allowed" and the argument "there is no entry, therefore the request never reached the policy" are both unsound. Making that claim to an auditor and being wrong is worse than saying up front that the stream is sampled. The converse still holds, and it is worth stating explicitly, because it is what you *can* offer: an entry that is present is real. It names a decision id, an input, a result, a timestamp and a bundle revision. Those entries support statements about what the policy did on the requests they cover, and the bundle revisions in them support a statement about which policy version was in force across the window. ## What you say on the day Separate what the data supports from what you are being asked to assert. 1. Show the entries you have for that window, and say plainly that the stream is sampled and by what mechanism. 2. Show which bundle revisions appear across that window, and the policy source at those revisions — that supports "this rule was loaded and evaluating" independently of whether the one request of interest survived sampling. 3. Do not reconstruct the missing entry from another source and present it as a decision log record. If it did not come from the engine, it is not what the engine decided. ## What you change afterwards The design mistake was treating log volume as a uniform problem with a uniform lever. Replace it with a policy-shaped one: - **Sample in the drop policy, not with a rate limit.** Keep every deny. Keep every decision on the policy paths a control depends on. Shed the routine high-volume allows on paths nobody will ever ask about. The result is a stream where you can state precisely what is guaranteed present. - **Size the buffer for the burst, not the average**, since eviction hits exactly when the system is busiest. - **Alarm on discards.** A silent hole is the whole problem; OPA reporting that it discarded events is the one chance you have to know. - **Decide, in advance and in writing, what the stream is allowed to be used for.** If someone will need per-decision assurance, sampling the paths that carry it is a decision to say no to. A candidate who answers this well does two things: refuses to overclaim, and converts a volume knob into a policy that expresses which decisions matter.
- How would you make the log answer that question next quarter without shipping every allow?Move sampling from the rate limit into the drop policy so it is deterministic and explainable: always keep denials, always keep decisions on the policy paths a control depends on, and shed the routine allows on paths nobody asks about. You then get a stream where you can state exactly which classes of decision are guaranteed present.
- OPA restarted mid-window. What happened to decisions it had already made?Whatever was still in the in-memory buffer and not yet uploaded is lost. The plugin does not persist the buffer across restarts and cannot re-emit those decisions later. Nothing in the sink marks the gap, so the loss is invisible unless you correlate with OPA's own logs and restart times.
- Does a missing entry mean the request was never evaluated?No. Absence is equally consistent with a rate-limited decision, one suppressed by a drop policy, one evicted from a full buffer, one lost in a restart, or an upload that failed. Treating absence as proof of non-occurrence is the error the whole scenario is testing for.
A shop that keeps every tenth receipt can prove it was trading on Tuesday, but not what it sold to one customer at 4pm.
saying these in an interview costs you the question
- Treats a missing entry as proof nothing happened
- Calls a sampled log stream an audit trail
- Assumes OPA replays buffered events after a restart
- Samples denials at the same rate as allows
- Promises the auditor coverage the stream cannot support