# Decision input freshness Status: published Date: 2026-09-02 Standard: security-layer-model_v0.7 §9.7.2 A flex-auth decision is a join over sources that refresh independently. One number at a PDP would be either a fiction or the worst case. This document states a **visibility deadline per input class**, with the mechanism that bounds it. Provenance identifies which snapshot and package a decision read (`registry_snapshot_digest`, `policy_package_digest`, `directory_etag`, `input_claim_digests`). Without those digests a deadline is unfalsifiable. Operational bound shared by every class: an allow is never valid past `lifetime.expires_at` (default TTL 15m). That is the consumer-visible ceiling. The class deadlines below say when a **new Check** is guaranteed to see a revocation of that class of input. ## Approval-claim freshness | | | | --- | --- | | What is joined | Request-time approval and identity claims on `CheckRequest.context` (and related subject attributes) | | Mechanism | No PDP-side cache of claims. Each Check evaluates the claims as presented. | | Deadline | **Immediate** on the next Check (0). A revoked claim is visible as soon as the consumer stops sending it. | | Cached allow | Bounded by `lifetime`. Replay of a previous allow after the claim is revoked is refused once the digest no longer matches or the TTL ends. | | Provenance | `input_claim_digests.context` | flex-auth does not store or mutate the approval object (`approval-engine`). ## Registry snapshot cadence | | | | --- | --- | | What is joined | Protected systems, resources, subjects, groups, teams, tenants, relationship facts | | Mechanism | In-memory `registry.Store` loaded at process start and by `flex-auth load-registry`. There is no background watch. | | Deadline | A registry-borne revocation is visible after the operator reloads the snapshot **or** when the current allow TTL ends, whichever is first. On a running process that has not reloaded, the snapshot is otherwise unchanged. | | Provenance | `registry_snapshot_digest` — SHA-256 of canonical snapshot JSON | The digest makes the deadline checkable: a later Check whose digest differs read a different snapshot. ## Policy package activation | | | | --- | --- | | What is joined | The validated Rego-in-Markdown package (`id` / `version` / compiled module) | | Mechanism | Loaded at process start and by CLI `--policy`. No hot swap. | | Deadline | A package change is visible after reload **or** when the current allow TTL ends, whichever is first. | | Provenance | `policy_package`, `policy_version`, `policy_package_digest` | ## Directory ETag | | | | --- | --- | | What is joined | Delegated directory state (Topaz objects/relations, relationship-PDP tuples) and optional group-resolver evidence | | Mechanism | Topaz returns `DirectoryETag`; relationship adapters return a consistency token. Group resolvers (`Graph`, `SCIM`, `LDAP`, `Keycloak`) attach `Freshness.MaxAge` when configured. Verdicts are not cached by flex-auth. | | Deadline | **Next Check** against the directory for ETag-bearing adapters (0 relative to the directory's own visibility). For resolvers, the configured `MaxAge`; if `MaxAge` is unset, directory-borne group evidence is unbounded except by the allow TTL. | | Provenance | `directory_etag`; resolver freshness is subject-attribute evidence, not a second decision | A stale-directory signal from Topaz fails closed (`topaz_directory_stale`). ## How to read this as a consumer 1. Do not cache a verdict past `lifetime.expires_at`. 2. To know whether a stored allow still names the same facts, compare `registry_snapshot_digest`, `policy_package_digest`, and `directory_etag` to a fresh Check. 3. Approval revocation is a claim-class problem: stop presenting the claim, and do not replay a digest that included it.