release: 0.6.0 — fail-CLOSED policy fetch, CSRF Bearer bypass, WS HMA…#29
Closed
maltsev-dev wants to merge 2 commits into
Closed
release: 0.6.0 — fail-CLOSED policy fetch, CSRF Bearer bypass, WS HMA…#29maltsev-dev wants to merge 2 commits into
maltsev-dev wants to merge 2 commits into
Conversation
| Hex-encoded HMAC-SHA256 signature | ||
| """ | ||
| body_hash = hashlib.sha256(body.encode('utf-8')).hexdigest() | ||
| body_hash = hashlib.sha256(body.encode("utf-8")).hexdigest() |
| secret_key.encode('utf-8'), | ||
| message.encode('utf-8'), | ||
| hashlib.sha256 | ||
| secret_key.encode("utf-8"), message.encode("utf-8"), hashlib.sha256 |
| secret_key.encode('utf-8'), | ||
| message.encode('utf-8'), | ||
| hashlib.sha256 | ||
| secret_key.encode("utf-8"), message.encode("utf-8"), hashlib.sha256 |
| # helper's bytes — the failure mode is silent 401 on the wire). | ||
| expected_body_hash = hashlib.sha256(body).hexdigest() | ||
| expected_msg = f"{headers['X-Signature-Timestamp']}:{api_key}:{expected_body_hash}".encode() | ||
| expected_sig = hmac.new( |
bf520b4 to
35f275c
Compare
…C identity pin
P0 hardening driven by the 2026-06-22 SDK↔backend integration audit.
Closes three classes of silent fail-OPEN regressions:
- FIX-F3: every signed POST now carries Authorization: Bearer <api_key>
so the backend CSRF middleware's has_bearer_auth bypass fires.
Pre-fix the SDK only sent X-API-Key, so every POST hit the
cookie-double-submit branch → 403 → SDK try/except swallowed →
every SDK-side enforcement gate was effectively fail-OPEN on
production traffic.
- FIX-F4: WebSocket HMAC identity field pinned to "api_key" via
WS_HMAC_IDENTITY_FIELD constant matching backend's SignedWsMessage
struct (ws_control.rs:43). SDK reads data["api_key"] (with
data["api_key_id"] as backwards-compat fallback).
- F-R2-02: Policy fetch is now fail-CLOSED. Pre-fix any HTTP
exception / non-200 / empty {"data": []} silently fell through
to Policy.default_local() (effectively unenforced). Post-fix
resolves in priority: last known-good cached policy →
Policy.strict_local() (zero budget cap forces backend reservation
service, fail-CLOSED there too) → opt-out via
NULLRUN_POLICY_FAIL_OPEN=1 for tests/staging.
Also:
- Policy.strict_local() classmethod (tight caps)
- Policy.from_dict maps rate_limit_per_minute (backend field)
- _is_acknowledged_state case-insensitive fallback for WS
- Correct backend policy fetch route (GET /api/v1/orgs/{id}/policies)
- README.md PyPI badge dm → dt (correct mirror counts)
- tests/test_integration_contract.py (new, 675 lines) — pins the
SDK↔backend wire-format contracts surfaced by the audit
- 13 existing test files re-aligned with the new contracts
Coverage: 84.59% branch (fail_under = 82, was ~76% in 0.5.2).
All four CI gates green: pytest (857 passed, 13 skipped), ruff,
mypy, coverage.
Files: 1 new test, 18 src/runtime/test, 1 docs.
35f275c to
ac35ab5
Compare
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…C identity pin
P0 hardening driven by the 2026-06-22 SDK↔backend integration audit. Closes three classes of silent fail-OPEN regressions:
FIX-F3: every signed POST now carries Authorization: Bearer <api_key>
so the backend CSRF middleware's has_bearer_auth bypass fires.
Pre-fix the SDK only sent X-API-Key, so every POST hit the
cookie-double-submit branch → 403 → SDK try/except swallowed →
every SDK-side enforcement gate was effectively fail-OPEN on
production traffic.
FIX-F4: WebSocket HMAC identity field pinned to "api_key" via WS_HMAC_IDENTITY_FIELD constant matching backend's SignedWsMessage struct (ws_control.rs:43). SDK reads data["api_key"] (with data["api_key_id"] as backwards-compat fallback).
F-R2-02: Policy fetch is now fail-CLOSED. Pre-fix any HTTP exception / non-200 / empty {"data": []} silently fell through to Policy.default_local() (effectively unenforced). Post-fix resolves in priority: last known-good cached policy → Policy.strict_local() (zero budget cap forces backend reservation service, fail-CLOSED there too) → opt-out via NULLRUN_POLICY_FAIL_OPEN=1 for tests/staging.
Also:
Coverage: 84.59% branch (fail_under = 82, was ~76% in 0.5.2). All four CI gates green: pytest (857 passed, 13 skipped), ruff, mypy, coverage.
Files: 1 new test, 18 src/runtime/test, 1 docs.
What
Why
How
Test plan
cd backend && cargo test,cd frontend && npm test)cd frontend && npm run lint)cd frontend && npm run type-check)Risk
Checklist
CONTRIBUTING.md(if present)