147 lines
6.4 KiB
YAML
147 lines
6.4 KiB
YAML
|
|
# flex-auth (access-engine) — §11 emission guarantee, per event class.
|
||
|
|
#
|
||
|
|
# Authority: security-layer-model §9.6 and §11; GH-DEC-2026-018 §2 and §3;
|
||
|
|
# net-kingdom/canon/standards/emission-cadence-security-profile_v0.1.md.
|
||
|
|
# Reference instance: approval-engine/cadence.yaml. Detection form:
|
||
|
|
# gate-house/docs/contracts/approval-emission-detection.md.
|
||
|
|
#
|
||
|
|
# WHY THIS FILE EXISTS AND WHY IT IS PER CLASS.
|
||
|
|
#
|
||
|
|
# flex-auth asked whether it is a §4 source of evidence for the decision record
|
||
|
|
# or only the producer of an artifact audit-core sources, declined to take the
|
||
|
|
# reading that favoured it, and held the question open as declared gap G2.
|
||
|
|
# GH-DEC-2026-018 §1 ruled that a custodian is never the source of what it
|
||
|
|
# holds: §9.6 rests on an archive being unable to prove a record was never
|
||
|
|
# sent, and that sentence has content only because archive and emitter are
|
||
|
|
# different parties. audit-core reached the same conclusion on its own
|
||
|
|
# authority (AUDIT-IN-0005) and declined the role. So flex-auth is the source.
|
||
|
|
#
|
||
|
|
# GH-DEC-2026-018 §4 ruled the declaration is PER EVENT CLASS and deliberately
|
||
|
|
# did NOT classify these classes, because §11 forbids a conformance run to
|
||
|
|
# infer class from event name, payload or observed rate and that prohibition
|
||
|
|
# binds a ruling as hard as it binds a runner. The classification below is
|
||
|
|
# therefore flex-auth's, published as §11 requires the source to publish it,
|
||
|
|
# and it is supplied to a checker rather than derived by one.
|
||
|
|
#
|
||
|
|
# The reason it is per class and not per repository: one guarantee averaged
|
||
|
|
# over a stream carrying both a high-volume allow and a rare deny is an
|
||
|
|
# average, not a declaration, and rate monitoring over that average cannot see
|
||
|
|
# the deny go missing. A denial is one of the three paradigm load-bearing
|
||
|
|
# events §9.6 names, and it is the event an adversary most wants absent.
|
||
|
|
|
||
|
|
schema_version: "0.1"
|
||
|
|
source: flex-auth # §4 row `access-engine`; FLEX-DEC-2026-013
|
||
|
|
kind: load-bearing
|
||
|
|
form: heartbeat-or-reconciliation
|
||
|
|
rate_monitoring: forbidden # class-level exception stated on `allow` only
|
||
|
|
|
||
|
|
# STATE. The classification below is published and in force as a declaration.
|
||
|
|
# The emission pipeline is not built: no sender named flex-auth or
|
||
|
|
# access-engine is registered with audit-core, no token lane, no scope row, and
|
||
|
|
# the decision record reaches consumers in the /v1/check response rather than
|
||
|
|
# into any custody. This file is therefore the declaration §11 requires and not
|
||
|
|
# a claim that the guarantee is delivered today. The delivery gap is G2 in
|
||
|
|
# docs/conformance/security-layer-conformance.md, with owner, blocker and
|
||
|
|
# review date, and it fails CLOSED on its distinguishing case: a stream with no
|
||
|
|
# declared cadence produces no silence finding, so the failure mode is a missed
|
||
|
|
# detection and never a manufactured permission.
|
||
|
|
state: declared-not-yet-emitting
|
||
|
|
gap: G2 # docs/conformance/security-layer-conformance.md
|
||
|
|
|
||
|
|
heartbeat:
|
||
|
|
class: flex-auth.decision.heartbeat
|
||
|
|
interval: 24h
|
||
|
|
assertion: nothing-to-report
|
||
|
|
missing: finding
|
||
|
|
|
||
|
|
reconciliation:
|
||
|
|
# Declared for EVERY class, including the volume one. Rate monitoring can see
|
||
|
|
# a stream stop; it cannot see a targeted subset removed, and a suppression
|
||
|
|
# aimed at one subject or one tenant is exactly the shape that leaves the
|
||
|
|
# aggregate rate inside its window.
|
||
|
|
compare:
|
||
|
|
local: committed outbox counts per class
|
||
|
|
remote: "audit-core event counts where source=flex-auth"
|
||
|
|
divergence: finding
|
||
|
|
undrained_local: lag-not-divergence
|
||
|
|
|
||
|
|
lag_bound:
|
||
|
|
outbox_depth: 100
|
||
|
|
outbox_age: 1h
|
||
|
|
exceed: finding
|
||
|
|
|
||
|
|
# EVENT CLASS INVENTORY.
|
||
|
|
#
|
||
|
|
# The classes are the decision-record effect vocabulary of
|
||
|
|
# `flex-auth.decision-record.v1` (docs/decision-record-contract.md,
|
||
|
|
# pkg/api.DecisionEffect). Every one of them is load-bearing: a decision record
|
||
|
|
# is the artifact a consumer's authority rests on, and §17 moved its schema
|
||
|
|
# here on the ground that it is the one thing in the estate only this
|
||
|
|
# repository produces.
|
||
|
|
classes:
|
||
|
|
deny:
|
||
|
|
action: flex-auth.decision.deny
|
||
|
|
evidence_class: load-bearing
|
||
|
|
rarity: rare
|
||
|
|
rate_monitoring: forbidden
|
||
|
|
detection: [heartbeat, reconciliation]
|
||
|
|
note: >-
|
||
|
|
§9.6's paradigm case, named there by the standard. Rare by nature, which
|
||
|
|
is where rate monitoring is the wrong instrument and the stakes are
|
||
|
|
highest.
|
||
|
|
redact:
|
||
|
|
action: flex-auth.decision.redact
|
||
|
|
evidence_class: load-bearing
|
||
|
|
rarity: rare
|
||
|
|
rate_monitoring: forbidden
|
||
|
|
detection: [heartbeat, reconciliation]
|
||
|
|
note: >-
|
||
|
|
A partial denial. It restricts authority, so it carries the same
|
||
|
|
suppression incentive as a deny and is classified with it.
|
||
|
|
not_applicable:
|
||
|
|
action: flex-auth.decision.not_applicable
|
||
|
|
evidence_class: load-bearing
|
||
|
|
rarity: rare
|
||
|
|
rate_monitoring: forbidden
|
||
|
|
detection: [heartbeat, reconciliation]
|
||
|
|
note: >-
|
||
|
|
No policy matched. A consumer fails closed on it, so its absence has the
|
||
|
|
same effect as a suppressed deny.
|
||
|
|
audit_only:
|
||
|
|
action: flex-auth.decision.audit_only
|
||
|
|
evidence_class: load-bearing
|
||
|
|
rarity: rare
|
||
|
|
rate_monitoring: forbidden
|
||
|
|
detection: [heartbeat, reconciliation]
|
||
|
|
note: >-
|
||
|
|
The effect whose entire purpose is the record. A record of it that does
|
||
|
|
not arrive is the decision not having happened.
|
||
|
|
allow:
|
||
|
|
action: flex-auth.decision.allow
|
||
|
|
evidence_class: load-bearing
|
||
|
|
rarity: volume
|
||
|
|
rate_monitoring: permitted # §3 of the profile: explicitly classified rate-suitable
|
||
|
|
expected_rate:
|
||
|
|
window: 1h
|
||
|
|
minimum: 1
|
||
|
|
below_minimum: finding
|
||
|
|
detection: [expected-rate, reconciliation]
|
||
|
|
note: >-
|
||
|
|
Classified volume, and stated as a classification rather than left to be
|
||
|
|
inferred from observed traffic. Reconciliation is declared anyway,
|
||
|
|
because rate monitoring over an allow stream cannot see a targeted subset
|
||
|
|
removed. An allow carries a TTL lifetime, so a suppressed allow expires
|
||
|
|
into a denial of service rather than into a standing grant.
|
||
|
|
heartbeat:
|
||
|
|
action: flex-auth.decision.heartbeat
|
||
|
|
evidence_class: operational
|
||
|
|
rarity: scheduled
|
||
|
|
note: The positive assertion above; not a decision.
|
||
|
|
|
||
|
|
bound: >-
|
||
|
|
Heartbeat and reconciliation detect loss, outage, drain failure and accident.
|
||
|
|
Neither detects a compromised source suppressing an event and its own count
|
||
|
|
together — §9.6's stated residual, and §16 puts the independent observer
|
||
|
|
outside audit-core's scope. Conformance to this declaration is not a claim of
|
||
|
|
stream completeness.
|