Skip to content

docs(security): record the rule-8 guardrail tests as closed (§21) - #270

Merged
ilpanich merged 1 commit into
mainfrom
claude/rule8-record
Aug 4, 2026
Merged

docs(security): record the rule-8 guardrail tests as closed (§21)#270
ilpanich merged 1 commit into
mainfrom
claude/rule8-record

Conversation

@ilpanich

@ilpanich ilpanich commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Docs-only. Closes the §15.3.1 item that had been carried through §16.3a, §18.6, §19.6 and §20.5 — rule 8 now has regression coverage in all eleven SDKs.

Merged: go#29 · rust#43 · kotlin#16 · java#37 · c#15 · cplusplus#13 · csharp#33 · swift#15

A correction to the count

Every prior section said nine SDKs outstanding. It was eight. PHP already had Sec085GuardCredentialSubstitutionTest — it is where the pattern was first written, as §15.3.1 itself says — and TypeScript and Python landed in the §16 round. The "nine" came from subtracting only those two from eleven, and was repeated forward without being re-derived.

It was not only a guardrail

The Java Spring filter rejected correctly (401, chain not invoked) but never cleared the ambient SecurityContext, so a rejected caller left behind whatever identity was already on the thread — from an earlier filter, or a pooled container thread. That's the servlet analogue of the SEC-085 substitution.

§21.2 records why §15.1's hand-verification missed it, which is the part worth keeping: that pass asked whether each guard rejects, and every guard does. This is the different question of what a guard leaves behind after rejecting — a property nobody had stated, so hand-verification could not have caught it. Writing the test did.

What the section adds

  • §21.3 — which SDKs carry the structural shape SEC-085 exploited (Kotlin, C and C# hand the guard a stateful client rather than a bare verifier), and how the structurally-safe ones assert the absence of a second credential instead.
  • §21.4 — what makes the tests non-vacuous: each asserts a substitution was genuinely available before asserting it wasn't taken. Plus the falsification results per SDK.
  • §21.5 — verification honesty: dotnet and swift were unavailable locally. C# failed CI on exactly that risk (FakeAxiamServerHandler is private and nested, so unreachable); Swift passed first try on 5.9 and 5.10.
  • §21.6 — still carried, unchanged: the SEC-086 timing channel, the gRPC m2m/user parity gap, residuals 4 and 5.

§20.5's stale bullet is replaced with a pointer to §21.

No code changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SkTHvZQMV47t3UwkEtmB1D


Generated by Claude Code

The §15.3.1 item carried through §16.3a, §18.6, §19.6 and §20.5 is done:
rule 8 now has regression coverage in all eleven SDKs.

Corrects the count. Every prior section said nine SDKs outstanding; it
was eight. PHP already had the test — it is where the pattern was first
written — and TypeScript and Python landed in the §16 round. The "nine"
figure came from subtracting only those two from eleven and was carried
forward without being re-derived.

Records that this was not purely a guardrail exercise: the Java Spring
filter rejected correctly but never cleared the ambient SecurityContext,
so a rejected caller left behind whatever identity was already on the
thread. §15.1's hand-verification asked whether each guard rejects, and
every guard does; this is the different question of what a guard leaves
behind afterwards, which no stated property covered.

Also records which SDKs carry the structural shape SEC-085 exploited
(Kotlin, C, C# hand the guard a stateful client), what makes the tests
non-vacuous (each asserts that a substitution was genuinely available
before asserting it was not taken), the falsification results, and that
C#/Swift could not be run locally — C# failed CI on exactly that risk,
Swift passed first try.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SkTHvZQMV47t3UwkEtmB1D
@ilpanich
ilpanich merged commit eb8e8db into main Aug 4, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants